westy Posted June 5, 2016 Share Posted June 5, 2016 I've been trying to implement drag and drop for some of the sprites in my project. I've managed to get it working to some extent using code that I found in a tutorial/example somewhere - the exact source escapes me, apologies. (It's in typescript but should be pretty much recognisable as js) constructor() { this.on("mousedown", this.startDrag); this.on("mouseup", this.endDrag); this.on("mouseupoutside", this.endDrag); this.on("mousemove", this.onDrag); } private startDrag(e: PIXI.interaction.InteractionEvent) { this.dragging = true; e.data.getLocalPosition(this.parent, this.lastDragPos); } private endDrag() { this.dragging = false; } private onDrag(e: PIXI.interaction.InteractionEvent) { if (this.dragging) { e.data.getLocalPosition(this.parent, this.dragPos); this.position.x += (this.dragPos.x - this.lastDragPos.x); this.position.y += (this.dragPos.y - this.lastDragPos.y); e.data.getLocalPosition(this.parent, this.lastDragPos); } } However this approach seems to have a number of problems. The deal breaker here is that the object is always one (or maybe even more??) frames behind the mouse. To me this is unacceptable and leads to all kinds of nonsense like needing the mouseupoutside event to work properly. There are a whole lot of edge cases, like letting go of the dragged object when it's over another draggable object causes problems, etc, etc... I'm guessing that the first problem is caused because this is using the event system and isn't coupled to the render loop. Is there a better way to do drag and drop in PIXI? Also open to any hints on mouse interaction in general, the documentation hasn't been hugely helpful to me (i.e. what's the purpose of the interactionManager?) Thanks! Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 5, 2016 Share Posted June 5, 2016 1. Your guess is right. You can try to look in the code (WebGLRenderer.renderWebGL) , and actually call updateTransform() and then interaction before the rendering itself. Also you have to handle events not when they appear but between updateTransform() and render() 2. There is still no bubbling of events, so yes, if container and element are both interactive, its a problem for drag. (https://github.com/pixijs/pixi.js/pull/2358/ is solution, still not merged) 3. Like you said, if some object appears above draggable, then it is a problem too. You can move temporarily move object to first position in children array. We are waiting for a messiah that will solve all that and make Pull Request for all these problems. I solved it all with hacks in my games, but i dont have generalized solution for you Any way, you have to clone github repo, you wont find all these answers in docs. If you really want to fix all these things, I can help, because I'll need them all too. Quote Link to comment Share on other sites More sharing options...
raddevus Posted June 5, 2016 Share Posted June 5, 2016 I've actually generalized the drag and drop code and written it up in an article at codeproject:http://www.codeproject.com/Articles/1096331/Algorithm-Calc-Convex-Hull-Draw-HTML-Canvas-Part It's part of another series of articles I've written, but you'll see the drag and drop functionality is separated out so you can easily use the code. Also you can see the animated gif of the simplified code working : Hope this helps. Quote Link to comment Share on other sites More sharing options...
bQvle Posted June 6, 2016 Share Posted June 6, 2016 Hi radevus, You can do something like this. (I made this for for an editor Im working on) http://designer.tankwars.io/scripts/global/mouseevents.js it covers: click, rightclick, middleclick, down, rightdown, middledown, up, rightup, middleup, drag, dragend, dragstart, rightdrag, rightdragend, rightdragstart, middledrag, middledragend, middledragstart, over and out. You need to change the "scene.mousePos" parts to another representation of mouseposition. (maybe "renderer.plugins.interaction.mouse.global") And for "_lastPosition: new Point()" you would need to use "new PIXI.Point()" (I'm using my own point class). Use it like this var Button = PIXI.Sprite.fromImage('...'); MouseEvents.init(Button); Button.mouse.click(function() { //... }); or.. var Box = PIXI.Sprite.fromImage('...'); MouseEvents.init(Box); Box.mouse.dragstart(function() { //... }); Box.mouse.drag(function() { //... }); Box.mouse.dragend(function() { //... }); Quote Link to comment Share on other sites More sharing options...
westy Posted June 8, 2016 Author Share Posted June 8, 2016 @ivan.popelyshev I'd love to come up with some sort of general solution, but I wouldn't even know where to begin! I don't have enough knowledge of how PIXI works to make any authoritive suggestions for what to do here. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 8, 2016 Share Posted June 8, 2016 40 minutes ago, westy said: @ivan.popelyshev I'd love to come up with some sort of general solution, but I wouldn't even know where to begin! I don't have enough knowledge of how PIXI works to make any authoritive suggestions for what to do here. You can use @bQvle 's code, he knows PIXI Quote Link to comment Share on other sites More sharing options...
westy Posted June 8, 2016 Author Share Posted June 8, 2016 5 minutes ago, ivan.popelyshev said: You can use @bQvle 's code, he knows PIXI I looked through the code, but I couldn't see anywhere it solves the frame lag problem (or any of the other problems I mentioned) - perhaps I just missed it? Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 8, 2016 Share Posted June 8, 2016 I improved drag&drop with new "pixi-display" plugin. That way I can move dragged elements on top of everything: http://pixijs.github.io/examples/index.html?s=display&f=zorder.js&title=Z-order&plugins=pixi-display&v=dev Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.