PixiJS Drag and Drop — Interactive Element Dragging
In this tutorial, you will learn about PixiJS Drag and Drop. We cover key concepts, practical examples, and best practices to help you master this topic.
PixiJS drag and drop enables interactive element dragging with pointer events for both mouse and touch input.
What You'll Learn
By the end of this guide, you will make sprites draggable with pointer events, implement drop zone detection, add snap-to-grid behavior, build sortable lists, and handle concurrent touch and mouse input.
Basic Draggable
sprite.interactive = true;
sprite.cursor = 'grab';
sprite.on('pointerdown', onDragStart)
.on('pointerup', onDragEnd)
.on('pointerupoutside', onDragEnd)
.on('pointermove', onDragMove);
var dragData = null;
function onDragStart(event) {
dragData = event.data;
this.alpha = 0.7;
this.dragging = true;
}
function onDragMove() {
if (this.dragging) {
var pos = dragData.getLocalPosition(this.parent);
this.x = pos.x;
this.y = pos.y;
}
}
function onDragEnd() {
this.alpha = 1;
this.dragging = false;
dragData = null;
}
Snap to Grid
function onDragMove() {
if (this.dragging) {
var pos = dragData.getLocalPosition(this.parent);
this.x = Math.round(pos.x / 50) * 50;
this.y = Math.round(pos.y / 50) * 50;
}
}
Drop Zone
dropZone.interactive = true;
dropZone.hitArea = new PIXI.Rectangle(0, 0, 100, 100);
function onDragEnd() {
this.alpha = 1;
this.dragging = false;
dragData = null;
if (dropZone.getBounds().contains(this.x, this.y)) {
this.position.set(
dropZone.x + dropZone.width / 2,
dropZone.y + dropZone.height / 2
);
console.log('Dropped in zone!');
}
}
Common Mistakes
1. Forgetting interactive = true
Sprites are not interactive by default. Set interactive = true to receive pointer events.
2. Using click Instead of pointer
Use pointerdown, pointermove, pointerup for unified mouse and touch handling.
3. Not Using getLocalPosition
Direct event.clientX/Y gives canvas coordinates. Use getLocalPosition for scene coordinates.
4. Dragging Outside Bounds
Without bounds checking, elements can be dragged off-screen. Clamp x, y after calculation.
5. Not Handling pointerupoutside
If the pointer moves off the sprite and releases, pointerupoutside fires but dragging should still end.
Practice Questions
Q1: How do you make a sprite draggable? A: Set interactive = true, then handle pointerdown, pointermove, pointerup events.
Q2: What event fires when dragging ends outside the sprite? A: pointerupoutside.
Q3: How do you get the correct drag position? A: Use event.data.getLocalPosition(sprite.parent).
Q4: How do you limit dragging to bounds? A: Clamp x and y after each pointermove.
Q5: How do you detect drop on a target? A: Check if the dragged sprite's position is within the target's bounds.
Challenge: Build a puzzle where pieces snap to a 3x3 grid. When all pieces are in correct positions, show a completion message. Pieces should animate back if dropped outside the grid.
FAQ
Try It Yourself
Build a draggable shape.
<!DOCTYPE html>
<html>
<head>
<title>PixiJS Drag Drop</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/7.3/pixi.min.js"></script>
</head>
<body style="font-family:sans-serif;padding:20px;">
<h2>Drag the Shapes</h2>
<script>
var app = new PIXI.Application({ width: 500, height: 350, background: 0xf5f5f5 });
document.body.appendChild(app.view);
var shapes = [
{ color: 0x4ecdc4, x: 80, y: 100 },
{ color: 0xff6b35, x: 200, y: 150 },
{ color: 0x2a9d8f, x: 320, y: 120 }
];
shapes.forEach(function(s) {
var g = new PIXI.Graphics();
g.beginFill(s.color);
g.drawRoundedRect(0, 0, 60, 60, 8);
g.endFill();
g.x = s.x;
g.y = s.y;
g.interactive = true;
g.cursor = 'grab';
g.on('pointerdown', function(event) {
this.alpha = 0.7;
this.dragging = true;
this.dragData = event.data;
this.parent.setChildIndex(this, this.parent.children.length - 1);
});
g.on('pointermove', function() {
if (this.dragging) {
var pos = this.dragData.getLocalPosition(this.parent);
this.x = Math.max(0, Math.min(440, pos.x - 30));
this.y = Math.max(0, Math.min(290, pos.y - 30));
}
});
g.on('pointerup', function() {
this.alpha = 1;
this.dragging = false;
});
g.on('pointerupoutside', function() {
this.alpha = 1;
this.dragging = false;
});
app.stage.addChild(g);
});
</script>
</body>
</html>
What's Next
Master interaction events.
Interaction — Event handling and interaction. Render Textures — Render textures.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro