How would you implement a drag behavior on two.js shapes? The two strategies I can imagine are dragging the underlying DOM elements, which would restrict me to an SVG renderer (but enable the use of helpers such as jquery-ui). Or implementing this "from scratch" using mouse events and point-in-shape detections, which would work with all renderers.
Any thoughts? Existing examples perhaps?
Regards,
Olivier.
You have a lot of options! If you have complicated shapes (beyond circles / squares) and need very accurate hit testing then I would recommend the SVG route. e.g: https://jsfiddle.net/jonobr1/e2uvusf7/
If you have a fixed size canvas then overlaying an SVG element (Two.js) scene on top of the visible one is another way to go: https://jsfiddle.net/jonobr1/6cw5nz5p/4/
I don't have an example for this one, but if you're just hit-testing circles and squares then rolling that as your own is the best.
Hope this helps!
Hi. Thanks for your answer!
The third option is interesting; I like the fact that it is renderer agnostic. So I implemented a small example of this approach by combining a spatial index (rbush), for efficiency, with some basic circle hit detection for precision: two-js-hit-detection.
In the course of writing this, I encountered some surprising behaviors. I would appreciate to know you take on them.
myShape.translation = new Two.Vector(x,y) but have to keep the existing instance and use myShape.translation.set(x,y) or myShape.translate.x = x. I guess this has to do with events registered on the existing instance.I reckon the first two points cannot be altered without incompatible API or behavior changes. Maybe notes in the documentation could highlight those points?
Thanks,
Olivier.
This is some really great work Olivier! The demo is super cool as well! Below are some details that hopefully help explain Two.js further:
shape.translation = new Two.Vector(x, y);. This is how the children attribute works as well so I think this would be a great enhancement! Thanks for the input.master branch. The dev branch (https://github.com/jonobr1/two.js/tree/dev) has properties on most primitives for easy manipulation. For example a Two.Circle has a radius with all proper flags, getters, and setters setup so you can modify radius and the shape will confirm. In the version of your demo you have to re-plot the vertices positions to reflect a changed "radius", which property doesn't exist.Hope this helps!
Dev branch now implements Two.Shape.translation to work in the way you expect. Thanks again for the feedback!
Thanks for your interest and quick answer!
makeCircle are actually "compiled" to a "draw object", then lost (and not retained as readable properties). This makes sense, since I understand you want us to be able to deform shapes once they are created (as in that great physics demo). But this is then not so much a "scene graph" as a "drawing list hierarchy" (I am not saying this in a derogatory way!). Of course, you mileage/definitions may vary, and I can simply enrich shapes with the informations I need.Since my demo piqued your interest, maybe I could ask you for some advice? I have not been able to reproduce the "touch device" capabilities of the rubber ball demo, even if I feel I included most of its touch-related events handling rather verbatim. Do you have an idea why I don't get a similar behavior (where finger swiping would color hit circles immediately)?
Regards,
Olivier.
I rewrote the demo to illustrate my third point.
For this purpose I added extra informations to just-created shapes to keep track of their properties. This helped me in isolating hit testing related code in lib/hitTester.js, where I could take advantage of those informations to build the proper hit test with respect to geometrical properties.
Regards,
Olivier.
Awesome! Glad it helps and again sorry for the confusion. Here are more tidbits that I hope help:
For this Extra Information Section you should be okay without adding that. The x and y values reside on circle.translation.x and circle.translation.y respectively. Finally, a circle has a radius attribute which is a getter / setter so you can check against that. The development branch has a number of properties added to each primitive shape so you can set and get those properties you initially apply without worrying about the other.
I'll make a note to try to be more explicit about how Two.Group styles work when affecting child nodes. As far as the touch code from the Rubber Ball demo in order to get your hit-test working.., I'm not totally sure. Could you point me to where you've added your touch code?
It's all pretty vanilla. Add touch events to the two.renderer.domElement and on touchmove get the first touch and set a Two.Vector with the pageX and pageY to get an absolute position of your touch... It could be that you need to add some meta tags so scrolling doesn't happen on the page.., or preventDefault or stopPropagation on the touch events themselves so that "native" handlers are nullified.
Thanks! I took advantage of the new Two.Circle and its properties to simplify my demo further. Indeed I do not need to enrich shapes anymore.
With respect to the touch behavior: here is the relevant code. I also added some scrolling-related meta tag to the HTML.
Any advice would be greatly appreciated!
Regards,
Olivier.
That's great to hear @oparisy! I think the only thing I can find different is that you're listeners are on the document instead of the window. Other than that it looks the same as the Rubber Ball demo...
So I gave my touch support issue a look, following your advice. Actually I cut and pasted the rubber ball code, but forgot to remove the .originalEvent reference, which is jQuery-specific. Now my demo properly react to touch events.
Thanks for your time! I'm closing this issue since my concerns are addressed: drag support can be built upon the hit detection I could demonstrate thanks to your feedback.
Regards,
Olivier.
Glad to hear you got it!
On Sat, Jan 28, 2017, 3:29 AM oparisy notifications@github.com wrote:
So I gave my touch support issue a look, following your advice. Actually I
cut and pasted the rubber ball code, but forgot to remove the
.originalEvent reference, which is jQuery-specific. Now my demo properly
react to touch events.Thanks for your time! I'm closing this issue since my concerns are
addressed: drag support can be built upon the hit detection I could
demonstrate thanks to your feedback.Regards,
Olivier.—
You are receiving this because you were assigned.Reply to this email directly, view it on GitHub
https://github.com/jonobr1/two.js/issues/209#issuecomment-275842921, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AANbgY4fpdmihu5xLqmrJjX5V30Mw-Goks5rWyamgaJpZM4LYkYh
.>
Most helpful comment
Hi. Thanks for your answer!
The third option is interesting; I like the fact that it is renderer agnostic. So I implemented a small example of this approach by combining a spatial index (rbush), for efficiency, with some basic circle hit detection for precision: two-js-hit-detection.
In the course of writing this, I encountered some surprising behaviors. I would appreciate to know you take on them.
myShape.translation = new Two.Vector(x,y)but have to keep the existing instance and usemyShape.translation.set(x,y)ormyShape.translate.x = x. I guess this has to do with events registered on the existing instance.I reckon the first two points cannot be altered without incompatible API or behavior changes. Maybe notes in the documentation could highlight those points?
Thanks,
Olivier.