diff --git a/packages/framework/src/utils/dnd.ts b/packages/framework/src/utils/dnd.ts index ae880a4..bcd7fb9 100644 --- a/packages/framework/src/utils/dnd.ts +++ b/packages/framework/src/utils/dnd.ts @@ -1,70 +1,80 @@ -type PointerRecord = { - id: number; - x: number; - y: number; -} +import { DisposableBag } from "./disposable"; + +type PointerRecord = { + id: number; + x: number; + y: number; +}; export enum DragDropEventType { - DOWN, - UP, - MOVE, + DOWN, + UP, + MOVE, } + export type DragDropEvent = { - type: DragDropEventType, - relativeX: number; - relativeY: number; -} + type: DragDropEventType; + deltaX: number; + deltaY: number; +}; export function dragDropEventEffect( - gameObject: Phaser.GameObjects.GameObject, -) { - let down: PointerRecord | null; - let up: PointerRecord | 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: Phaser.GameObjects.GameObject, + disposables?: DisposableBag, +): () => void { + let isDragging = false; + let down: PointerRecord | null = null; - gameObject.on('pointerdown', onPointerDown); - gameObject.on('pointerup', onPointerUp); - gameObject.scene.input.on('pointermove', onPointerMove); - return function () { - gameObject.off('pointerdown', onPointerDown); - gameObject.off('pointerup', onPointerUp); - gameObject.scene.input.off('pointermove', onPointerMove); - } -} \ No newline at end of file + function onPointerDown(pointer: Phaser.Input.Pointer) { + if (isDragging) return; + isDragging = true; + down = { id: pointer.id, x: pointer.x, y: pointer.y }; + + const event: DragDropEvent = { + 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; +}