import { ModuleControl } from "queenjs"; import { reactive } from "vue"; import { EditorModule } from "../../module"; import { DesignComp } from "../../objects/DesignTemp/DesignComp"; import { Matrix } from "./Matrix"; import * as transforms from "./transforms"; import { GroupActionCtrl } from "./GroupCtrl"; type TransHandle = (this: TransferCtrl, e: MouseEvent) => void; export type TransCreateFn = (...args: any[]) => { mousedown?: TransHandle; mousemove: TransHandle; mouseup: TransHandle; }; export class TransferCtrl extends ModuleControl { compEl!: HTMLElement; pageEl!: HTMLElement; currComp!: DesignComp; currTransfer!: ReturnType; currObserver?: MutationObserver; transforms = transforms; groupCtrl = new GroupActionCtrl(this.module); transEvent = { startX: 0, startY: 0, offsetX: 0, offsetY: 0, width: 0, height: 0, }; transferStyle = reactive({ top: "", left: "", width: "", height: "", transform: { scale: 1, rotate: "0deg", translateX: "-50%", translateY: "-50%", }, }); originPiont = { x: 0, y: 0, }; init(pageEl: HTMLElement) { this.groupCtrl.init(); this.currComp = this.module.store.currComp; this.compEl = this.currComp.$el; this.pageEl = pageEl; this.observe(); } mousedown(e: MouseEvent, type: keyof typeof transforms, currComp?: any) { if (!currComp) { currComp = this.store.currComp; } this.currComp = currComp; this.compEl = currComp.$el; this.transEvent = { startX: e.clientX, startY: e.clientY, offsetX: 0, offsetY: 0, width: currComp.layout.size?.[0] || currComp.$el.clientWidth * 2, height: currComp.layout.size?.[1] || currComp.$el.clientHeight * 2, }; this.currTransfer = this.transforms[type](); document.addEventListener("mousemove", this.mousemove); document.addEventListener("mouseup", this.mouseup); this.currTransfer.mousedown?.call(this, e); } private mousemove = (e: MouseEvent) => { const { transEvent } = this; transEvent.offsetX = e.clientX - transEvent.startX; transEvent.offsetY = e.clientY - transEvent.startY; this.currTransfer.mousemove.call(this, e); }; private mouseup = (e: MouseEvent) => { document.removeEventListener("mousemove", this.mousemove); document.removeEventListener("mouseup", this.mouseup); this.currTransfer.mouseup.call(this, e); }; observe() { if (this.currObserver) { this.currObserver.disconnect(); } this.initStyle(); this.currObserver = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if ( mutation.type === "childList" || (mutation.type === "attributes" && mutation.attributeName === "style") ) { this.initStyle(); } }); }); this.currObserver.observe(this.compEl, { attributes: true, childList: true, subtree: true, characterData: true, }); } initStyle() { if (!this.compEl) return; const rect = this.compEl.getBoundingClientRect(); const pageRect = this.pageEl.getBoundingClientRect(); const matrix = new Matrix(); matrix.setFormDiv(this.compEl); const width = this.compEl.clientWidth * matrix.getScale(); const height = this.compEl.clientHeight * matrix.getScale(); this.transferStyle.width = width + "px"; this.transferStyle.height = height + "px"; this.transferStyle.top = rect.top + rect.height / 2 - pageRect.top + "px"; this.transferStyle.left = rect.left + rect.width / 2 - pageRect.left + "px"; if (!this.transferStyle.transform) { this.transferStyle.transform = { scale: 1, rotate: "0deg", translateX: "-50%", translateY: "-50%", }; } this.transferStyle.transform.scale = matrix.getScale(); this.transferStyle.transform.rotate = matrix.getRotate() + "deg"; this.transferStyle.transform.translateY = "-" + height / 2 + "px"; this.originPiont.x = rect.left + rect.width / 2; this.originPiont.y = rect.top + rect.height / 2; } resetStyle() { Object.keys(this.transferStyle).forEach((key) => { (this.transferStyle as any)[key] = ""; }); } destroy() { this.groupCtrl.destroy(); this.currObserver?.disconnect(); this.resetStyle(); } }