67 lines
No EOL
1.9 KiB
TypeScript
67 lines
No EOL
1.9 KiB
TypeScript
export class InteractionEvent {
|
|
x: number;
|
|
y: number;
|
|
}
|
|
|
|
export class Tragable {
|
|
static getRootSVG(elem: SVGElement): SVGSVGElement {
|
|
while (!(elem instanceof SVGSVGElement)) {
|
|
if (!(elem instanceof SVGElement)) throw new Error("Not in an SVG");
|
|
elem = elem.parentElement as any;
|
|
}
|
|
return elem;
|
|
}
|
|
|
|
#moveCB: (event: InteractionEvent) => any = () => { };
|
|
#clickCB: (event: InteractionEvent) => any = () => { };
|
|
initTrag(element: SVGElement) {
|
|
let svg = Tragable.getRootSVG(element);
|
|
let selected = false;
|
|
let moved = true;
|
|
element.addEventListener('mousedown', () => {
|
|
selected = true;
|
|
moved = false;
|
|
});
|
|
svg.addEventListener('mousemove', event => {
|
|
if (selected) {
|
|
moved = true;
|
|
this.#moveCB(event);
|
|
}
|
|
});
|
|
svg.addEventListener('mouseup', () => {
|
|
selected = false;
|
|
});
|
|
svg.addEventListener('mouseleave', event => {
|
|
selected = false;
|
|
});
|
|
element.addEventListener('click', event => {
|
|
if (!selected && !moved) this.#clickCB(event);
|
|
});
|
|
|
|
element.addEventListener('touchstart', () => {
|
|
selected = true;
|
|
moved = false;
|
|
console.log("td");
|
|
});
|
|
svg.addEventListener('touchmove', event => {
|
|
if (selected) {
|
|
moved = true;
|
|
let e = event.touches[0];
|
|
this.#moveCB({ x: e.clientX, y: e.clientY });
|
|
}
|
|
});
|
|
svg.addEventListener('touchend', () => {
|
|
selected = false;
|
|
});
|
|
svg.addEventListener('touchcancel', event => {
|
|
selected = false;
|
|
});
|
|
}
|
|
|
|
onMove(cb: (event: InteractionEvent) => any) {
|
|
this.#moveCB = cb;
|
|
}
|
|
onClick(cb: (event: InteractionEvent) => any) {
|
|
this.#clickCB = cb;
|
|
}
|
|
} |