123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- import { Attrib, ShapeStyles, ShapeType } from "../type";
- import { Entity } from "../packages/entity";
- import { Shape } from "konva/lib/Shape";
- import { Group } from "konva/lib/Group";
- import { getAbsoluteTransform } from "./shape-helper";
- import { KonvaEventObject } from "konva/lib/Node";
- let mouseDisabled = false;
- const dragShapes: (Shape | Group)[] = [];
- export const disableMouse = () => {
- console.log("disable mose");
- mouseDisabled = true;
- dragShapes.forEach((shape) => shape.draggable(false));
- };
- export const enableMouse = () => {
- console.log("enable mose");
- mouseDisabled = false;
- dragShapes.forEach((shape) => shape.draggable(true));
- };
- export const openShapeMouseStyles = <T extends Shape | Group>(
- shape: T,
- styles: ShapeStyles,
- namespace = "mouse-style"
- ) => {
- shape.listening(true);
- const useEvents: string[] = [];
- const useOn = (name: string, cb: (ev: KonvaEventObject<any>) => void) => {
- shape.on(name, cb);
- useEvents.push(name);
- };
- let enter = false;
- let draging = false;
- let active = false;
- const mouseHandler = (ev: KonvaEventObject<any>) => {
- const api = draging
- ? "draging"
- : active
- ? "active"
- : enter
- ? "hover"
- : "common";
- if (!mouseDisabled) {
- styles[api] && styles[api](ev);
- }
- };
- if (styles.hover) {
- useOn(`mouseenter.${namespace}`, (ev) => {
- enter = true;
- mouseHandler(ev);
- });
- useOn(`mouseleave.${namespace}`, (ev) => {
- if (!draging) {
- enter = false;
- mouseHandler(ev);
- }
- });
- }
- if (styles.active) {
- useOn(`click.${namespace} touchend.${namespace}`, (ev) => {
- if (!styles.active) return;
- if (draging) return;
- active = true;
- mouseHandler(ev);
- setTimeout(() => {
- const stage = shape.getStage();
- if (!stage) return;
- stage.on(
- `click.${namespace}${shape.id()} touchend.${namespace}${shape.id()}`,
- (evt) => {
- if (evt.target !== shape) {
- active = false;
- mouseHandler(evt);
- }
- setTimeout(() => {
- if (!stage) return;
- stage.off(
- `click.${namespace}${shape.id()} touchend.${namespace}${shape.id()}`
- );
- });
- }
- );
- });
- });
- }
- useOn(`dragstart.${namespace}`, (ev) => {
- draging = true;
- mouseHandler(ev);
- });
- useOn(`dragend.${namespace}`, (ev) => {
- setTimeout(() => {
- draging = false;
- mouseHandler(ev);
- }, 16);
- });
- return () => {
- shape.listening(false);
- shape.off(useEvents.join(" "));
- };
- };
- export type DragHandlers<T> = {
- readyHandler?: (ev: KonvaEventObject<any>) => T;
- moveHandler: (
- move: number[],
- readyData: T,
- ev: KonvaEventObject<any>
- ) => void;
- endHandler?: (readyData: T, ev: KonvaEventObject<any>) => void;
- };
- export const openShapeDrag = <T extends Shape | Group, D>(
- shape: T,
- handler: DragHandlers<D>,
- transform = true,
- tfIncludeSelf = false
- ) => {
- let readlyData = null as D;
- if (!mouseDisabled) {
- shape.draggable(true);
- }
- dragShapes.push(shape);
- shape.dragBoundFunc((pos, ev) => {
- if (!mouseDisabled) {
- let move = pos;
- if (transform) {
- const tf = getAbsoluteTransform(shape, tfIncludeSelf).invert();
- move = tf.point(pos);
- }
- handler.moveHandler([move.x, move.y], readlyData, ev);
- }
- return shape.absolutePosition();
- });
- if (handler.readyHandler) {
- shape.on("dragstart.drag", (ev) => {
- if (!mouseDisabled) {
- readlyData = handler.readyHandler(ev);
- }
- });
- }
- if (handler.endHandler) {
- shape.on("dragend.drag", (ev) => {
- if (!mouseDisabled) {
- handler.endHandler(readlyData, ev);
- }
- });
- }
- return () => {
- const ndx = dragShapes.indexOf(shape);
- if (~ndx) {
- dragShapes.splice(ndx, 1);
- }
- shape.draggable(false);
- shape.off("dragstart.drag dragend.drag");
- };
- };
- export type EntityDragHandlers<R extends Attrib, T> = {
- readyHandler?: (attrib: R, ev: KonvaEventObject<any>) => T;
- moveHandler: (
- attrib: R,
- move: number[],
- readyData: T,
- ev: KonvaEventObject<any>
- ) => void;
- endHandler?: (attrib: R, readyData: T, ev: KonvaEventObject<any>) => void;
- };
- export const openEntityDrag = <T extends Attrib, S extends ShapeType, R>(
- entity: Entity<T, S>,
- handler: EntityDragHandlers<T, R>
- ) => {
- entity.enableDrag({
- readyHandler(ev) {
- return handler.readyHandler && handler.readyHandler(entity.attrib, ev);
- },
- moveHandler(move: number[], readyData: R, ev) {
- return handler.moveHandler(entity.attrib, move, readyData, ev);
- },
- endHandler(readlyData: R, ev) {
- return (
- handler.endHandler && handler.endHandler(entity.attrib, readlyData, ev)
- );
- },
- });
- };
- export const shapeTreeEq = (
- parent: ShapeType,
- eq: (shape: ShapeType) => boolean
- ) => {
- if (eq(parent)) {
- return parent;
- }
- if ("children" in parent) {
- for (const child of parent.children) {
- const e = shapeTreeEq(child, eq);
- if (e) {
- return child;
- }
- }
- }
- return null;
- };
- export const shapeParentsEq = (
- target: ShapeType,
- eq: (shape: ShapeType) => boolean
- ) => {
- while (target) {
- if (eq(target)) {
- return target;
- }
- target = target.parent as any;
- }
- return null;
- };
- export const shapeTreeContain = (parent: ShapeType, target: ShapeType) => {
- const eqShape = shapeTreeEq(parent, (shape) => shape === target);
- return !!eqShape;
- };
|