В PixiJS объекты сцены являются интерактивными спрайтами
(PIXI.Sprite) или контейнерами
(PIXI.Container). Для реализации механизма Drag and Drop
необходимо использовать систему событий PixiJS, которая позволяет
отслеживать действия мыши и касаний. Основные события:
pointerdown — нажатие на объект.pointerup — отпускание объекта.pointerupoutside — отпускание за пределами сцены.pointermove — перемещение указателя.Чтобы объект реагировал на события, нужно включить его интерактивность:
sprite.interactive = true;
sprite.buttonMode = true; // Курсор изменяется при наведении
При событии pointerdown фиксируется начальная позиция
указателя и объекта. Это позволяет корректно смещать объект без
“скачков”:
sprite.on('pointerdown', onDragStart);
function onDragStart(event) {
this.data = event.data; // Сохраняем данные события
this.dragging = true; // Флаг состояния
this.dragOffset = {
x: event.data.getLocalPosition(this.parent).x - this.x,
y: event.data.getLocalPosition(this.parent).y - this.y
};
}
Использование getLocalPosition(this.parent) важно для
учета координат родительского контейнера.
Обновление позиции происходит в обработчике pointermove.
Перемещение выполняется только если объект находится в состоянии
dragging:
sprite.on('pointermove', onDragMove);
function onDragMove() {
if (this.dragging) {
const newPosition = this.data.getLocalPosition(this.parent);
this.x = newPosition.x - this.dragOffset.x;
this.y = newPosition.y - this.dragOffset.y;
}
}
Такой подход обеспечивает плавное перемещение и правильное смещение относительно точки захвата.
При событии pointerup или pointerupoutside
объект прекращает перемещаться. Необходимо очистить данные и флаг:
sprite.on('pointerup', onDragEnd);
sprite.on('pointerupoutside', onDragEnd);
function onDragEnd() {
this.dragging = false;
this.data = null;
}
Для ограничения перемещения объекта внутри границ сцены или контейнера используют проверку координат при обновлении:
function onDragMove() {
if (!this.dragging) return;
const pos = this.data.getLocalPosition(this.parent);
const minX = 0, maxX = app.screen.width - this.width;
const minY = 0, maxY = app.screen.height - this.height;
this.x = Math.min(Math.max(pos.x - this.dragOffset.x, minX), maxX);
this.y = Math.min(Math.max(pos.y - this.dragOffset.y, minY), maxY);
}
Такой код предотвращает выход объекта за пределы видимой области.
Для работы с множеством объектов удобно создавать функцию и применять ее к каждому спрайту:
function makeDraggable(sprite) {
sprite.interactive = true;
sprite.buttonMode = true;
sprite.on('pointerdown', onDragStart)
.on('pointermove', onDragMove)
.on('pointerup', onDragEnd)
.on('pointerupoutside', onDragEnd);
}
spritesArray.forEach(makeDraggable);
Это позволяет централизованно управлять поведением без дублирования кода.
Drag and Drop работает не только со спрайтами, но и с контейнерами. При этом важно учитывать координаты локальной системы:
container.on('pointerdown', onDragStart)
.on('pointermove', onDragMove)
.on('pointerup', onDragEnd)
.on('pointerupoutside', onDragEnd);
getLocalPosition всегда используется относительно
родителя контейнера, чтобы движения были корректными.
pointermove для всех
объектов через делегирование при большом количестве спрайтов.pointermove.interaction.moveWhenInside = true, чтобы отслеживать
движения только внутри канвы.Drag and Drop часто сочетается с кликами или hover-эффектами. Важно корректно разделять состояния:
sprite.on('pointertap', () => {
if (!sprite.dragging) {
console.log('Объект кликнут');
}
});
Проверка dragging предотвращает срабатывание клика во
время перемещения.
const app = new PIXI.Application({ width: 800, height: 600 });
document.body.appendChild(app.view);
const sprite = PIXI.Sprite.from('image.png');
sprite.x = 100;
sprite.y = 100;
makeDraggable(sprite);
app.stage.addChild(sprite);
Этот код создает интерактивный спрайт с возможностью перетаскивания, учитывая точку захвата и ограничения по экрану, что формирует базовую основу для любых Drag and Drop интерфейсов в PixiJS.