<!DOCTYPE HTML>
<html>
<head>
<!-- Shamelessly adapted from pixi.js Example 8 - Dragging -->
<title>Sprite to Mouse Snapping issue</title>
<script src="pixi.js"></script>
</head>
<body>
<script>
var stage = new PIXI.Stage(0x97c56e, true);
var renderer = PIXI.autoDetectRenderer(window.innerWidth, window.innerHeight, null);
// add the renderer view element to the DOM
document.body.appendChild(renderer.view);
renderer.view.style.position = "absolute";
renderer.view.style.top = "0px";
renderer.view.style.left = "0px";
requestAnimFrame( animate );
// create a texture from an image path
var texture = PIXI.Texture.fromImage("aboriginal-bunny.png");
createAboriginalBunny(100, 100);
function createAboriginalBunny(x, y)
{
var bunny = new PIXI.Sprite(texture);
bunny.setInteractive(true);
// leaving anchor point at 10% to illustrate the problem clearer
bunny.anchor.x = 0.1;
bunny.anchor.y = 0.1;
/*
* Set-up dragging
*/
bunny.mousedown = bunny.touchstart = function(data)
{
this.data = data;
this.alpha = 0.5;
this.dragging = true;
};
bunny.mouseup = bunny.mouseupoutside = bunny.touchend = bunny.touchendoutside = function(data)
{
this.alpha = 1
this.dragging = false;
// set the interaction data to null
this.data = null;
};
bunny.mousemove = bunny.touchmove = function(data)
{
if(this.dragging)
{
// need to get parent coords..
var newPosition = this.data.getLocalPosition(this.parent);
this.position.x = newPosition.x;
this.position.y = newPosition.y;
}
}
// move the sprite to initial pos
bunny.position.x = x;
bunny.position.y = y;
stage.addChild(bunny);
}
function animate() {
requestAnimFrame( animate );
renderer.render(stage);
}
</script>
</body>
</html>
First of all, thank you for the detailed bug report and the sample code, it helps a lot when we are given so much information!
Unfortunately, this is not a bug. This issue is caused by you setting the position of the sprite to the position of the mouse each mousemove (most likely because that is what the example does). Really, what should happen is you should update your sprite by the delta of the mouse movement. Try something like this:
/*
* Set-up dragging
*/
bunny.mousedown = bunny.touchstart = function(data)
{
this.data = data;
this.alpha = 0.5;
this.dragging = this.data.getLocalPosition(this.parent);;
};
bunny.mouseup = bunny.mouseupoutside = bunny.touchend = bunny.touchendoutside = function(data)
{
this.alpha = 1
this.dragging = false;
// set the interaction data to null
this.data = null;
};
bunny.mousemove = bunny.touchmove = function(data)
{
if(this.dragging)
{
// need to get parent coords..
var newPosition = this.data.getLocalPosition(this.parent);
this.position.x += (newPosition.x - this.dragging.x);
this.position.y += (newPosition.y - this.dragging.y);
this.dragging = newPosition;
}
}
The important bits are on mousedown
I store the location of the mouse, then on mousemove
I update my sprite position by how much the mouse has _moved_ (not set it to the new position), then I update the stored mouse position for the next time. I hope this helps!
Hello,
This resolves my issue, and is much clearer to understand, thanks. And yes, my code is based on how the example works, so would be good if the example could be updated -- I recall having trouble understanding how it worked, guess it did not fully work. :P
A related question, is there strictly a need to set interaction data to null on mouseup?
I'm also still unclear when getLocalPosition is required, vs. just the current position.
PS. no worries re: bug report detail, least I could do. Thanks for providing the library. :)
The reason for getLocalPosition
is to transform the absolute coords of the mouse event, into local relative coords that DisplayObjects use. Each DisplayObject's position is relative to its parent, so we take the absolute mouse coords and transform them to be relative to the parent with this.data.getLocalPosition(this.parent)
.
It is isn't particularly necessary to set this.data = null
on mouseup. Really you should be able to just use the data
param to each function, and not use this.data
at all.
Thanks again for your help; pretty new to graphics libs, so getting to terms with various implementation choices. Appreciate the pixi devs taking the time to answer my questions in a timely manner.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
First of all, thank you for the detailed bug report and the sample code, it helps a lot when we are given so much information!
Unfortunately, this is not a bug. This issue is caused by you setting the position of the sprite to the position of the mouse each mousemove (most likely because that is what the example does). Really, what should happen is you should update your sprite by the delta of the mouse movement. Try something like this:
The important bits are on
mousedown
I store the location of the mouse, then onmousemove
I update my sprite position by how much the mouse has _moved_ (not set it to the new position), then I update the stored mouse position for the next time. I hope this helps!