-
Notifications
You must be signed in to change notification settings - Fork 394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to set a list of clickable shapes #75
Comments
Sorry I forgot one thing : I don't know - for the moment - how to synchronize the draggable mode between the vibible canvas and his ghost, so I deactivated the draggable mode. |
Hi, I fixed a small bug tonight, on my example of "ghost canvas" : there was a bad synchro between the 2 canvas for the arrow keys. |
Thanks a lot for this! Here's a fork with enabled dragRotate: https://codepen.io/ncodefun/pen/aggZKP |
Thank's a lot to @webappslove, it works fine :) |
I will be attempting to implement a generalizable version of this method into my wrapping of zdog since one of the primary use cases is to use it as an input device but it is somewhat annoying to do. Was wondering if there was a plan to implement a built in way to get clicked objects. @desandro |
I was able to implement a generalization solution that I hope is scalable. Instead of maintaining two canvases and keeping their rotations in sync, at click time I create a new canvas, a new illustration and copy contents of the current illustration to the new canvas. The new canvas has a black background and I iterate over the child objects of the the illustration to give them colors by incrementing the color value by 1 whenever a child with a color/backface is encountered. The click then returns the pixel value which is turned back into an integer to act as the object id. I am new to javascript so this is not probably not the best way to do it. Some problems it has:
Don't have a codepen but relevant code can be found here Edit: I was able to get the specific object that was clicked by appending an ID to every object after creation by looping around the original object whose children has id's appended to them. New version is here |
I was actually toying with the idea of creating a zdog modeler and thinking of using zdog itself to draw the move/scale/rotate handles of selected objects. In order for that to work I need to be able to detect when the user has clicked on shapes It would be very nice if click detection was a part of zdog's api instead of a hack |
Hi @blurymind , |
perhaps the api can simply detect when the user has clicked on a shape and trigger a callback like this:
The developer then only needs to capture the release event. This would make it super easy to implement manipulation handles and object selection. But I guess we would also need some way of implementing a box selection of multiple objects. How would we do that in a simple way? Anyways, this is super interesting to me, but from the standpoint of wanting to make an open source editor for zzdog content |
You're right @blurymind, but the onclick event is easier to implement with a SVG graphic, it's more complex with a canvas. Complex subject, but really interesting ;) |
@gregja zzdog is rendering svgs right? Can't we make any shape clickable just by passing to the rendered svg a callback function upon creation? Edit: ah I see, its challenging because it happens inside a canvas element Could we add some onclick event listener inside the shape? |
@blurymind If you are willing to live with svg rendering, you can add event handlers to shape's render elements (paths) using existing public API e.g. var shape = // ... some Zdog Shape with fill: true
shape.getRenderElement(null, Zdog.SvgRenderer).addEventListener('click', () => alert('the shape was clicked!')); Caveats:
Seems a little easier to deal with then creating a "ghost canvas" and checking pixel colors. I am willing to live with the listed caveats, but I wish there was a better API for it. I briefly considered adding something, but given that it only works with SvgRenderer, I doubt there will be much interest. |
I think there is a way with Canvas API if it's implemented in the library. isPointInPath, isPointInStroke will accept a Path2D. But as of now, Path parameter is not supported in Safari. |
I made a codepen of this SVG click idea, some interesting things like the shape doesn't have to be filled I think, I put comments in the code. |
I am absolutely desperate for click detection on shapes as well. I want to be able to make it so users can click and drag little animals in my ZDog scene, and I can't do it without click detection. All of the ideas in this thread, while clever, each have their drawbacks. What we need is a simple way to do this built into the API. With click detection, you could build entire games or even functional websites with ZDog, the potential is huge! |
@gregja @oganm @blurymind @edwonedwon @coder787 Hi, any progres in ZDog cklickable elements? Im very into it now, and I was happy like a child when i discovered this topic. please let me know guys if you made any progress with this function. Cheers. |
No updates on my part and haven't been checking the latest discussions here but the code should still work for canvas outputs with the old caveats (no resizing, no svg support and written by someone who doesn't really know javascript) These should be enough to replicate it. this piece where you create a listener for mouse clicks on the original canvas. This part creates an empty and invisible canvas to be used later. and this function that is executed on a click. It uses the invisible canvas to create a copy of the original canvas with a unique color for each item and decides which item you just clicked based on the color under the mouse if it was clicked on this invisible canvas. Probably not the best way to do it but was working last time i checked. |
I used the same technique to add event listeners in react-zdog library. Works really fine, though syncing the ghost canvas and visible canvas was challenge, I managed to do it using Proxy object. |
I wouldlike to create small games with Zdog, so I need to be able to click on each shape individually.
I solved the problem with an old technique which is working pretty weel with Zdog : I created 2 canvas, one for the demo and a second I named "ghost" and which is a copy of the first. But not an exact copy because each shape has a unique color which is stored in a catalog of colors.
When I click on the "demo" canvas, I store the coordinates of the mouse and I check which color has those coordinates on the "ghost canvas". So I know which shape is clicked.
You can see an example on that pen :
https://codepen.io/gregja/pen/rEGmGB
and I added the code in my repository :
https://github.com/gregja/zdogXperiments
It's experimental, but it's a good beginning : don't hesitate to suggest some improvements, all ideas are welcome.
Be careful : don't use anything else than the "getMousePos" function I wrote in the script. I tested different versions and it's the only one which works well with Chrome.
The text was updated successfully, but these errors were encountered: