123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- import { Entity, EntityEvent, EntityTree } from "./entity";
- import konva from "konva";
- import { entityMount } from "./entity-server";
- import { Emitter, Pos, RootMat } from "../type";
- import {
- EditModeProps,
- injectSetCursor,
- injectConstant,
- EditModeChange,
- openEditModePacking,
- injectPointerEvents,
- PointerEvents,
- } from "./entity-root-server";
- import { inRevise } from "../../shared";
- import { Transform } from "konva/lib/Util";
- export type RootEvent = EntityEvent & {
- triggerFocus: Entity;
- triggerDrag: Entity | null;
- addEntity: Entity;
- delEntity: Entity;
- setEntity: Entity;
- entityChangeBefore: void;
- entityChange: EditModeChange;
- entityChangeAfter: void;
- changeView: RootMat;
- changeViewPort: Pos;
- changeViewScale: RootMat["scale"];
- changeViewPosition: RootMat["position"];
- changeViewRotation: RootMat["rotation"];
- };
- export class Root<T extends Entity = any> extends Entity<
- null,
- konva.Layer,
- EntityTree<never, T, Root<Entity>>
- > {
- dragEntity: Entity | null = null;
- container?: HTMLDivElement;
- stage: konva.Stage;
- fixLayer: konva.Layer;
- tempLayer: konva.Layer;
- bus: Emitter<RootEvent>;
- mat: Transform;
- invMat: Transform;
- tempComtainer = document.createElement("div");
- constructor() {
- super({
- name: "container",
- attrib: null,
- key: "root",
- });
- this.root = this;
- this.stage = new konva.Stage({ container: document.createElement("div") });
- this.fixLayer = new konva.Layer();
- this.mat = this.stage.getTransform();
- this.invMat = this.mat.copy().invert();
- this.stage.add(this.fixLayer);
- this.setTeleport(this.stage);
- }
- history: null | { hasRecovery: boolean };
- setHistory(history: null | { hasRecovery: boolean }) {
- this.history = history;
- }
- setCursor = injectSetCursor(this);
- initShape() {
- return new konva.Layer();
- }
- trigger: PointerEvents;
- openPointerEvents() {
- this.trigger = injectPointerEvents(this);
- }
- closePointerEvents() {
- this.trigger && this.trigger.destory();
- }
- private __editPacking: ReturnType<typeof openEditModePacking>;
- get hasEditMode() {
- return !!this.__editPacking;
- }
- editMode(props?: EditModeProps) {
- if (this.__editPacking) {
- throw "当前正在编辑模式";
- }
- this.__editPacking = openEditModePacking(this, props);
- }
- leaveEditMode() {
- if (this.__editPacking) {
- this.__editPacking.complete();
- this.__editPacking = null;
- }
- }
- interruptEditMode() {
- if (this.__editPacking) {
- this.__editPacking.interrupt();
- this.__editPacking = null;
- }
- }
- getPixel(real: Pos) {
- return this.mat.point(real);
- }
- getReal(pixel: Pos) {
- return this.invMat.point(pixel);
- }
- constant = injectConstant(this);
- private __changeContainerRelease: () => void;
- mount(container: HTMLDivElement = this.tempComtainer): void {
- if (container === this.container && this.isMounted) return;
- if (!container) throw "mount 需要 container";
- if (this.container) {
- this.__changeContainerRelease();
- }
- const changeSize = () => {
- const w = container.offsetWidth;
- const h = container.offsetHeight;
- if (w !== this.stage.width() || h !== this.stage.height()) {
- this.stage.width(w);
- this.stage.height(h);
- this.bus.emit("changeViewPort", { x: w, y: h });
- }
- };
- if (container) {
- this.stage.setContainer(container);
- changeSize();
- window.addEventListener("resize", changeSize);
- this.__changeContainerRelease = () => {
- window.removeEventListener("resize", changeSize);
- };
- this.container = container;
- this.isMounted || entityMount(this);
- }
- }
- updateViewMat(transform: Transform) {
- const mat = transform.decompose();
- const scale = {
- x: mat.scaleX,
- y: mat.scaleY,
- };
- const position = {
- x: mat.x,
- y: mat.y,
- };
- const rotation = mat.rotation;
- const scaleChange = inRevise(scale, this.shape.scale());
- const positionChange = inRevise(position, this.shape.position());
- const rotateChange = inRevise(rotation, this.shape.rotation());
- this.shape.scale(scale);
- this.shape.rotate(rotation);
- this.shape.position(position);
- this.mat = transform.copy();
- this.invMat = transform.copy().invert();
- this.shape.draw();
- if (scaleChange) {
- this.bus.emit("changeViewScale", scale);
- }
- if (positionChange) {
- this.bus.emit("changeViewPosition", position);
- }
- if (rotateChange) {
- this.bus.emit("changeViewRotation", rotation);
- }
- if (rotateChange || scaleChange || positionChange) {
- this.bus.emit("changeView", {
- scale: this.shape.scale(),
- position: this.shape.position(),
- rotation: this.shape.rotation(),
- });
- }
- }
- }
|