|
@@ -1,7 +1,6 @@
|
|
|
import konva from "konva";
|
|
|
import { Attrib, ShapeStyles, ShapeType } from "../type";
|
|
|
import { DEV } from "../env";
|
|
|
-import { Shape } from "konva/lib/Shape";
|
|
|
import { Group } from "konva/lib/Group";
|
|
|
import { Layer } from "konva/lib/Layer";
|
|
|
import { Stage } from "konva/lib/Stage";
|
|
@@ -12,6 +11,7 @@ import {
|
|
|
openShapeDrag,
|
|
|
openShapeMouseStyles,
|
|
|
} from "../shared/shape-mose";
|
|
|
+import { Container } from "./container";
|
|
|
|
|
|
export type EntityBaseProps = {
|
|
|
reactive?: boolean;
|
|
@@ -22,6 +22,7 @@ export type EntityProps<T extends Attrib> = EntityBaseProps & {
|
|
|
name?: string;
|
|
|
attrib: T;
|
|
|
zIndex?: number;
|
|
|
+ teleport?: ShapeType;
|
|
|
};
|
|
|
|
|
|
type ParentShapeType<T extends ShapeType> = T extends Layer
|
|
@@ -30,33 +31,49 @@ type ParentShapeType<T extends ShapeType> = T extends Layer
|
|
|
? null
|
|
|
: Group;
|
|
|
|
|
|
+export type EntityTypeEvent<T extends string, R> = {
|
|
|
+ [key in T]: R;
|
|
|
+};
|
|
|
+
|
|
|
export type EntityType<
|
|
|
T extends Attrib,
|
|
|
S extends ShapeType,
|
|
|
P extends EntityProps<T> = EntityProps<T>,
|
|
|
- K extends Entity<T, S> = Entity<T, S>
|
|
|
-> = new (props: P) => K;
|
|
|
+ K extends Entity<T, S> = Entity<T, S>,
|
|
|
+ EK extends string = string,
|
|
|
+ ER = any
|
|
|
+> = (new (props: P) => K) & { EventHandler?: { [key in EK]: ER } };
|
|
|
|
|
|
-export abstract class Entity<T extends Attrib, S extends ShapeType> {
|
|
|
+export abstract class Entity<
|
|
|
+ T extends Attrib = Attrib,
|
|
|
+ S extends ShapeType = ShapeType
|
|
|
+> {
|
|
|
props: EntityProps<T>;
|
|
|
+ container: Container<
|
|
|
+ string,
|
|
|
+ Attrib,
|
|
|
+ ShapeType,
|
|
|
+ EntityType<Attrib, ShapeType>
|
|
|
+ >;
|
|
|
attrib: T;
|
|
|
shape: S;
|
|
|
name: string;
|
|
|
|
|
|
private zIndex: number;
|
|
|
- private teleport: ParentShapeType<S>;
|
|
|
+ teleport: ParentShapeType<S>;
|
|
|
|
|
|
children: Entity<Attrib, ShapeType>[] = [];
|
|
|
parent: Entity<Attrib, ShapeType>;
|
|
|
|
|
|
constructor(props: EntityProps<T>) {
|
|
|
this.name = props.name;
|
|
|
+ this.teleport = props.teleport as any;
|
|
|
this.props = props;
|
|
|
this.attrib = props.reactive ? (reactive(props.attrib) as T) : props.attrib;
|
|
|
this.zIndex = props.zIndex || 0;
|
|
|
|
|
|
if (DEV) {
|
|
|
- console.log(this.name + " create");
|
|
|
+ // console.log(this.name + " create");
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -66,6 +83,10 @@ export abstract class Entity<T extends Attrib, S extends ShapeType> {
|
|
|
}
|
|
|
|
|
|
abstract diffRedraw(): void;
|
|
|
+ redraw() {
|
|
|
+ this.diffRedraw();
|
|
|
+ this.children.forEach((child) => child.redraw());
|
|
|
+ }
|
|
|
|
|
|
setAttrib(newAttrib: Omit<T, "id">) {
|
|
|
this.attrib = depPartialUpdate(
|
|
@@ -78,31 +99,49 @@ export abstract class Entity<T extends Attrib, S extends ShapeType> {
|
|
|
private destoryReactive: () => void;
|
|
|
protected initReactive() {
|
|
|
this.destoryReactive && this.destoryReactive();
|
|
|
- return watchEffect(() => {
|
|
|
- this.diffRedraw();
|
|
|
- });
|
|
|
+ return watchEffect(
|
|
|
+ () => {
|
|
|
+ this.diffRedraw();
|
|
|
+ },
|
|
|
+ { flush: "post" }
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
init() {
|
|
|
this.shape = this.initShape();
|
|
|
this.shape.id(this.name);
|
|
|
- this.setAttrib(this.props.attrib);
|
|
|
- if (this.props.reactive) {
|
|
|
- this.destoryReactive = this.initReactive();
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
- setTeleport(tel?: ParentShapeType<S>) {
|
|
|
+ mount(tel?: ParentShapeType<S>) {
|
|
|
if (this.shape instanceof Stage) {
|
|
|
- throw "stage 为顶级容器无法挂载到";
|
|
|
- } else if (this.shape instanceof Layer && !(tel instanceof Stage)) {
|
|
|
+ throw "stage 为顶级容器无法挂载";
|
|
|
+ } else if (tel && this.shape instanceof Layer && !(tel instanceof Stage)) {
|
|
|
+ console.log(this.name, tel);
|
|
|
throw "layer 只能挂载到 Stage";
|
|
|
}
|
|
|
+
|
|
|
+ if (this.teleport && this.teleport === tel) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.children.sort((a, b) => a.zIndex - b.zIndex);
|
|
|
+
|
|
|
const parentShape = (tel || this.parent.shape) as Layer;
|
|
|
- this.shape.remove();
|
|
|
parentShape.add(this.shape);
|
|
|
+ this.teleport = parentShape as unknown as ParentShapeType<S>;
|
|
|
this.setZIndex(this.zIndex);
|
|
|
- this.teleport = tel;
|
|
|
+
|
|
|
+ this.setAttrib(this.props.attrib);
|
|
|
+ if (this.props.reactive) {
|
|
|
+ this.destoryReactive = this.initReactive();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ isMounted = false;
|
|
|
+ mounted() {
|
|
|
+ this.diffRedraw();
|
|
|
+ this.children.forEach((child) => child.mounted());
|
|
|
+ this.isMounted = true;
|
|
|
}
|
|
|
|
|
|
setParent(parent: Entity<any, any> | null) {
|
|
@@ -110,53 +149,63 @@ export abstract class Entity<T extends Attrib, S extends ShapeType> {
|
|
|
const ndx = this.parent.children.indexOf(this as any);
|
|
|
~ndx && this.parent.children.splice(ndx, 1);
|
|
|
}
|
|
|
- if (this.parent !== parent) {
|
|
|
- this.parent = parent;
|
|
|
- if (parent) {
|
|
|
- this.parent.children.push(this as any);
|
|
|
- this.setTeleport();
|
|
|
- }
|
|
|
+
|
|
|
+ this.parent = parent;
|
|
|
+ if (parent) {
|
|
|
+ this.parent.children.push(this as any);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private getLevelNdx(parent = this.parent) {
|
|
|
- const level = parent.children;
|
|
|
- for (let i = level.length - 1; i >= 0; i--) {
|
|
|
- if (level[i] !== this && level[i].zIndex <= this.zIndex) {
|
|
|
- return i + 1;
|
|
|
+ if (parent) {
|
|
|
+ const level = parent.children;
|
|
|
+ for (let i = level.length - 1; i >= 0; i--) {
|
|
|
+ if (level[i] !== this && level[i].zIndex <= this.zIndex) {
|
|
|
+ return i;
|
|
|
+ }
|
|
|
}
|
|
|
+ return -1;
|
|
|
}
|
|
|
- return 0;
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
setZIndex(index: number) {
|
|
|
this.zIndex = index;
|
|
|
const packNdx = this.getLevelNdx();
|
|
|
+ if (packNdx === null) return;
|
|
|
+
|
|
|
const packChild = this.parent.children;
|
|
|
- let repPack: any = this;
|
|
|
- for (let i = packNdx; i < packChild.length; i++) {
|
|
|
- const temp = packChild[i];
|
|
|
- packChild[i] = repPack;
|
|
|
- repPack = temp;
|
|
|
+ const oldNdx = packChild.indexOf(this);
|
|
|
+
|
|
|
+ if (oldNdx !== packNdx + 1) {
|
|
|
+ let rep: any = this;
|
|
|
+ for (let i = packNdx + 1; i < packChild.length; i++) {
|
|
|
+ const temp = packChild[i];
|
|
|
+ packChild[i] = rep;
|
|
|
+ rep = temp;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- const parentShape = this.teleport || (this.parent.shape as any);
|
|
|
+ const parentShape = this.teleport as any;
|
|
|
const levelShapes = parentShape.children;
|
|
|
const shapeNdx =
|
|
|
- packNdx === 0
|
|
|
+ packNdx === -1
|
|
|
? 0
|
|
|
- : levelShapes.indexOf(packChild[packNdx - 1].getShape()) + 1;
|
|
|
-
|
|
|
- if (shapeNdx !== 0) {
|
|
|
- let repShape: any = this.shape;
|
|
|
- for (let i = shapeNdx; i < levelShapes.length; i++) {
|
|
|
- const temp = levelShapes[i];
|
|
|
- parentShape.add(repShape);
|
|
|
- repShape.zIndex(i);
|
|
|
- repShape = temp;
|
|
|
+ : levelShapes.indexOf(packChild[packNdx].getShape()) + 1;
|
|
|
+ const oldShapeNdx = levelShapes.indexOf(this.shape);
|
|
|
+
|
|
|
+ if (oldShapeNdx !== shapeNdx) {
|
|
|
+ if (shapeNdx !== 0) {
|
|
|
+ let repShape: any = this.shape;
|
|
|
+ for (let i = shapeNdx; i < levelShapes.length; i++) {
|
|
|
+ const temp = levelShapes[i];
|
|
|
+ parentShape.add(repShape);
|
|
|
+ repShape.zIndex(i);
|
|
|
+ repShape = temp;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.shape.zIndex(0);
|
|
|
}
|
|
|
- } else {
|
|
|
- this.shape.zIndex(0);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -173,10 +222,14 @@ export abstract class Entity<T extends Attrib, S extends ShapeType> {
|
|
|
private activeDestory: () => void;
|
|
|
enableActive(activeCallback: (isActive: boolean) => void) {
|
|
|
this.disableActive();
|
|
|
- this.activeDestory = openShapeMouseStyles(this.shape, {
|
|
|
- active: () => activeCallback(true),
|
|
|
- common: () => activeCallback(false),
|
|
|
- });
|
|
|
+ this.activeDestory = openShapeMouseStyles(
|
|
|
+ this.shape,
|
|
|
+ {
|
|
|
+ active: () => activeCallback(true),
|
|
|
+ common: () => activeCallback(false),
|
|
|
+ },
|
|
|
+ "mouse-active"
|
|
|
+ );
|
|
|
}
|
|
|
disableActive() {
|
|
|
this.activeDestory && this.activeDestory();
|
|
@@ -184,9 +237,13 @@ export abstract class Entity<T extends Attrib, S extends ShapeType> {
|
|
|
}
|
|
|
|
|
|
private mouseActDestory: () => void;
|
|
|
- enableMouseAct(styles: ShapeStyles<Shape>) {
|
|
|
+ enableMouseAct(styles: ShapeStyles) {
|
|
|
this.disableMouseAct();
|
|
|
- this.mouseActDestory = openShapeMouseStyles(this.shape, styles as any);
|
|
|
+ this.mouseActDestory = openShapeMouseStyles(
|
|
|
+ this.shape,
|
|
|
+ styles,
|
|
|
+ "act-mouse"
|
|
|
+ );
|
|
|
}
|
|
|
disableMouseAct() {
|
|
|
this.mouseActDestory && this.mouseActDestory();
|
|
@@ -209,4 +266,17 @@ export abstract class Entity<T extends Attrib, S extends ShapeType> {
|
|
|
this.shape.destroy();
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ find(name: string): Entity {
|
|
|
+ for (const child of this.children) {
|
|
|
+ if (child.name === name) {
|
|
|
+ return child;
|
|
|
+ }
|
|
|
+ const childQueryed = child.find(name);
|
|
|
+ if (childQueryed) {
|
|
|
+ return childQueryed;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
}
|