123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047 |
- import { Effect, ModuleControl } from "queenjs";
- import { reactive } from "vue";
- import { EditorModule } from "../../module";
- import { ObjsContainer } from "./ObjsContainer";
- import { CompObject } from "./compObj";
- import Event from "./event";
- import { Matrix } from "./matrix";
- import { Project, VectorLenth } from "./objects/mathUtils";
- import { Point } from "./objects/point";
- import { indexOf } from "lodash";
- import { AssistCtrl } from "./assistCtrl";
- import { AssistRulerCtrl } from "./assistRulerCtrl";
- import { AssistMagnetCtrl } from "./assistMagnetCtrl";
- /**
- * 页面画布空间进行选择
- */
- const MODE_SEL_RECT = 1;
- const MODE_MOVING = 2;
- const MODE_ROTATE = 3;
- const MODE_SCALE_WIDTH = 4;
- const MODE_SCALE_SCALE = 5;
- const MODE_RULER_LINE = 6;
- const MODE_RULER_DRAG = 7;
- const MODE_NONE = 0;
- export class SelectCtrl extends ModuleControl<EditorModule> {
- transEvent = {
- startX: 0,
- startY: 0,
- offsetX: 0,
- offsetY: 0,
- width: 0,
- height: 0,
- };
- transferStyle = reactive({
- baseCardTop: "0px",
- showGizmo: false,
- editingText: false,
- width: 0,
- height: 0,
- relWidth: 0,
- relHeight: 0,
- matrix: "matrix(1,0,0,1,0,0)",
- matrixInvert: "matrix(1,0,0,1,0,0)",
- showOrthScale: false,
- mode: MODE_NONE,
- });
- selected: any[] = []; //选中的所有组件ids
- pageEl?: HTMLElement;
- selCanvas = {} as HTMLCanvasElement;
- _downed = false;
- _selCtx = {} as CanvasRenderingContext2D;
- _state = MODE_NONE;
- _selDownX = 0;
- _selDownY = 0;
- _selBox = {} as DOMRect;
- _selCanvaseSize = { w: 0, h: 0 };
- _downClientX = 0;
- _downClientY = 0;
- //groupCtrl = new GroupActionCtrl(this.module);
- bus = new Event();
- viewport?: HTMLElement;
- assistCtrl?: AssistCtrl;
- assistRuler?: AssistRulerCtrl;
- assistMagnet?: AssistMagnetCtrl;
- getPageBox() {
- return (this.pageEl as (HTMLElement)).getBoundingClientRect();
- }
-
- getCurrCardBox() {
- return this.store.currStreamCard.$el.getBoundingClientRect();
- }
- getViewPortBox() {
- //@ts-ignore
- return this.viewport.getBoundingClientRect();
- }
-
- getCurrCard() {
- return this.store.currStreamCard;
- }
- getProjectId() {
- return this.store.designData._id;
- }
- getUnSelectChilds() {
- const childs = this.store.currStreamCard.children.default || [];
- let n = childs.length;
- let out = [];
- while(n--) {
- if (this.store.selected.indexOf(childs[n]) == -1) {
- out.push(new CompObject( this.store.compMap[childs[n]]));
- }
- }
- return out;
- }
- 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;
- this._selCtx = selCanvas.getContext("2d") as CanvasRenderingContext2D;
- this._selCanvaseSize.w = selCanvas.width * 2;
- this._selCanvaseSize.h = selCanvas.height * 2;
- this.assistCtrl = new AssistCtrl(this);
- this.assistRuler = new AssistRulerCtrl(this);
- this.assistMagnet = new AssistMagnetCtrl(this);
- viewport.addEventListener("mousedown", this.onDocMouseDown.bind(this));
- window.addEventListener("resize", this.onResize.bind(this));
- this.initEffects();
- }
- initEffects() {
- //相应相应的事件
- Effect.array(() => this.store.selected)
- .list({
- remove: () => {
- console.log("xxx");
- },
- change: (added: string[], removed: string[]) => {
- console.log("changeMap=>", added, removed);
- this._updateSelects();
- },
- })
- .run();
- }
- _mouseDownFlag = "";
- _mouseDownTimestamp = 0;
- _containers: Map<string, ObjsContainer> = new Map();
- _updateSelects() {
- const selecteds = this.store.selected;
- const ObjC = this._containers.get(this.store.selectId);
- let objs = [];
- for (let item of selecteds) {
- objs.push(new CompObject(this.compMap[item]));
- }
- this.selecteObjs(objs, ObjC);
- if (this.store.selectId) {
- this._containers.set(
- this.store.selectId,
- this.objContainer as ObjsContainer
- );
- }
- }
- _downClickedCompId = "";
- onDocMouseDown(e: MouseEvent) {
- this._mouseDownTimestamp = Date.now();
- if (!this.pageEl || !this.selCanvas) return;
-
- document.addEventListener("mousemove", this.onDocMouseMove, {
- capture: true,
- });
- //mouseup和click都会被触发, 监听click事件可以阻止子组件的点击行为
- document.addEventListener("click", this.onDocMouseUp.bind(this), {
- capture: true,
- once: true,
- });
- let box = this.pageEl.getBoundingClientRect();
- const pageX = e.clientX - box?.left;
- const pageY = e.clientY - box?.top;
- const draging = this.assistRuler?.dragTest(e)
- this._state = draging ? MODE_RULER_DRAG : MODE_NONE;
- const sel = this.selCanvas.getBoundingClientRect();
- const selX = e.clientX - sel.left;
- const sely = e.clientY - sel.top;
- this._selDownX = selX;
- this._selDownY = sely;
- this._selBox = sel;
- this._downClientX = e.clientX;
- this._downClientY = e.clientY;
- this._downClickedCompId = this.compClickTest2(e);
- this._downed = true;
- this._mouseDownFlag = this.getDivTransformFlag(e.target as any);
-
- if (!draging) {
- if (!this._mouseDownFlag) {
- //选框点击判断
- let isClickSelRect = false;
- if (this.selected.length > 0) {
- const card = this.store.currStreamCard.$el;
- box = card.getBoundingClientRect();
- const cardX = pageX;
- const cardY = e.clientY - box.top;
- isClickSelRect = this.objContainer?.testClick(cardX, cardY) as boolean;
- if (isClickSelRect) {
- this._state = MODE_MOVING;
- }
- }
- if (!isClickSelRect) {
- //点击在选框之外
-
- if (!this._downClickedCompId) {
- //没有点击到组件
- 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 {//点击到选框之外的组件, 把时间放到mouseup 时相应.
- // 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.indexOf("move") > -1) {
- this._state = MODE_MOVING;
- } else if (this._mouseDownFlag.indexOf("scale") > -1) {
- this._state = MODE_SCALE_WIDTH;
- if (
- this.store.selected.length == 1 &&
- (this.selected[0].comp.compKey == "Text" || this.selected[0].comp.compKey == "Group")
- ) {
- //拖拽的是文本
- const scaleFlags = [
- "scaleBottomright",
- "scaleBottomleft",
- "scaleTopleft",
- "scaleTopright",
- ];
- if (scaleFlags.indexOf(this._mouseDownFlag) > -1) {
- this._state = MODE_SCALE_SCALE;
- }
- }
- } else if (this._mouseDownFlag.indexOf("ruler") > -1) {
- this._state = MODE_RULER_LINE;
- }
- }
- this._movePreClientX = this._downClientX;
- this._movePreClientY = this._downClientY;
- this._initMovePos.x = -1;
- this._initMovePos.y = -1;
- }
- _initMovePos = { x: -1, y: -1 };
- getDivFlag(div: HTMLElement, flag = "editable") {
- let c: any = div;
- if (!c) return "";
- let i = 0;
- do {
- if (c[flag]) return c[flag];
- c = c.parentElement;
- i += 1;
- if (i > 16) {
- return "";
- }
- } while (c);
- return "";
- }
- getDivId(div: HTMLElement) {
- let c: any = div;
- if (!c) return;
- let i = 0;
- do {
- if (c.id) return c.id;
- c = c.parentElement;
- i += 1;
- if (i > 5) {
- return;
- }
- } while (c);
- }
- getDivTransformFlag(div: HTMLElement) {
- const id = this.getDivId(div);
- if (!id) return "";
- if (
- id.indexOf("rotate") > -1 ||
- id.indexOf("move") > -1 ||
- id.indexOf("scale") > -1 ||
- id.indexOf("toolbar") > -1 ||
- id.indexOf("ruler") > -1
- )
- return id;
- return "";
- }
- compClickTest2(e: MouseEvent) {
- const compId = this.getDivFlag(e.target as any, "compId");
- console.log("down click=>", compId);
- return compId;
- }
- 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: any[] = [];
- while (n--) {
- const cardComp = compMap[cards[n]];
- const box = cardComp.$el.getBoundingClientRect();
- const cardY = e.clientY - box.top;
- const cardChilds = cardComp.children.default || [];
- let maxZ = -1;
- let topItem = null;
- 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) {
- let z = c.layout.zIndex || 0;
- if (z > maxZ) {
- maxZ = z;
- topItem = {
- id: key,
- el: c.$el,
- cardX: pageX,
- cardY: cardY,
- cardId: cards[n],
- startMatrix: m,
- };
- }
- }
- }
- if (topItem) {
- Out.push(topItem);
- return Out;
- }
- }
- 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;
- translate(xOffset: number, yOffset: number) {
- const objContainer = this.objContainer as ObjsContainer;
- objContainer.translate(xOffset, yOffset);
- this.upgateGizmoStyle();
- this.helper.extendStreamCard(this.store.currStreamCardId);
- }
- movingMousemove(e: MouseEvent) {
- const objContainer = this.objContainer as ObjsContainer;
- const magnet = this.assistMagnet as AssistMagnetCtrl;
- if (this._initMovePos.x == -1 && this._initMovePos.y == -1) {
- const obj = this.objContainer as ObjsContainer;
- this._initMovePos = { x: obj.parent.x, y: obj.parent.y };
- }
- magnet.test(e);
- objContainer.setPivot(0);
- objContainer.translate(
- magnet.clientX - this._movePreClientX,
- magnet.clientY - this._movePreClientY
- );
- this.upgateGizmoStyle();
- }
- _movePreClientX = 0;
- _movePreClientY = 0;
- onDocMouseMove = (e: MouseEvent) => {
- if (!this.pageEl) return;
- if (this._state) {
- e.preventDefault();
- e.stopPropagation();
- }
- switch (this._state) {
- 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_WIDTH:
- case MODE_SCALE_SCALE:
- this.scaleMousemove(e);
- break
- case MODE_RULER_LINE:
- this.assistRuler?.rulerLineMouseMove(e);
- break;
- case MODE_RULER_DRAG:
- this.assistRuler?.onDragMove(e);
- break;
- }
- this._movePreClientY = e.clientY;
- this._movePreClientX = e.clientX;
- };
- get compMap() {
- return this.store.designData.compMap;
- }
- onDocMouseUp(e: MouseEvent) {
- let isClick = false;
- let offsetT = Date.now() - this._mouseDownTimestamp;
- const dx = Math.abs(e.clientX - this._downClientX);
- const dy = Math.abs(e.clientY - this._downClientY);
- if (dx < 2 && dy < 2 && offsetT < 200) {
- isClick = true;
- }
- document.removeEventListener("mousemove", this.onDocMouseMove, {
- capture: true,
- });
- if (this._mouseDownFlag == "toolbar") {
- return;
- }
- if (isClick) {
- this._state = MODE_NONE;
- if ((!e.shiftKey && !e.ctrlKey) ) {
- this.actions.pickComp(this._downClickedCompId);
- } else {
- const paths = this.helper.getCompTrees(this._downClickedCompId)
- if (paths[2]) {
- this._selectObjs([paths[2].id], e)
- }
- }
- }
- 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],
- e
- );
- }
- if (this._state == MODE_ROTATE) {
- this.rotateMouseUp(e);
- } else if (
- this._state == MODE_SCALE_WIDTH ||
- this._state == MODE_SCALE_SCALE
- ) {
- this.scaleMouseUp(e);
- } else if (this._state == MODE_MOVING) {
- this.moveMouseUp(e, isClick);
- } else if (this._state == MODE_RULER_LINE) {
- this.assistRuler?.rulerLineMouseUp(e, isClick)
- }else if (this._state == MODE_RULER_DRAG) {
- this.assistRuler?.onDragUp(e)
- }
- this._state = MODE_NONE;
- this._downed = false;
- this._moveSelectUpdated = false;
- this.upgateGizmoStyle();
- this.helper.extendStreamCard(this.store.currStreamCardId);
- this.assistRuler?.draw();
- this.assistMagnet?.onMouseUp();
- }
- moveMouseUp(e: MouseEvent, clicked: boolean) {
- const history = this.controls.historyCtrl.history;
- const obj = this.objContainer as ObjsContainer;
- const lastX = obj.parent.x,
- lastY = obj.parent.y;
- const initX = this._initMovePos.x,
- initY = this._initMovePos.y;
- this._initMovePos.x = -1;
- this._initMovePos.y = -1;
- if (initX == -1 && initY == -1) return;
- obj.setPivot(0);
- history.record({
- undo: () => {
- console.log("undo ");
- const currObj = this.objContainer as ObjsContainer;
- currObj.setPivot(0);
- currObj.parent.x = initX;
- currObj.parent.y = initY;
- currObj.parent.updateTransform();
- currObj.updateCompState();
- this.upgateGizmoStyle();
- this.helper.extendStreamCard(this.store.currStreamCardId);
- },
- redo: () => {
- const currObj = this.objContainer as ObjsContainer;
- currObj.setPivot(0);
- currObj.parent.x = lastX;
- currObj.parent.y = lastY;
- currObj.parent.updateTransform();
- currObj.updateCompState();
- this.upgateGizmoStyle();
- this.helper.extendStreamCard(this.store.currStreamCardId);
- },
- } as any);
- history.submit();
- }
- rectSelect(x: number, y: number, width: number, height: number, e:MouseEvent) {
- const childs =
- this.compMap[this.store.currStreamCardId].children.default || [];
- let n = childs.length;
- const outs:string[] = [];
- while (n--) {
- const o = new CompObject(this.compMap[childs[n]]);
- if (o.testRect({ x, y, w: width, h: height }, true)) {
- //相交
- outs.push(o.comp.id);
- }
- }
- this._selectObjs(outs, e);
- }
- _selectObjs( outs:string[], e:MouseEvent) {
- let objs = this.store.selected.slice(0);
- let lastId = outs[outs.length-1];
-
- if (e.ctrlKey) {
- objs.forEach(o=>{
- if (outs.indexOf(o) == -1) {
- outs.push(o);
- }
- })
- }
-
- let selected = outs;
- if (e.shiftKey) {//反选
- selected = [];
- objs.forEach(o=>{
- if (outs.indexOf(o) == -1) selected.push(o);
- })
- lastId = selected[selected.length-1] || "";
- }
- if (lastId) {
- this.actions.pickComp(lastId, false);
- }
- this.actions.selectObjs(selected, lastId);
-
- if (selected.length < 1) {
- this.actions.pickComp(this.store.currStreamCardId);
- }
- }
- upgateGizmoStyle() {
- this.transferStyle.mode = this._state;
- if (this.selected.length < 1) {
- this.transferStyle.showGizmo = false;
- return;
- }
- this.assistCtrl?.flashDrawCardDists();
- this.transferStyle.showGizmo = false;
- //@ts-ignore
- const yoff = this.store.currStreamCard.$el.getBoundingClientRect().top - this.pageEl?.getBoundingClientRect().top;
- this.transferStyle.baseCardTop = yoff + "px";
- 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);
- let matrix = `matrix(${tmp.a},${tmp.b},${tmp.c},${tmp.d},${tmp.tx},${tmp.ty})`;
- tmp.rotate(-tmp.getRotate());
- 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.relWidth = w * obj.scale.x;
- this.transferStyle.relHeight = h * obj.scale.y;
- this.transferStyle.matrix = matrix;
- this.transferStyle.matrixInvert = matrixInvert;
- this.transferStyle.showOrthScale = this.selected.length == 1;
- if (this.selected.length == 1) {
- const comp = this.selected[0].comp
- if (comp.compKey == "Group") {
- this.transferStyle.showOrthScale = false;
- }
- if (comp.layout.locked) {
- this.transferStyle.showGizmo = false;
- }
- if (comp.compKey == "Text") {
- if (!this.helper.isStreamCardChild(comp.id)) {
- this.transferStyle.showGizmo = false;
- }
- }
- }
- }
- selectId(id: string) {
- //选中ids之前 id对应组件必须已经渲染
- console.log("selectId=>", id);
- }
- _lastSelRect = [0, 0, 0, 0];
- drawSelRect(e: MouseEvent) {
- this.assistRuler?.draw();
- 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.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.selCanvas;
- }
- onResize() {
- const b = this.selCanvas.getBoundingClientRect();
- 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;
- }
- //
- checkIntersect(compId: string, e: MouseEvent) {
- const currCard = this.store.currStreamCard.$el;
- const comp = this.store.designData.compMap[compId];
- //排除坐标没有在streamCard空间内的坐标
- //把当前的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)
- }
- 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 (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;
- this.selected = objs;
- 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");
- }
- 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;
- const history = this.controls.historyCtrl.history;
- this.objContainer?.setPivot(0);
- history.record({
- undo: () => {
- const objContainer = this.objContainer as ObjsContainer;
- this.objContainer?.setPivot(4);
- this.objContainer?.rotate(initrad);
- this.objContainer?.setPivot(0);
- this.objContainer?.updateCompState();
- this.upgateGizmoStyle();
- this.helper.extendStreamCard(this.store.currStreamCardId);
- },
- redo: () => {
- console.log("redo ");
- const objContainer = this.objContainer as ObjsContainer;
- this.objContainer?.setPivot(4);
- this.objContainer?.rotate(last);
- this.objContainer?.setPivot(0);
- this.objContainer?.updateCompState();
- this.upgateGizmoStyle();
- this.helper.extendStreamCard(this.store.currStreamCardId);
- },
- } as any);
- history.submit();
- 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 };
- initScaleWith = { w: 0, h: 0 };
- scaleMousemove(event: MouseEvent) {
- let dirIndexs = [
- "scaleBottomright",
- "scaleBottomleft",
- "scaleTopleft",
- "scaleTopright",
- ];
- let dirOrth = ["scaleright", "scaleleft", "scalebottom", "scaletop"];
- const rect = this.store.currStreamCard.$el.getBoundingClientRect();
- const maget = this.assistMagnet as AssistMagnetCtrl;
- maget.test(event);
- let StartX = maget.clientX - rect.left;
- let StartY = maget.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.initScaleWith = { w: objContainer.width, h: objContainer.height };
- 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);
- const currW = this.initScaleWith.w * this.lastScale.x;
- objContainer.scaleSize(currW, this.lastScale.y * this.initScaleWith.h);
- } else {
- let mainVec = this.mainAxisVector;
- let dtaScale = Project(vec, mainVec) / this.mainAxisVectorLenth;
- console.log("dtaScale=>", dtaScale);
- let i = dirOrth.indexOf(this._mouseDownFlag);
- if (i == -1) {
- this.lastScale.x = dtaScale * this.initScale.x;
- this.lastScale.y = dtaScale * this.initScale.y;
- if (this._state == MODE_SCALE_SCALE) {
- objContainer.scale(this.lastScale.x, this.lastScale.y);
- } else {
- objContainer.scaleSize(this.lastScale.x, this.lastScale.y);
- }
- } else if (i == 0 || i == 1) {
- this.lastScale.x = dtaScale * this.initScale.x;
- // objContainer.scaleX(this.lastScale.x);
- objContainer.scaleWidth(this.lastScale.x);
- } else if (i == 2 || i == 3) {
- this.lastScale.y = dtaScale * this.initScale.y;
- // objContainer.scaleY(this.lastScale.y);
- objContainer.scaleHeight(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 };
- const history = this.controls.historyCtrl.history;
- this.objContainer?.setPivot(0);
- const scaleMode = this._state;
- history.record({
- undo: () => {
- console.log("undo ");
- this.objContainer?.setPivot(scaleIndex);
- if (scaleMode == MODE_SCALE_WIDTH) {
- this.objContainer?.scaleSize(preScale.x, preScale.y);
- } else {
- this.objContainer?.scale(preScale.x, preScale.y);
- }
- this.objContainer?.setPivot(0);
- this.objContainer?.updateCompState();
- this.upgateGizmoStyle();
- this.helper.extendStreamCard(this.store.currStreamCardId);
- },
- redo: () => {
- console.log("redo ");
- this.objContainer?.setPivot(scaleIndex);
- if (scaleMode == MODE_SCALE_WIDTH) {
- this.objContainer?.scaleSize(lastScale.x, lastScale.y);
- } else {
- this.objContainer?.scale(lastScale.x, lastScale.y);
- }
- this.objContainer?.setPivot(0);
- this.objContainer?.updateCompState();
- this.upgateGizmoStyle();
- this.helper.extendStreamCard(this.store.currStreamCardId);
- },
- } as any);
- history.submit();
- this.scaleCmd = false;
- }
- }
- }
|