123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- import { KonvaEventObject } from "konva/lib/Node";
- import { hasTouchEvents } from "../env";
- import { Container } from "../packages";
- import { EntityType, Entity } from "../packages/entity";
- import { Attrib, ShapeType } from "../type";
- import { getTouchOffset } from "./act";
- import { createLineByDire, getDireDist } from "./math";
- import { inRevise } from "./public";
- import { disableMouse, enableMouse } from "./shape-mose";
- import { generateId, getChangeAllPoart } from "./util";
- const getExtendsProps = (parent: Entity<any, any>) => {
- return parent
- ? {
- reactive: parent.props.reactive,
- readonly: parent.props.reactive,
- }
- : {};
- };
- export const entityFactory = <
- T extends Attrib,
- S extends ShapeType,
- C extends EntityType<T, S, { attrib: T }>
- >(
- attrib: T,
- Type: C,
- parent?: Entity<any, any>,
- extra?: (self: InstanceType<C>) => void,
- created?: (self: InstanceType<C>) => void
- ) => {
- const entity = new Type({
- attrib,
- ...getExtendsProps(parent),
- }) as InstanceType<C>;
- extra && extra(entity);
- if (parent) {
- entity.container = parent.container;
- entity.setParent(parent);
- }
- entity.init();
- entity.mount(entity.teleport);
- if (parent.isMounted) {
- entity.mounted();
- }
- created && created(entity);
- return entity;
- };
- export type IncEntitysFactory<T extends Attrib, E extends Entity<T, any>> = (
- attribs: T[] | T
- ) => IncEntitys<T, E>;
- export type IncEntitys<T extends Attrib, E extends Entity<T, any>> = {
- adds: E[];
- dels: E[];
- upds: E[];
- };
- // 增量工厂
- export const incEntitysFactoryGenerate = <
- T extends Attrib,
- S extends ShapeType,
- C extends EntityType<T, S, { attrib: T }>
- >(
- Type: C,
- parent?: Entity<any, any>,
- extra?: (self: InstanceType<C>) => void,
- created?: (self: InstanceType<C>) => void
- ) => {
- let oldAttribs: T[] = [];
- const findAttrib = (attribs: T[], id: Attrib["id"]) =>
- attribs.find((attrib) => attrib.id === id);
- const cache: { [key in Attrib["id"]]: InstanceType<C> } = {};
- const destory = (id: Attrib["id"]) => {
- const delEntity = cache[id];
- delEntity.destory();
- delete cache[id];
- return delEntity;
- };
- const add = (attrib: T) => {
- const addEntity = entityFactory(attrib, Type, parent, extra, created);
- cache[attrib.id] = addEntity;
- return addEntity;
- };
- return (attribsRaw: T | T[]) => {
- const attribs = Array.isArray(attribsRaw) ? attribsRaw : [attribsRaw];
- const { addPort, delPort, changePort } = getChangeAllPoart(
- attribs,
- oldAttribs
- );
- const dels = delPort.map(destory);
- const adds = addPort.map((id) => add(findAttrib(attribs, id)));
- const upds = changePort.map((id) => {
- const newAttrib = findAttrib(attribs, id);
- if (inRevise(newAttrib, cache[id].attrib)) {
- console.log("setAttrib");
- cache[id].setAttrib(findAttrib(attribs, id));
- }
- return cache[id];
- });
- oldAttribs = [...attribs];
- return {
- adds,
- dels,
- upds,
- };
- };
- };
- export type CopyProps<T extends Entity = Entity> = {
- entity: T;
- count?: number;
- dire?: number[];
- size: number[];
- factoryAttrib(pos: number[]): any;
- };
- export const copyEntityAttrib = <T extends Entity = Entity>(
- props: CopyProps<T>
- ) => {
- const count = props.count || 1;
- const dire = props.dire || [1, 0];
- const halfSize = props.size;
- const entity = props.entity;
- const start = entity.shape.getPosition();
- const unit = getDireDist(halfSize);
- const items = entity.container.getSameLevelData(entity) as Attrib[];
- for (let i = 0; i < count; i++) {
- const line = createLineByDire(dire, [start.x, start.y], unit * (i + 1));
- const newAttrib = {
- ...props.factoryAttrib([line[2], line[3]]),
- id: generateId(items),
- };
- items.push(newAttrib as any);
- }
- };
- const interrupts = new WeakMap<Container, () => void>();
- export const addEntityAttrib = (
- container: Container,
- factoryAttrib: (pos: number[]) => any
- ) => {
- const oldInterrupt = interrupts.get(container);
- if (oldInterrupt) {
- oldInterrupt();
- }
- let finished = false;
- const finish = () => {
- if (finished) return;
- if (hasTouchEvents) {
- container.stage.off("touchend.addEntity");
- } else {
- container.stage.off("click.addEntity");
- }
- enableMouse();
- interrupts.delete(container);
- finished = true;
- };
- const complete = (data: any) => {
- finish();
- resolve(data);
- };
- const interrupt = () => {
- finish();
- reject("cancel");
- };
- let resolve: (data: any) => void, reject: (msg: string) => void;
- const promise = new Promise<any>((rs, rj) => {
- resolve = rs;
- reject = rj;
- const clickHandler = (ev: KonvaEventObject<any>) => {
- let offset = ev.evt;
- if (ev.evt instanceof TouchEvent) {
- offset = getTouchOffset(ev);
- }
- const pos = container.getRealFromStage([offset.offsetX, offset.offsetY]);
- complete(factoryAttrib(pos));
- };
- disableMouse();
- interrupts.set(container, interrupt);
- if (hasTouchEvents) {
- container.stage.on("touchend.addEntity", clickHandler);
- } else {
- container.stage.on("click.addEntity", clickHandler);
- }
- });
- return {
- promise,
- interrupt,
- };
- };
|