|
@@ -2,12 +2,25 @@ import { ModuleControl } from "queenjs";
|
|
|
import { reactive } from "vue";
|
|
|
import { EditorModule } from "../../module";
|
|
|
import { DesignComp } from "../../objects/DesignTemp/DesignComp";
|
|
|
-import { Matrix } from "../TransferCtrl/Matrix";
|
|
|
+import { Matrix } from "./matrix";
|
|
|
+import { GroupActionCtrl } from "../TransferCtrl/GroupCtrl";
|
|
|
+import { Point } from "./objects/point";
|
|
|
+import { ObjsContainer } from "./ObjsContainer";
|
|
|
+import Event from "./event";
|
|
|
+import { DisplayObject } from "./objects/displayObject";
|
|
|
+import { CompObject } from "./compObj";
|
|
|
+import { each, eachRight } from "lodash";
|
|
|
+import { string } from "vue-types";
|
|
|
+import { Project, VectorLenth } from "./objects/mathUtils";
|
|
|
|
|
|
/**
|
|
|
* 页面画布空间进行选择
|
|
|
*/
|
|
|
const MODE_SEL_RECT = 1;
|
|
|
+const MODE_MOVING = 2;
|
|
|
+const MODE_ROTATE = 3;
|
|
|
+const MODE_SCALE = 4;
|
|
|
+
|
|
|
const MODE_NONE = 0;
|
|
|
|
|
|
export class SelectCtrl extends ModuleControl<EditorModule> {
|
|
@@ -21,144 +34,730 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
|
|
|
};
|
|
|
|
|
|
transferStyle = reactive({
|
|
|
- width: "",
|
|
|
- height: "",
|
|
|
- transform: {
|
|
|
- rotate: "0deg",
|
|
|
- translateX: 0,
|
|
|
- translateY: 0,
|
|
|
- scale: 1,
|
|
|
- },
|
|
|
+ showGizmo: false,
|
|
|
+ width: 0,
|
|
|
+ height: 0,
|
|
|
+ matrix: "matrix(1,0,0,1,0,0)",
|
|
|
+ matrixInvert: "matrix(1,0,0,1,0,0)",
|
|
|
});
|
|
|
- selectIds = []; //选中的所有组件ids
|
|
|
|
|
|
- pageEl?:HTMLElement
|
|
|
- selCanvas= {} as HTMLCanvasElement
|
|
|
+ selected: any[] = []; //选中的所有组件ids
|
|
|
+ mouseDownSelects: any[] = []; //鼠标按下时选中的
|
|
|
+
|
|
|
+ pageEl?: HTMLElement;
|
|
|
+ selCanvas = {} as HTMLCanvasElement;
|
|
|
|
|
|
_downed = false;
|
|
|
- _selCtx = {} as CanvasRenderingContext2D
|
|
|
+ _selCtx = {} as CanvasRenderingContext2D;
|
|
|
_state = MODE_SEL_RECT;
|
|
|
|
|
|
_selDownX = 0;
|
|
|
_selDownY = 0;
|
|
|
_selBox = {} as DOMRect;
|
|
|
- _selCanvaseSize = {w: 0, h: 0};
|
|
|
-
|
|
|
- initEvents(pageEl: HTMLElement, selCanvas: HTMLCanvasElement) {
|
|
|
+ _selCanvaseSize = { w: 0, h: 0 };
|
|
|
+ _downClientX = 0;
|
|
|
+ _downClientY = 0;
|
|
|
+ //groupCtrl = new GroupActionCtrl(this.module);
|
|
|
+ bus = new Event();
|
|
|
+ viewport?:HTMLElement;
|
|
|
+
|
|
|
+ initEvents(pageEl: HTMLElement, selCanvas: HTMLCanvasElement, viewport:HTMLElement) {
|
|
|
+ this.viewport = viewport;
|
|
|
this.pageEl = pageEl;
|
|
|
this.selCanvas = selCanvas;
|
|
|
const b = selCanvas.getBoundingClientRect();
|
|
|
- selCanvas.width = b.width *2;
|
|
|
- selCanvas.height = b.height *2;
|
|
|
+ selCanvas.width = b.width * 2;
|
|
|
+ selCanvas.height = b.height * 2;
|
|
|
|
|
|
this._selCtx = selCanvas.getContext("2d") as CanvasRenderingContext2D;
|
|
|
-
|
|
|
- this._selCanvaseSize.w = selCanvas.width *2;
|
|
|
- this._selCanvaseSize.h = selCanvas.height *2;
|
|
|
|
|
|
- document.addEventListener("mousedown", this.onDocMouseDown.bind(this))
|
|
|
- document.addEventListener("mousemove", this.onDocMouseMove.bind(this))
|
|
|
- document.addEventListener("mouseup", this.onDocMouseUp.bind(this))
|
|
|
+ this._selCanvaseSize.w = selCanvas.width * 2;
|
|
|
+ this._selCanvaseSize.h = selCanvas.height * 2;
|
|
|
+
|
|
|
+ document.addEventListener("mousedown", this.onDocMouseDown.bind(this));
|
|
|
+ document.addEventListener("mousemove", this.onDocMouseMove.bind(this));
|
|
|
+ document.addEventListener("mouseup", this.onDocMouseUp.bind(this));
|
|
|
|
|
|
window.addEventListener("resize", this.onResize.bind(this));
|
|
|
}
|
|
|
|
|
|
+ _mouseDownFlag = "";
|
|
|
onDocMouseDown(e: MouseEvent) {
|
|
|
- if (!this.pageEl || !this.selCanvas ) return;
|
|
|
+ if (!this.pageEl || !this.selCanvas) return;
|
|
|
|
|
|
let box = this.pageEl.getBoundingClientRect();
|
|
|
- const pageX = e.clientX- box?.left
|
|
|
- const pageY = e.clientY- box?.top
|
|
|
-
|
|
|
+ const pageX = e.clientX - box?.left;
|
|
|
+ const pageY = e.clientY - box?.top;
|
|
|
+
|
|
|
const card = this.store.currStreamCard.$el;
|
|
|
box = card.getBoundingClientRect();
|
|
|
const cardX = pageX;
|
|
|
const cardY = e.clientY - box.top;
|
|
|
|
|
|
const sel = this.selCanvas.getBoundingClientRect();
|
|
|
- const selX = (e.clientX - sel.left);
|
|
|
- const sely = (e.clientY - sel.top);
|
|
|
+ const selX = e.clientX - sel.left;
|
|
|
+ const sely = e.clientY - sel.top;
|
|
|
this._selDownX = selX;
|
|
|
this._selDownY = sely;
|
|
|
this._selBox = sel;
|
|
|
|
|
|
- console.log(cardX,selX, cardY, sely)
|
|
|
+ this._downClientX = e.clientX;
|
|
|
+ this._downClientY = e.clientY;
|
|
|
+
|
|
|
+ console.log(cardX, selX, cardY, sely);
|
|
|
|
|
|
this._downed = true;
|
|
|
- this._state = MODE_SEL_RECT;
|
|
|
+ this._mouseDownFlag = this.getDivFlag(e.target as any);
|
|
|
+ if (!this._mouseDownFlag) {
|
|
|
+ //选框点击判断
|
|
|
+ let isClickSelRect = false;
|
|
|
+ if (this.selected.length > 0) {
|
|
|
+ isClickSelRect = this.objContainer?.testClick(cardX, cardY) as boolean;
|
|
|
+ if (isClickSelRect) {
|
|
|
+ this._state = MODE_MOVING;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isClickSelRect) {
|
|
|
+ //判断是否有点击到card stream
|
|
|
+ const comps = this.compClickTest(e);
|
|
|
+ this.mouseDownSelects = comps;
|
|
|
+ console.log("comps=>", comps);
|
|
|
+ if (comps.length < 1) {
|
|
|
+ const view = this.viewport?.getBoundingClientRect() as any;
|
|
|
+ const isOut = (e.clientX < view.left || e.clientX > (view.right) || e.clientY < view.top || e.clientY > view.bottom)
|
|
|
+ if (!isOut) {
|
|
|
+ this._state = MODE_SEL_RECT;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this._state = MODE_MOVING;
|
|
|
+ const obj = this.compMap[comps[0].id];
|
|
|
+ this.selecteObjs([new CompObject(obj)]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (this._mouseDownFlag == "rotate") {
|
|
|
+ this._state = MODE_ROTATE;
|
|
|
+ } else if (this._mouseDownFlag == "move") {
|
|
|
+ this._state = MODE_MOVING;
|
|
|
+ } else if (this._mouseDownFlag.indexOf("scale") > -1) {
|
|
|
+ this._state = MODE_SCALE;
|
|
|
+ }
|
|
|
+
|
|
|
+ this._movePreClientX = this._downClientX;
|
|
|
+ this._movePreClientY = this._downClientY;
|
|
|
+ }
|
|
|
+
|
|
|
+ getDivFlag(div: HTMLElement) {
|
|
|
+ let c: any = div;
|
|
|
+ if (!c) return;
|
|
|
+ let i = 0;
|
|
|
+ do {
|
|
|
+ if (c.editable) return c.editable;
|
|
|
+ c = div.parentElement;
|
|
|
+ i += 1;
|
|
|
+ if (i > 3) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } while (c);
|
|
|
+ }
|
|
|
+
|
|
|
+ compClickTest(e: MouseEvent) {
|
|
|
+ const cards = this.store.streamCardIds;
|
|
|
+ let n = cards.length;
|
|
|
+ const compMap = this.store.designData.compMap;
|
|
|
+ //@ts-ignore
|
|
|
+ const pbox = this.pageEl.getBoundingClientRect();
|
|
|
+ const pageX = e.clientX - pbox?.left;
|
|
|
+
|
|
|
+ const Out = [];
|
|
|
+ while (n--) {
|
|
|
+ const cardComp = compMap[cards[n]];
|
|
|
+ const box = cardComp.$el.getBoundingClientRect();
|
|
|
+ const cardY = e.clientY - box.top;
|
|
|
+
|
|
|
+ const cardChilds = cardComp.children.default || [];
|
|
|
+ for (const key of cardChilds) {
|
|
|
+ const c = compMap[key];
|
|
|
+ const m = Matrix.createFromDiv(c.$el);
|
|
|
+ const localp = m.applyInverse(new Point(pageX, cardY));
|
|
|
+ const cw = this.helper.designSizeToPx(c.layout.size?.[0] as number);
|
|
|
+ const ch = this.helper.designSizeToPx(c.layout.size?.[1] as number);
|
|
|
+ const out =
|
|
|
+ localp.x < 0 || localp.x > cw || localp.y < 0 || localp.y > ch;
|
|
|
+ if (!out) {
|
|
|
+ Out.push({
|
|
|
+ id: key,
|
|
|
+ el: c.$el,
|
|
|
+ cardX: pageX,
|
|
|
+ cardY: cardY,
|
|
|
+ cardId: cards[n],
|
|
|
+ startMatrix: m,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return Out;
|
|
|
+ }
|
|
|
+
|
|
|
+ streamCardClickTest(e: MouseEvent) {
|
|
|
+ const cards = this.store.streamCardIds;
|
|
|
+ let n = cards.length;
|
|
|
+ const compMap = this.store.designData.compMap;
|
|
|
+ //@ts-ignore
|
|
|
+ const pbox = this.pageEl.getBoundingClientRect();
|
|
|
+ const pageX = e.clientX - pbox?.left;
|
|
|
+ if (pageX < 0 || pageX > pbox.width) return "";
|
|
|
+ while (n--) {
|
|
|
+ const card = compMap[cards[n]];
|
|
|
+ const box = card.$el.getBoundingClientRect();
|
|
|
+ if (e.clientY >= box.top && e.clientY <= box.bottom)
|
|
|
+ return { id: cards[n], x: pageX, y: e.clientY - box.top };
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ _moveSelectUpdated = false;
|
|
|
+
|
|
|
+ updateSelects() {
|
|
|
+ if (this._moveSelectUpdated) return;
|
|
|
+ this._moveSelectUpdated = true;
|
|
|
+
|
|
|
+ //鼠标按下并移动中 修正当前选中的对象
|
|
|
+ if (this.selected.length < 1) {
|
|
|
+ //没有被选中的
|
|
|
+ this.selected = this.mouseDownSelects;
|
|
|
+ } else {
|
|
|
+ //当前有选中的
|
|
|
+ let findSeleted = false;
|
|
|
+ let n = this.selected.length;
|
|
|
+ if (this.mouseDownSelects.length > 0) {
|
|
|
+ while (n--) {
|
|
|
+ const item = this.mouseDownSelects.find(
|
|
|
+ (item) => item.id == this.selected[n].id
|
|
|
+ );
|
|
|
+ if (item) findSeleted = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!findSeleted) {
|
|
|
+ this.selected = this.mouseDownSelects;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (this.selected.length > 0) {
|
|
|
+ this._state = MODE_MOVING;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ translate(xOffset:number, yOffset:number) {
|
|
|
+ const objContainer = this.objContainer as ObjsContainer;
|
|
|
+ objContainer.translate(xOffset, yOffset);
|
|
|
+ this.upgateGizmoStyle();
|
|
|
}
|
|
|
|
|
|
+ movingMousemove(e: MouseEvent) {
|
|
|
+ const objContainer = this.objContainer as ObjsContainer;
|
|
|
+
|
|
|
+ objContainer.translate(
|
|
|
+ e.clientX - this._movePreClientX,
|
|
|
+ e.clientY - this._movePreClientY
|
|
|
+ );
|
|
|
+
|
|
|
+ this.upgateGizmoStyle();
|
|
|
+ }
|
|
|
+
|
|
|
+ _movePreClientX = 0;
|
|
|
+ _movePreClientY = 0;
|
|
|
+
|
|
|
onDocMouseMove(e: MouseEvent) {
|
|
|
- if (!this.pageEl ) return;
|
|
|
+ if (!this.pageEl) return;
|
|
|
|
|
|
if (!this._downed) {
|
|
|
- this.checkHover();
|
|
|
+ this.checkHover();
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
switch (this._state) {
|
|
|
- case MODE_SEL_RECT: //选框模式
|
|
|
- this.drawSelRect(e);
|
|
|
- break;
|
|
|
+ case MODE_SEL_RECT: //选框模式
|
|
|
+ this.drawSelRect(e);
|
|
|
+ break;
|
|
|
+ case MODE_MOVING:
|
|
|
+ this.movingMousemove(e);
|
|
|
+ break;
|
|
|
+ case MODE_ROTATE:
|
|
|
+ this.rotateMousemove(e);
|
|
|
+ break;
|
|
|
+ case MODE_SCALE:
|
|
|
+ this.scaleMousemove(e);
|
|
|
}
|
|
|
+
|
|
|
+ this._movePreClientY = e.clientY;
|
|
|
+ this._movePreClientX = e.clientX;
|
|
|
+ }
|
|
|
+
|
|
|
+ get compMap() {
|
|
|
+ return this.store.designData.compMap;
|
|
|
}
|
|
|
|
|
|
onDocMouseUp(e: MouseEvent) {
|
|
|
+ let isClick = false;
|
|
|
+ const dx = Math.abs(e.clientX - this._downClientX);
|
|
|
+ const dy = Math.abs(e.clientY - this._downClientY);
|
|
|
+ if (dx < 2 && dy < 2) {
|
|
|
+ isClick = true;
|
|
|
+ }
|
|
|
+ if (isClick) {
|
|
|
+ this._state = MODE_NONE;
|
|
|
+ if (this.mouseDownSelects.length < 1) this.selecteObjs([]);
|
|
|
+ else {
|
|
|
+ const objs = this.mouseDownSelects.map(
|
|
|
+ (item) => new CompObject(this.compMap[item.id])
|
|
|
+ );
|
|
|
+ this.selecteObjs(objs);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
console.log("up");
|
|
|
+
|
|
|
+ if (this._state == MODE_SEL_RECT && !isClick) {
|
|
|
+ //选择空间转 streamCard空间
|
|
|
+ const card = this.store.currStreamCard;
|
|
|
+ const box = card.$el.getBoundingClientRect();
|
|
|
+ this.rectSelect(
|
|
|
+ this._lastSelRect[0] - box.left,
|
|
|
+ this._lastSelRect[1] - box.top,
|
|
|
+ this._lastSelRect[2],
|
|
|
+ this._lastSelRect[3]
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this._state == MODE_ROTATE) {
|
|
|
+ this.rotateMouseUp(e);
|
|
|
+ }
|
|
|
+ if (this._state == MODE_SCALE) {
|
|
|
+ this.scaleMouseUp(e);
|
|
|
+ }
|
|
|
this._state = MODE_NONE;
|
|
|
- this._selCtx?.clearRect(0, 0, this._selCanvaseSize.w, this._selCanvaseSize.h)
|
|
|
+ this._downed = false;
|
|
|
+ this._moveSelectUpdated = false;
|
|
|
+ this._selCtx?.clearRect(
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ this._selCanvaseSize.w,
|
|
|
+ this._selCanvaseSize.h
|
|
|
+ );
|
|
|
+
|
|
|
+ this.upgateGizmoStyle();
|
|
|
+ }
|
|
|
+
|
|
|
+ rectSelect(x: number, y: number, width: number, height: number) {
|
|
|
+ const childs =
|
|
|
+ this.compMap[this.store.currStreamCardId].children.default || [];
|
|
|
+ let n = childs.length;
|
|
|
+ const outs = [];
|
|
|
+ while (n--) {
|
|
|
+ const o = new CompObject(this.compMap[childs[n]]);
|
|
|
+ if (o.testRect({ x, y, w: width, h: height }, true)) {
|
|
|
+ //相交
|
|
|
+ outs.push(o);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ console.log(outs);
|
|
|
+
|
|
|
+ this.selecteObjs(outs);
|
|
|
+ }
|
|
|
+
|
|
|
+ upgateGizmoStyle() {
|
|
|
+ if (this.selected.length < 1) {
|
|
|
+ this.transferStyle.showGizmo = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.transferStyle.showGizmo = false;
|
|
|
+
|
|
|
+ const selector = this.objContainer as ObjsContainer;
|
|
|
+ if (!selector) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.transferStyle.showGizmo = true;
|
|
|
+
|
|
|
+ let obj = selector.parent;
|
|
|
+ let w = selector.rect.width,
|
|
|
+ h = selector.rect.height;
|
|
|
+
|
|
|
+ let tmp = new Matrix();
|
|
|
+ tmp.copyFrom(obj.worldTransform);
|
|
|
+ // tmp.scale(0.5 , 0.5);
|
|
|
+
|
|
|
+ let matrix = `matrix(${tmp.a},${tmp.b},${tmp.c},${tmp.d},${tmp.tx},${tmp.ty})`;
|
|
|
+ tmp.invert();
|
|
|
+ let matrixInvert = `matrix(${tmp.a},${tmp.b},${tmp.c},${tmp.d},0,0)`;
|
|
|
+
|
|
|
+ this.transferStyle.width = w;
|
|
|
+ this.transferStyle.height = h;
|
|
|
+ this.transferStyle.matrix = matrix;
|
|
|
+ this.transferStyle.matrixInvert = matrixInvert;
|
|
|
}
|
|
|
-
|
|
|
- selectId(id :string) { //选中ids之前 id对应组件必须已经渲染
|
|
|
- console.log("selectId=>", id)
|
|
|
+
|
|
|
+ selectId(id: string) {
|
|
|
+ //选中ids之前 id对应组件必须已经渲染
|
|
|
+ console.log("selectId=>", id);
|
|
|
}
|
|
|
|
|
|
- drawSelRect(e:MouseEvent) {
|
|
|
+ _lastSelRect = [0, 0, 0, 0];
|
|
|
|
|
|
+ drawSelRect(e: MouseEvent) {
|
|
|
const ctx = this._selCtx;
|
|
|
|
|
|
const dx = this._selDownX;
|
|
|
const dy = this._selDownY;
|
|
|
- const currX = e.clientX - this._selBox.left;
|
|
|
- const currY = e.clientY - this._selBox.top;
|
|
|
- const x = Math.min(currX, dx), y = Math.min(dy, currY)
|
|
|
- ctx.clearRect(0, 0, this._selCanvaseSize.w, this._selCanvaseSize.h)
|
|
|
-
|
|
|
- ctx.fillStyle = "rgba(232, 139, 0, 0.16)";
|
|
|
- ctx.fillRect(x*2, y*2, Math.abs(currX-dx)*2, Math.abs(currY-dy)*2);
|
|
|
-
|
|
|
- ctx.lineWidth = 2;
|
|
|
- ctx.strokeStyle = "#E88B00";
|
|
|
- ctx.strokeRect(x*2, y*2, Math.abs(currX-dx)*2, Math.abs(currY-dy)*2);
|
|
|
+ const currX = e.clientX - this._selBox.left;
|
|
|
+ const currY = e.clientY - this._selBox.top;
|
|
|
+ const x = Math.min(currX, dx),
|
|
|
+ y = Math.min(dy, currY);
|
|
|
+ ctx.clearRect(0, 0, this._selCanvaseSize.w, this._selCanvaseSize.h);
|
|
|
+
|
|
|
+ ctx.fillStyle = "rgba(232, 139, 0, 0.16)";
|
|
|
+ const w = Math.abs(currX - dx);
|
|
|
+ const h = Math.abs(currY - dy);
|
|
|
+ ctx.fillRect(x * 2, y * 2, w * 2, h * 2);
|
|
|
+
|
|
|
+ ctx.lineWidth = 2;
|
|
|
+ ctx.strokeStyle = "#E88B00";
|
|
|
+ ctx.strokeRect(x * 2, y * 2, w * 2, h * 2);
|
|
|
+
|
|
|
+ this._lastSelRect[0] = x + this._selBox.left;
|
|
|
+ this._lastSelRect[1] = y + this._selBox.top;
|
|
|
+ this._lastSelRect[2] = w;
|
|
|
+ this._lastSelRect[3] = h;
|
|
|
}
|
|
|
|
|
|
checkHover() {
|
|
|
- this.selectIds;
|
|
|
+ this.selCanvas;
|
|
|
}
|
|
|
|
|
|
onResize() {
|
|
|
-
|
|
|
const b = this.selCanvas.getBoundingClientRect();
|
|
|
- this.selCanvas.width = b.width *2;
|
|
|
- this.selCanvas.height = b.height *2;
|
|
|
+ this.selCanvas.width = b.width * 2;
|
|
|
+ this.selCanvas.height = b.height * 2;
|
|
|
this._selCtx = this.selCanvas.getContext("2d") as CanvasRenderingContext2D;
|
|
|
- this._selCanvaseSize.w = b.width *2;
|
|
|
- this._selCanvaseSize.h = b.height *2;
|
|
|
+ this._selCanvaseSize.w = b.width * 2;
|
|
|
+ this._selCanvaseSize.h = b.height * 2;
|
|
|
}
|
|
|
//
|
|
|
- checkIntersect(compId:string, e:MouseEvent) {
|
|
|
- const currCard = this.store.currStreamCard.$el;
|
|
|
+ checkIntersect(compId: string, e: MouseEvent) {
|
|
|
+ const currCard = this.store.currStreamCard.$el;
|
|
|
+
|
|
|
+ const comp = this.store.designData.compMap[compId];
|
|
|
+
|
|
|
+ //排除坐标没有在streamCard空间内的坐标
|
|
|
|
|
|
- const comp = this.store.designData.compMap[compId];
|
|
|
+ //把当前的card坐标转为 组件的自己local坐标判断是否在方框外面
|
|
|
+ const cardBox = currCard.getBoundingClientRect();
|
|
|
+ const cardX = e.clientX - cardBox.left;
|
|
|
+ const cardY = e.clientY - cardBox.top;
|
|
|
|
|
|
- //排除坐标没有在streamCard空间内的坐标
|
|
|
+ //const m = Matrix.createFromComp(comp.layout.transform)
|
|
|
+ }
|
|
|
+ objContainer?: ObjsContainer;
|
|
|
+
|
|
|
+ selecteObjs(objs: any[], ContainerBox?: ObjsContainer) {
|
|
|
+ if (this.selected.length == 0 && objs.length == 0) return;
|
|
|
+ if (
|
|
|
+ this.selected.length == 1 &&
|
|
|
+ objs.length == 1 &&
|
|
|
+ this.selected[0] == objs[0]
|
|
|
+ )
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (objs.length == 1) {
|
|
|
+ this.actions.pickComp(objs[0].comp.id);
|
|
|
+ }
|
|
|
+
|
|
|
+ // objs = this.getSceneObjOrderArr(objs);
|
|
|
+
|
|
|
+ const preObjContainer = this.objContainer;
|
|
|
+
|
|
|
+ if (this.objContainer) {
|
|
|
+ this.objContainer.destroy();
|
|
|
+ this.objContainer = undefined;
|
|
|
+ }
|
|
|
+
|
|
|
+ let newObjContainer = undefined;
|
|
|
+
|
|
|
+ if (objs.length > 0 && objs[0]) {
|
|
|
+ newObjContainer = ContainerBox ? ContainerBox : new ObjsContainer(objs);
|
|
|
+ if (ContainerBox) {
|
|
|
+ objs.forEach((obj) => {
|
|
|
+ ContainerBox.parent.addChildWorldNoChange(obj);
|
|
|
+ });
|
|
|
+ ContainerBox.selected = objs;
|
|
|
+ ContainerBox.parent.updateTransform();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.objContainer = newObjContainer;
|
|
|
+
|
|
|
+ const pre = this.selected.slice(0);
|
|
|
+ this.selected = objs;
|
|
|
+
|
|
|
+ // if (history) {
|
|
|
+ // this.editor.history.record({
|
|
|
+ // undo: () => {
|
|
|
+
|
|
|
+ // this.selected = pre;
|
|
|
+
|
|
|
+ // if (preObjContainer) {
|
|
|
+ // let parent = preObjContainer.parent;
|
|
|
+ // pre.forEach(obj => {
|
|
|
+ // parent.addChildWorldNoChange(obj);
|
|
|
+ // });
|
|
|
+ // parent.updateTransform();
|
|
|
+ // this.objContainer = preObjContainer;
|
|
|
+ // } else {
|
|
|
+ // this.objContainer = null;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // this.emitChange();
|
|
|
+
|
|
|
+ // }, redo: () => {
|
|
|
+ // this.selected = objs;
|
|
|
+
|
|
|
+ // if (preObjContainer) {
|
|
|
+ // preObjContainer.destroy();
|
|
|
+ // }
|
|
|
+
|
|
|
+ // if (newObjContainer) {
|
|
|
+ // let parent = newObjContainer.parent;
|
|
|
+ // objs.forEach(obj => {
|
|
|
+ // parent.addChildWorldNoChange(obj);
|
|
|
+ // });
|
|
|
+ // parent.updateTransform();
|
|
|
+ // this.objContainer = newObjContainer;
|
|
|
+ // } else {
|
|
|
+ // this.objContainer = null;
|
|
|
+ // }
|
|
|
+ // this.emitChange();
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ // }
|
|
|
+ this.emitChange();
|
|
|
+ this.upgateGizmoStyle();
|
|
|
+
|
|
|
+ return this.selected;
|
|
|
+ }
|
|
|
+
|
|
|
+ emitChange() {
|
|
|
+ const selected = this.selected;
|
|
|
+ if (selected.length && selected[0]) {
|
|
|
+ this.bus.emit("showProps", selected[0].from);
|
|
|
+ } else {
|
|
|
+ this.bus.emit("showProps");
|
|
|
+ }
|
|
|
+ this.bus.emit("selectedChange");
|
|
|
+ }
|
|
|
|
|
|
- //把当前的card坐标转为 组件的自己local坐标判断是否在方框外面
|
|
|
- const cardBox = currCard.getBoundingClientRect();
|
|
|
- const cardX = e.clientX - cardBox.left;
|
|
|
- const cardY = e.clientY - cardBox.top;
|
|
|
-
|
|
|
- //const m = Matrix.createFromComp(comp.layout.transform)
|
|
|
+ rotateCenter?: { x: number; y: number };
|
|
|
+ ratatePre = 0;
|
|
|
+ objinitAngleRad = 0;
|
|
|
+ rotateCmd = false;
|
|
|
+ lastRad = 0;
|
|
|
|
|
|
+ rotateMousemove(e: MouseEvent) {
|
|
|
+ const card = this.store.currStreamCard;
|
|
|
+
|
|
|
+ const rect = card.$el.getBoundingClientRect();
|
|
|
+ let StartX = e.clientX - rect.left;
|
|
|
+ let StartY = e.clientY - rect.top;
|
|
|
+
|
|
|
+ const objContainer = this.objContainer as ObjsContainer;
|
|
|
+
|
|
|
+ //获取当前屏幕坐标和选框中心点坐标,计算旋转值
|
|
|
+ if (!this.rotateCenter) {
|
|
|
+ //let rect = this.objContainer.parent.getBounds(false);
|
|
|
+ let center = objContainer.setPivot(4);
|
|
|
+
|
|
|
+ this.rotateCenter = center;
|
|
|
+
|
|
|
+ let vec = { x: StartX - center.x, y: StartY - center.y };
|
|
|
+
|
|
|
+ let angle = Math.atan2(vec.y, vec.x);
|
|
|
+ if (angle < 0) angle += 2 * Math.PI;
|
|
|
+ this.ratatePre = angle;
|
|
|
+
|
|
|
+ this.objinitAngleRad = objContainer.parent.rotation;
|
|
|
+
|
|
|
+ this.rotateCmd = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ let center = this.rotateCenter;
|
|
|
+ let vec = { x: StartX - center.x, y: StartY - center.y };
|
|
|
+ let angle = Math.atan2(vec.y, vec.x);
|
|
|
+ if (angle < 0) angle += 2 * Math.PI;
|
|
|
+
|
|
|
+ let dta = this.objinitAngleRad + angle - this.ratatePre;
|
|
|
+ if (e.shiftKey) {
|
|
|
+ //规整到0 90 180 270
|
|
|
+ if (dta < 0) dta += 2 * Math.PI;
|
|
|
+ let Deg45 = Math.PI / 4.0;
|
|
|
+ let Deg90 = Math.PI / 2.0;
|
|
|
+ let Deg135 = Deg45 * 3;
|
|
|
+ let Deg225 = Deg45 * 5;
|
|
|
+ let Deg270 = Deg45 * 6;
|
|
|
+ let Deg315 = Deg45 * 7;
|
|
|
+ if (dta < Deg45) {
|
|
|
+ dta = 0;
|
|
|
+ } else if (dta < Deg135) {
|
|
|
+ dta = Deg90;
|
|
|
+ } else if (dta < Deg225) {
|
|
|
+ dta = Math.PI;
|
|
|
+ } else if (dta < Deg315) {
|
|
|
+ dta = Deg270;
|
|
|
+ } else {
|
|
|
+ dta = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.lastRad = dta;
|
|
|
+ console.log("rotate=>", dta);
|
|
|
+
|
|
|
+ objContainer.rotate(dta);
|
|
|
+
|
|
|
+ // this.emit("translateChange", this.objContainer)
|
|
|
+ this.upgateGizmoStyle();
|
|
|
+ }
|
|
|
+
|
|
|
+ rotateMouseUp(e: MouseEvent) {
|
|
|
+ this.rotateCenter = undefined;
|
|
|
+ if (!this.rotateCmd) return;
|
|
|
+ let scope = this;
|
|
|
+ let last = this.lastRad;
|
|
|
+ let initrad = scope.objinitAngleRad;
|
|
|
+
|
|
|
+ // this.editor.history.record({undo:function(){
|
|
|
+ // scope.objContainer.setPivot(4);
|
|
|
+ // scope.objContainer.rotate( initrad );
|
|
|
+ // scope.emitChange();
|
|
|
+ // }, redo:function(){
|
|
|
+ // scope.objContainer.setPivot(4);
|
|
|
+ // scope.objContainer.rotate( last );
|
|
|
+ // scope.emitChange();
|
|
|
+ // }});
|
|
|
+ this.rotateCmd = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //缩放选中的对象
|
|
|
+ scalePivot?: any;
|
|
|
+ scaleIndex = 0;
|
|
|
+ mainAxisVector = { x: 0, y: 0 };
|
|
|
+ initScale = { x: 1, y: 1 };
|
|
|
+ mainAxisVectorLenth = 0;
|
|
|
+ xAxisVector = { x: 1, y: 1 };
|
|
|
+ xAxisVectorLength = 0;
|
|
|
+ yAxisVector = { x: 1, y: 1 };
|
|
|
+ yAxisVectorLength = 0;
|
|
|
+ scaleCmd = false;
|
|
|
+ lastScale = { x: 1, y: 1 };
|
|
|
+
|
|
|
+ scaleMousemove(event: MouseEvent) {
|
|
|
+ let dirIndexs = [
|
|
|
+ "scaleBottomright",
|
|
|
+ "scaleBottomleft",
|
|
|
+ "scaleTopleft",
|
|
|
+ "scaleTopright",
|
|
|
+ ];
|
|
|
+ let dirOrth = ["scaleright", "scaleleft", "scalebottom", "scaletop"];
|
|
|
+
|
|
|
+ const rect = this.store.currStreamCard.$el.getBoundingClientRect();
|
|
|
+ let StartX = event.clientX - rect.left;
|
|
|
+ let StartY = event.clientY - rect.top;
|
|
|
+ const objContainer = this.objContainer as ObjsContainer;
|
|
|
+
|
|
|
+ //获取当前屏幕坐标和选框中心点坐标,计算旋转值
|
|
|
+ if (!this.scalePivot) {
|
|
|
+ let dir = this._mouseDownFlag;
|
|
|
+ let scaleIndex = dirIndexs.indexOf(dir);
|
|
|
+ if (scaleIndex == -1) {
|
|
|
+ scaleIndex = dirOrth.indexOf(dir);
|
|
|
+ if (scaleIndex == 2) scaleIndex = 0;
|
|
|
+ }
|
|
|
+ let pivot = objContainer.setPivot(scaleIndex);
|
|
|
+
|
|
|
+ this.scaleIndex = scaleIndex;
|
|
|
+ this.scalePivot = pivot;
|
|
|
+
|
|
|
+ this.mainAxisVector = { x: StartX - pivot.x, y: StartY - pivot.y };
|
|
|
+ let scale = objContainer.parent.scale;
|
|
|
+ this.initScale = { x: scale.x, y: scale.y };
|
|
|
+ this.mainAxisVectorLenth = VectorLenth(
|
|
|
+ this.mainAxisVector.x,
|
|
|
+ this.mainAxisVector.y
|
|
|
+ );
|
|
|
+
|
|
|
+ let ret = objContainer.getPivotXY(scaleIndex);
|
|
|
+
|
|
|
+ this.xAxisVector = ret.x;
|
|
|
+ this.xAxisVectorLength = VectorLenth(ret.x.x, ret.x.y);
|
|
|
+ this.yAxisVector = ret.y;
|
|
|
+ this.yAxisVectorLength = VectorLenth(ret.y.x, ret.y.y);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.scaleCmd = true;
|
|
|
+
|
|
|
+ let center = this.scalePivot;
|
|
|
+ let vec = { x: StartX - center.x, y: StartY - center.y };
|
|
|
+
|
|
|
+ if (event.shiftKey) {
|
|
|
+ //按住shift 自由缩放
|
|
|
+ let dtaX = Project(vec, this.xAxisVector) / this.xAxisVectorLength;
|
|
|
+ let dtaY = Project(vec, this.yAxisVector) / this.yAxisVectorLength;
|
|
|
+ this.lastScale.x = dtaX * this.initScale.x;
|
|
|
+ this.lastScale.y = dtaY * this.initScale.y;
|
|
|
+ objContainer.scale(this.lastScale.x, this.lastScale.y);
|
|
|
+ } else {
|
|
|
+ let mainVec = this.mainAxisVector;
|
|
|
+ let dtaScale = Project(vec, mainVec) / this.mainAxisVectorLenth;
|
|
|
+
|
|
|
+ let i = dirOrth.indexOf(this._mouseDownFlag);
|
|
|
+ if (i == -1) {
|
|
|
+ this.lastScale.x = dtaScale * this.initScale.x;
|
|
|
+ this.lastScale.y = dtaScale * this.initScale.y;
|
|
|
+ objContainer.scale(this.lastScale.x, this.lastScale.y);
|
|
|
+ } else if (i == 0 || i == 1) {
|
|
|
+ this.lastScale.x = dtaScale * this.initScale.x;
|
|
|
+ objContainer.scaleX(this.lastScale.x);
|
|
|
+ } else if (i == 2 || i == 3) {
|
|
|
+ this.lastScale.y = dtaScale * this.initScale.y;
|
|
|
+ objContainer.scaleY(this.lastScale.y);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.upgateGizmoStyle();
|
|
|
+ }
|
|
|
+
|
|
|
+ scaleMouseUp(event: MouseEvent) {
|
|
|
+ this.scalePivot = undefined;
|
|
|
+ if (this.scaleCmd) {
|
|
|
+ let preScale = { x: this.initScale.x, y: this.initScale.y };
|
|
|
+ let scaleIndex = this.scaleIndex;
|
|
|
+ let lastScale = { x: this.lastScale.x, y: this.lastScale.y };
|
|
|
+
|
|
|
+ // this.editor.history.record({
|
|
|
+ // undo:()=>{
|
|
|
+ // this.objContainer.setPivot( scaleIndex );
|
|
|
+ // this.objContainer.scale(preScale.x, preScale.y);
|
|
|
+
|
|
|
+ // this.emitChange();
|
|
|
+ // },
|
|
|
+ // redo:()=>{
|
|
|
+ // this.objContainer.setPivot( scaleIndex );
|
|
|
+ // this.objContainer.scale(lastScale.x, lastScale.y);
|
|
|
+
|
|
|
+ // this.emitChange();
|
|
|
+ // }
|
|
|
+ // });
|
|
|
+ this.scaleCmd = false;
|
|
|
+
|
|
|
+ // this.emit("objSizeChanged");
|
|
|
+ // this.editor.draw();
|
|
|
+ }
|
|
|
+ // this.emitTransformed = false;
|
|
|
}
|
|
|
}
|