Refactor dnd utility and add drag lifecycle events
Attach pointerup and pointermove listeners to scene.input for reliable tracking. Emit dragstart, dragmove, and dragend events alongside drag. Rename relativeX/Y to deltaX/Y in DragDropEvent and integrate DisposableBag.
This commit is contained in:
parent
eefcef861a
commit
d993d55576
|
|
@ -1,70 +1,80 @@
|
||||||
type PointerRecord = {
|
import { DisposableBag } from "./disposable";
|
||||||
id: number;
|
|
||||||
x: number;
|
type PointerRecord = {
|
||||||
y: number;
|
id: number;
|
||||||
}
|
x: number;
|
||||||
|
y: number;
|
||||||
|
};
|
||||||
|
|
||||||
export enum DragDropEventType {
|
export enum DragDropEventType {
|
||||||
DOWN,
|
DOWN,
|
||||||
UP,
|
UP,
|
||||||
MOVE,
|
MOVE,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DragDropEvent = {
|
export type DragDropEvent = {
|
||||||
type: DragDropEventType,
|
type: DragDropEventType;
|
||||||
relativeX: number;
|
deltaX: number;
|
||||||
relativeY: number;
|
deltaY: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function dragDropEventEffect(
|
export function dragDropEventEffect(
|
||||||
gameObject: Phaser.GameObjects.GameObject,
|
gameObject: Phaser.GameObjects.GameObject,
|
||||||
) {
|
disposables?: DisposableBag,
|
||||||
let down: PointerRecord | null;
|
): () => void {
|
||||||
let up: PointerRecord | null;
|
let isDragging = false;
|
||||||
|
let down: PointerRecord | null = null;
|
||||||
function onPointerDown(pointer: Phaser.Input.Pointer) {
|
|
||||||
down = {
|
|
||||||
id: pointer.id,
|
|
||||||
x: pointer.x,
|
|
||||||
y: pointer.y
|
|
||||||
}
|
|
||||||
up = null;
|
|
||||||
|
|
||||||
const type = DragDropEventType.DOWN;
|
|
||||||
const relativeX = pointer.x - down.x;
|
|
||||||
const relativeY = pointer.y - down.y;
|
|
||||||
gameObject.emit('drag', {type, relativeX, relativeY});
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPointerUp(pointer: Phaser.Input.Pointer) {
|
|
||||||
if(!down) return;
|
|
||||||
up = {
|
|
||||||
id: pointer.id,
|
|
||||||
x: pointer.x,
|
|
||||||
y: pointer.y
|
|
||||||
}
|
|
||||||
|
|
||||||
const type = DragDropEventType.UP;
|
|
||||||
const relativeX = pointer.x - down.x;
|
|
||||||
const relativeY = pointer.y - down.y;
|
|
||||||
gameObject.emit('drag', {type, relativeX, relativeY});
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPointerMove(pointer: Phaser.Input.Pointer) {
|
|
||||||
if(!down || up) return;
|
|
||||||
if(down.id !== pointer.id) return;
|
|
||||||
|
|
||||||
const type = DragDropEventType.MOVE;
|
|
||||||
const relativeX = pointer.x - down.x;
|
|
||||||
const relativeY = pointer.y - down.y;
|
|
||||||
gameObject.emit('drag', {type, relativeX, relativeY});
|
|
||||||
}
|
|
||||||
|
|
||||||
gameObject.on('pointerdown', onPointerDown);
|
function onPointerDown(pointer: Phaser.Input.Pointer) {
|
||||||
gameObject.on('pointerup', onPointerUp);
|
if (isDragging) return;
|
||||||
gameObject.scene.input.on('pointermove', onPointerMove);
|
isDragging = true;
|
||||||
return function () {
|
down = { id: pointer.id, x: pointer.x, y: pointer.y };
|
||||||
gameObject.off('pointerdown', onPointerDown);
|
|
||||||
gameObject.off('pointerup', onPointerUp);
|
const event: DragDropEvent = {
|
||||||
gameObject.scene.input.off('pointermove', onPointerMove);
|
type: DragDropEventType.DOWN,
|
||||||
}
|
deltaX: 0,
|
||||||
}
|
deltaY: 0,
|
||||||
|
};
|
||||||
|
gameObject.emit("drag", event);
|
||||||
|
gameObject.emit("dragstart", event);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPointerUp(pointer: Phaser.Input.Pointer) {
|
||||||
|
if (!isDragging || !down || pointer.id !== down.id) return;
|
||||||
|
|
||||||
|
isDragging = false;
|
||||||
|
const deltaX = pointer.x - down.x;
|
||||||
|
const deltaY = pointer.y - down.y;
|
||||||
|
const event: DragDropEvent = { type: DragDropEventType.UP, deltaX, deltaY };
|
||||||
|
gameObject.emit("drag", event);
|
||||||
|
gameObject.emit("dragend", event);
|
||||||
|
down = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPointerMove(pointer: Phaser.Input.Pointer) {
|
||||||
|
if (!isDragging || !down || pointer.id !== down.id) return;
|
||||||
|
|
||||||
|
const deltaX = pointer.x - down.x;
|
||||||
|
const deltaY = pointer.y - down.y;
|
||||||
|
const event: DragDropEvent = {
|
||||||
|
type: DragDropEventType.MOVE,
|
||||||
|
deltaX,
|
||||||
|
deltaY,
|
||||||
|
};
|
||||||
|
gameObject.emit("drag", event);
|
||||||
|
gameObject.emit("dragmove", event);
|
||||||
|
}
|
||||||
|
|
||||||
|
gameObject.on("pointerdown", onPointerDown);
|
||||||
|
gameObject.scene.input.on("pointerup", onPointerUp);
|
||||||
|
gameObject.scene.input.on("pointermove", onPointerMove);
|
||||||
|
|
||||||
|
const dispose = () => {
|
||||||
|
gameObject.off("pointerdown", onPointerDown);
|
||||||
|
gameObject.scene.input.off("pointerup", onPointerUp);
|
||||||
|
gameObject.scene.input.off("pointermove", onPointerMove);
|
||||||
|
};
|
||||||
|
|
||||||
|
disposables?.add(dispose);
|
||||||
|
return dispose;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue