import { cloneDeep, pick } from "lodash"; import { nanoid } from "nanoid"; import { Exception, queenApi } from "queenjs"; import { EditorModule } from ".."; import { ScreenshotCtrl } from "../../controllers/ScreenshotCtrl"; import { ObjsContainer } from "../../controllers/SelectCtrl/ObjsContainer"; import { CompObject } from "../../controllers/SelectCtrl/compObj"; import { Matrix } from "../../controllers/SelectCtrl/matrix"; import { DesignComp } from "../../objects/DesignTemp/DesignComp"; import { ICompKeys, Layout } from "../../typings"; const ctrlState = { selected: [] as string[], type: 0, // 1 ctrlc 2 ctrlx cardId: "", //当前的卡片Id screenId: "", //屏幕Id selWidth: 0, selX: 0, selY: 0, }; export const editActions = EditorModule.action({ pickComp(compId: string, selected = true) { if (compId == "") { //空的时候,就选择根页面 compId = "root"; } const selectCardChild = (id: string) => { const paths = this.helper.getCompTrees(id); const cardChilds = paths[2]; if (cardChilds) { this.actions.selectObjs([cardChilds.id]); } else { this.actions.selectObjs([]); if (id != "root") { this.store.setCurrComp(this.store.currStreamCardId); } } }; if (this.store.currCompId == compId) { return; } this.store.setCurrComp(compId); if (selected) { selectCardChild(compId); } }, // 通过点击添加组件到画布 async clickCompToDesign(compKey: ICompKeys, cb?: (comp: DesignComp) => void) { if (!this.store.currStreamCardId) { queenApi.messageError("请先选中一个卡片"); return; } //点击默认都创建一个容器 //创建容器 const isCreatCard = compKey != "Text" && compKey != "Image" && compKey != "Rectage" && compKey != "Line" && compKey != "Arc" && compKey != "Triangle" && compKey != "Ellipse" && compKey != "Polygon" && compKey != "PolygonNormal" && compKey != "Curve"; let yOffset = 0; if ( this.store.currCompId != this.store.currStreamCardId && !isCreatCard && this.store.currCompId != "root" ) { const bound = this.helper.getCardCompBound(this.store.currCompId); yOffset = bound.y + bound.h; } let currCard = this.store.currStreamCard; if (isCreatCard) { //先创建卡片 const currCardIndex = this.store.streamCardIds.indexOf(this.store.currStreamCardId) + 1; const compId = await this.store.insertDesignContent( "Container", currCardIndex ); currCard = this.helper.findComp(compId) as DesignComp; currCard.layout.size[0] = this.controls.screenCtrl.getCurrScreenWidth(); } const compId = await this.store.insertCompContainer(compKey, currCard); const addedComp = this.store.compMap[compId]; addedComp.layout.position = "absolute"; const currComp = this.helper.findComp(compId) as DesignComp; cb?.(currComp); const w = this.controls.screenCtrl.getCurrScreenWidth(); //添加组件到当前选中的组件下面 let xOffset = this.helper.designSizeToPx( w / 2.0 - (currComp.layout.size?.[0] || w) / 2 ); const obj = new CompObject(currComp); //没有选中组件添加到当前卡片最后 const children = currCard.children.default || []; if (yOffset == 0 && children.length >= 2) { const prevCompIndex = children.indexOf(compId) - 1; const bound = this.helper.getCardCompBound(children[prevCompIndex]); yOffset = bound.y + bound.h; } obj.worldTransform.translate(xOffset, yOffset); currComp.layout.transformMatrix = obj.worldTransform.getMatrixStr(); this.actions.pickComp(compId); this.helper.extendStreamCard(currCard.id); if (compKey == "Text") { this.actions.textFocus(compId, true); } this.controls.cropCtrl.close(); }, // 通过点击添加组件到画布 async clickCompUserToDesign(id: string, isSys) { if (!this.store.currStreamCardId) { queenApi.messageError("请先选中一个卡片"); return; } const { result } = await this.https.getCompDetail(id, isSys); //先创建卡片 // const currCardIndex = this.store.streamCardIds.indexOf(this.store.currStreamCardId) + 1; // const cardId = await this.store.insertDesignContent( // "Container", // currCardIndex // ); // const currCard = this.helper.findComp(cardId) as DesignComp; const currCard = this.store.currStreamCard; const comp = this.store.addUserCard(result); const compId = comp.id; const childIds = [...(currCard.children.default || [])]; childIds.push(compId); currCard.children.default = childIds; this.store.setCompPid(compId, currCard.id); const addedComp = this.store.compMap[compId]; addedComp.layout.position = "absolute"; this.actions.initAddedCompPos(this.store.currCompId, compId, currCard.id); this.actions.pickComp(compId); }, initAddedCompPos(currId: string, addedId: string, cardId: string) { let yOffset = 0; if (currId != this.store.currStreamCardId && currId != "root") { const paths = this.helper.getCompTrees(currId); const bound = this.helper.getCardCompBound(paths[2].id); yOffset = bound.y + bound.h; } const currComp = this.helper.findComp(addedId) as DesignComp; const w = this.controls.screenCtrl.getCurrScreenWidth(); //添加组件到当前选中的组件下面 let xOffset = this.helper.designSizeToPx( w / 2.0 - (currComp.layout.size?.[0] || w) / 2 ); const obj = new CompObject(currComp); const currCard = this.helper.findComp(cardId) as DesignComp; //没有选中组件添加到当前卡片最后 const children = currCard.children.default || []; if (yOffset == 0 && children.length >= 2) { const prevCompIndex = children.indexOf(addedId) - 1; const bound = this.helper.getCardCompBound(children[prevCompIndex]); yOffset = bound.y + bound.h; } obj.worldTransform.translate(xOffset, yOffset); currComp.layout.transformMatrix = obj.worldTransform.getMatrixStr(); this.helper.extendStreamCard(currCard.id); this.controls.cropCtrl.close(); }, // 通过拖拽添加组件到画布 async dragCompToDesign(event: MouseEvent, compKey: string, data: any) { const currCardDom = this.store.currStreamCard.$el; if (compKey == "CompCard") { const { result } = await this.https.getCompDetail(data.id, data.isSys); const comp = this.store.addUserCard(result); const currCard = this.store.currStreamCard; const compId = comp.id; const childIds = [...(currCard.children.default || [])]; childIds.push(compId); currCard.children.default = childIds; const addedComp = this.store.compMap[compId]; addedComp.layout.position = "absolute"; this.store.setCompPid(compId, currCard.id); this.actions.pickComp(compId); } else { await this.actions.addCompToDesign(compKey as any); } setTimeout(() => { const cardPoints = this.helper.getPointOffsetWith(event, currCardDom); const { currComp } = this.store; let selCtrl = this.controls.selectCtrl; const w = this.controls.screenCtrl.getCurrScreenWidth(); selCtrl.translate( this.helper.designSizeToPx( w / 2.0 - (currComp.layout.size?.[0] || w) / 2 ), cardPoints.y ); this.helper.extendStreamCard(this.store.currStreamCardId); if (compKey == "Text") { this.actions.selectObjs([]); this.actions.textFocus(currComp.id, true); } this.controls.cropCtrl.close(); }, 100); }, async selectObjs(ids: string[], last = "") { this.store.selected = ids; this.store.selectId = ids.length > 1 ? Date.now() + "" : ""; this.store.lastSelected = last ? last : ids.length > 0 ? ids[ids.length - 1] : ""; }, // 添加组件到画布 async addCompToDesign(compKey: ICompKeys, index?: number) { if (!this.store.currStreamCardId) { //必须选中一个streamCard return; } if (compKey == "Container") { // index = this.store.streamCardIds.indexOf(this.store.currStreamCardId) + 1; const compId = await this.store.insertDesignContent(compKey, index); this.actions.pickComp(compId); const c = this.helper.findComp(compId) as DesignComp; c.layout.size[0] = this.controls.screenCtrl.getCurrScreenWidth(); c.layout.size[1] = this.controls.screenCtrl.getCurrScreenHeight(); this.helper.extendStreamCard(compId); this.actions.selectObjs([]); return; } const compId = await this.store.insertCompContainer( compKey, this.store.currStreamCard ); const addedComp = this.store.compMap[compId]; this.actions.setCompPositionFloat(addedComp); this.actions.pickComp(compId); }, // 切换当前组件 // pickComp(compId: string) { // const { store, helper } = this; // // 组合模式下,切换组件 // // if (store.currCompId && store.groupModeStatus) { // // const enableGroupIds = helper // // .findParentComp(compId) // // ?.getChildIds() as string[]; // // const comps = helper.getCompTrees(compId); // // while (comps.length) { // // const comp = comps.pop() as DesignComp; // // const index = store.groupIds.indexOf(comp.id); // // if (index >= 0) { // // const groupIds = [...store.groupIds]; // // groupIds.splice(index, 1); // // store.setGroupIds(groupIds); // // } else if (enableGroupIds.includes(comp.id)) { // // store.groupIds.push(comp.id); // // return; // // } // // } // // return; // // } // // let nextCompId = compId; // // if (this.store.isEditPage) { // // const comps = this.helper.getCompTrees(compId); // // nextCompId = comps[1].id; // // } // if (this.store.currCompId == compId) { // return; // } // if (this.store.currComp.compKey == "Text") { // this.store.setTextEditingState(false); // } // this.store.setCurrComp(compId); // if (this.store.currCompId == this.store.currStreamCardId) { // this.controls.transferCtrl.destroy(); // } // }, // 切换到父组件 pickParentComp(compId: string) { const parentComp = this.helper.findParentComp(compId); parentComp && this.store.setCurrComp(parentComp.id); }, ctrlc() { ctrlState.selected = []; const children = this.store.currStreamCard.children.default || []; children.forEach((c) => { if (this.store.selected.indexOf(c) > -1) { ctrlState.selected.push(c); } }); ctrlState.screenId = this.controls.screenCtrl.currScreenId; ctrlState.cardId = this.store.currStreamCardId; ctrlState.type = 1; const objc = this.controls.selectCtrl.objContainer as ObjsContainer; ctrlState.selWidth = this.helper.pxToDesignSize(objc.width); objc.setPivot(0); const currX = objc.parent.x, currY = objc.parent.y; ctrlState.selX = currX; ctrlState.selY = currY; objc.setPivot(4); }, copyLastSelected() { if (this.store.currCompId && this.store.currCompId != "root") { ctrlState.selected = [this.store.currCompId]; ctrlState.cardId = this.store.currStreamCardId; ctrlState.type = 1; } }, setSameSize(isWidth: boolean) { const selectCtrl = this.controls.selectCtrl; const objc = selectCtrl.objContainer as ObjsContainer; const w = this.controls.screenCtrl.getCurrScreenWidth(); if (this.store.selected.length == 1) { if (isWidth) this.store.currComp.layout.size[0] = w; else this.store.currComp.layout.size[1] = this.store.currStreamCard.layout.size[1]; objc.updateSize(); selectCtrl.upgateGizmoStyle(); return; } const anchorBox = this.helper.findComp(this.store.lastSelected); if (!anchorBox) return; objc.parent.children.forEach((c) => { const child = c as CompObject; const r = child.getBox(); if (isWidth) child.comp.layout.size[0] = anchorBox.layout.size[0]; else child.comp.layout.size[1] = anchorBox.layout.size[1]; }); objc.updateSize(); selectCtrl.upgateGizmoStyle(); }, toogleGroup() { if (this.store.selected.length > 1) { this.actions.createGroupComps(); return; } if (this.store.selected.length == 1) { const c = this.helper.findComp(this.store.selected[0]) as DesignComp; if (c.compKey == "Group") { this.actions.cancelGroupComps(c); } } }, ctrlx() { //console.log("ctrlv ", this.store.selected); //console.log("ctrlv ", this.store.selected); //保持图层顺序 ctrlState.selected = []; const children = this.store.currStreamCard.children.default || []; children.forEach((c) => { if (this.store.selected.indexOf(c) > -1) { ctrlState.selected.push(c); } }); ctrlState.cardId = this.store.currStreamCardId; ctrlState.type = 2; ctrlState.screenId = this.controls.screenCtrl.currScreenId; const objc = this.controls.selectCtrl.objContainer as ObjsContainer; ctrlState.selWidth = this.helper.pxToDesignSize(objc.width); objc.setPivot(0); const currX = objc.parent.x, currY = objc.parent.y; ctrlState.selX = currX; ctrlState.selY = currY; objc.setPivot(4); }, ctrlv() { if (ctrlState.selected.length < 1) return; const news: string[] = []; const deepCopy = (c: DesignComp) => { const childs = c.children.default || []; if (childs.length > 0) { childs.forEach((id, index) => { const cp = this.helper.findComp(id) as DesignComp; const cp1 = cloneDeep(cp); cp1.id = nanoid(); this.store.compMap[cp1.id] = cp1; this.store.setCompPid(cp1.id, c.id); childs[index] = cp1.id; deepCopy(cp); }); } }; ctrlState.selected.forEach((c) => { const cp = this.helper.findComp(c) as DesignComp; const cp1 = cloneDeep(cp); cp1.id = nanoid(); news.push(cp1.id); this.store.compMap[cp1.id] = cp1; this.store.setCompPid(cp1.id, this.store.currStreamCardId); deepCopy(cp); }); this.actions.addComps(news); this.actions.selectObjs(news); setTimeout(() => { if (ctrlState.type == 2) { //剪辑删除原来的组件 const card = this.helper.findComp(ctrlState.cardId) as DesignComp; const childs = card.children.default?.slice(0) || []; ctrlState.selected.forEach((s) => { let i = childs.indexOf(s); if (i != -1) { childs.splice(i, 1); } }); card.children.default = childs; this.helper.extendStreamCard(ctrlState.cardId); ctrlState.selected = []; } //获取当前选中的内容 if (ctrlState.cardId != this.store.currStreamCardId) { //跨卡片拷贝 let pox = this.helper.getCardNextPosY( this.store.currStreamCardId, ctrlState.selWidth ); this.controls.selectCtrl.translate(0, pox.y - ctrlState.selY); return; } if (ctrlState.screenId == this.controls.screenCtrl.currScreenId) { this.controls.selectCtrl.translate(20, 20); } }, 100); }, addComps(ids: string[]) { const childs = this.store.currStreamCard.children.default?.slice(0) || []; childs.push(...ids); this.store.currStreamCard.children.default = childs; }, ctrlAndA() { const childrens = (this.store.currStreamCard.children.default || []).slice( 0 ); this.actions.selectObjs(childrens); // this.controls.selectCtrl. //objc.updateSize(); //selectCtrl.upgateGizmoStyle(); }, // 删除组件 removeSelectComps() { const selected = this.store.selected.slice(0); this.actions.selectObjs([]); let n = selected.length; while (n--) { this.actions.removeComp(selected[n]); } }, // 删除组件 removeComp(compId: string) { const paths = this.helper.getCompTrees(compId); if (!paths[2]) { if (this.helper.isStreamCard(compId)) { this.actions.removeStreamCard(compId); return; } return; } compId = paths[2].id; if (this.helper.isCompCanDelete(compId)) { if (this.helper.isStreamCard(compId)) { this.actions.removeStreamCard(compId); return; } const cardid = this.store.currStreamCardId; if (compId === this.store.currCompId) { this.store.setCurrComp(this.store.currStreamCardId); } this.store.deleteComp(compId); this.helper.extendStreamCard(cardid); this.actions.selectObjs([]); } }, async removeStreamCard(compId: string) { await queenApi.showConfirm({ title: "删除", content: "确认删除当前页面?" }); // if (this.store.streamCardIds.length < 2) { // queenApi.messageError("") // return; // } let nextCard = this.store.currStreamCardId; if (compId == this.store.currStreamCardId) { const i = this.store.streamCardIds.indexOf(compId); nextCard = this.store.streamCardIds[i + 1]; if (!nextCard) { nextCard = this.store.streamCardIds[i - 1]; } } this.controls.selectCtrl.selecteObjs([]); this.store.setCurrComp(nextCard); this.store.deleteComp(compId); }, // 移动组件顺序 moveComp(selIndex: number, targetIndex: number) { this.actions.selectObjs([]); if (selIndex === targetIndex) return; this.store.moveComp(selIndex, targetIndex); }, // 保存容器为组件 async saveAsComp(comp: DesignComp) { try { const CompSave = this.components.CompSave as any; let title = ""; let type = "comp"; try { const ret: any = await queenApi.dialog(, { width: "300px", title: "保存到我的", }); if (!ret) { return; } title = ret.title; type = ret.type; } catch (error) { return; } console.log(title, type); // 组件封面 const blob = await new ScreenshotCtrl().snap({ element: comp.$el, }); const thumbnail = URL.createObjectURL(blob); // const title = await queenApi.showInput({ // title: "保存到我的", // defaultValue: this.controls.compUICtrl.state.components.get( // comp.compKey // )?.name, // }); const data = { title, type, thumbnail, compMap: cloneDeep(this.store.designData.compMap), }; this.helper.clearUnusedComps(data.compMap, comp.id); data.compMap.root = data.compMap[comp.id]; data.compMap.root.id = "root"; //清除平移距离 const mtx = Matrix.createFromMatrixStr( data.compMap.root.layout.transformMatrix as string ); mtx.tx = 0; mtx.ty = 0; data.compMap.root.layout.transformMatrix = mtx.getMatrixStr(); delete data.compMap[comp.id]; queenApi.showLoading("保存中"); await this.controls.uploader.uploadBlobs(data); await this.https.createComp(data); queenApi.messageSuccess("保存成功"); } catch (error: any) { throw Exception.error(error.toString()); } finally { queenApi.hideLoading(); } }, // 保存项目 async saveDesign() { try { // 清除无用组件 this.helper.clearProjectUnusedComps(this.store.designData.compMap); const c = this.controls.screenCtrl; c.saveScreenPage(); const root = this.helper.findRootComp() as DesignComp; root.value.useFor = c.state.screen.useFor; root.value.pageMode = c.state.screen.pageMode; root.value.pageSizeType = c.state.screen.pageSizeType; // 封面截屏 if (!this.store.designData.thumbnail) { await this.actions.updateThumbnailByScreenshot(); } queenApi.showLoading("保存中"); await this.controls.uploader.uploadBlobs(this.store.designData); if (this.store.isWk) { await this.https[this.store.isEditPage ? "saveWkDesign" : "saveComp"]( this.store.designData ); } else { await this.https[this.store.isEditPage ? "saveDesign" : "saveComp"]( this.store.designData ); } queenApi.messageSuccess("保存成功"); } catch (error: any) { throw Exception.error(error.toString()); } finally { queenApi.hideLoading(); } }, // 截屏保存封面 async updateThumbnailByScreenshot(autoSave?: boolean) { try { const rootComp = this.helper.findRootComp(); if (!rootComp) return; queenApi.showLoading("截屏中"); const blob = await new ScreenshotCtrl().snap({ element: rootComp.$el, ratio: this.store.isEditComp ? 0 : 1, }); const thumbnail = URL.createObjectURL(blob); this.store.setDesignThumbnail(thumbnail); if (autoSave) { await this.controls.uploader.uploadBlobs(this.store.designData); await this.https[this.store.isEditPage ? "saveDesign" : "saveComp"]( pick(this.store.designData, ["_id", "thumbnail"]) ); queenApi.messageSuccess("保存成功"); } } catch (error: any) { throw Exception.error(error.toString()); } finally { queenApi.hideLoading(); } }, // 设置组件变换 setCompTransform(comp: DesignComp, transform: Layout["transform"]) { if (!comp) return; comp.layout.transform = transform; console.log(comp); }, // 设置组件变换 setCompTransformMatrix(comp: DesignComp, transformMatrix: string) { if (!comp) return; comp.layout.transformMatrix = transformMatrix; }, // 设置组件浮动 setCompPositionFloat(comp: DesignComp) { comp.layout.position = "absolute"; }, // 设置组件浮动 setCompPosition(comp: DesignComp) { comp.layout.position = comp.layout.position === "absolute" ? undefined : "absolute"; }, // 设置组件显示隐藏 setCompVisible(comp: DesignComp) { comp.layout.visible = comp.layout.visible === false ? true : false; }, // 组件重命名 async resetCompName(comp: DesignComp) { const res = await queenApi.showInput({ title: "重命名", defaultValue: comp.title, }); if (!res) return; comp.title = res; }, // 清除组件变换 clearCompTransform(comp: DesignComp) { comp.layout.margin = ""; comp.layout.transform = undefined; }, // 设置组件锁定状态 setCompLock(comp: DesignComp) { comp.layout.locked = !comp.layout.locked; }, // 设置组件层级 setCompLayer(comp: DesignComp, offset: number) { const cards = this.store.currStreamCard.children.default || []; const i = cards.indexOf(comp.id); if (i == -1) return; if (offset < 0) { //向下移动 if (i == 0) return; const temp = cards[i - 1]; cards[i - 1] = comp.id; cards[i] = temp; return; } if (i == cards.length - 1) return; const temp = cards[i + 1]; cards[i + 1] = comp.id; cards[i] = temp; // comp.layout.zIndex = Math.min( // Math.max((comp.layout.zIndex || 0) + offset, 0), // 99 // ); }, //横向对齐 setAlignX(flag: 0 | 1 | 2 | 3, isGroup = false) { console.log("alignX"); const selectCtrl = this.controls.selectCtrl; const w = this.helper.designSizeToPx( this.controls.screenCtrl.getCurrScreenWidth() ); if (this.store.selected.length == 1 || isGroup) { const objc = selectCtrl.objContainer as ObjsContainer; const box = objc.getBound(); switch (flag) { case 0: selectCtrl.translate(-box.left, 0); break; case 1: selectCtrl.translate(-(box.center.x - w / 2.0), 0); break; case 2: selectCtrl.translate(w - box.right, 0); break; } return; } //多选元素对齐模式 const anchorBox = this.helper.findComp(this.store.lastSelected); if (!anchorBox) return; const anchor = new CompObject(anchorBox); const anchorRect = anchor.getBox(); const objc = selectCtrl.objContainer as ObjsContainer; let min = 10000, max = -10000; let step = 0; if (flag == 3) { //Y轴均匀排布 objc.parent.children.forEach((c) => { const child = c as CompObject; const r = child.getBox(); const x = r.x + r.w / 2.0; if (x < min) min = x; if (x > max) max = x; }); const stepCount = objc.parent.children.length; step = (max - min) / (stepCount - 1); const stepIndexMap: any = {}; objc.parent.children.forEach((c) => { const child = c as CompObject; const r = child.getBox(); const x = r.x + r.w / 2.0; let minIndex = -1; let minV = 10000; for (let i = 0; i < stepCount; i++) { const ty = i * step + min; if (Math.abs(x - ty) < minV && !stepIndexMap[i]) { minV = Math.abs(x - ty); minIndex = i; } } stepIndexMap[minIndex] = true; child.translate(minIndex * step + min - x, 0); }); objc.updateSize(); selectCtrl.upgateGizmoStyle(); return; } objc.parent.children.forEach((c) => { const child = c as CompObject; if (child.comp.id == this.store.lastSelected) return; const r = child.getBox(); switch (flag) { case 0: child.translate(anchorRect.x - r.x, 0); break; case 1: child.translate( anchorRect.x + anchorRect.w / 2.0 - (r.x + r.w / 2.0), 0 ); break; case 2: child.translate(anchorRect.x + anchorRect.w - (r.x + r.w), 0); break; } }); objc.updateSize(); selectCtrl.upgateGizmoStyle(); }, setAlignY(flag: 0 | 1 | 2 | 3, isGroup = false) { const selectCtrl = this.controls.selectCtrl; if (this.store.selected.length == 1 || isGroup) { const objc = selectCtrl.objContainer as ObjsContainer; const box = objc.getBound(); const card = new CompObject(this.store.currStreamCard); const cardBox = card.getBox(); switch (flag) { case 0: selectCtrl.translate(0, -box.top); break; case 1: selectCtrl.translate(0, -(box.center.y - cardBox.h / 2.0)); break; case 2: selectCtrl.translate(0, cardBox.h - box.bottom); break; } return; } const anchorBox = this.helper.findComp(this.store.lastSelected); if (!anchorBox) return; const anchor = new CompObject(anchorBox); const anchorRect = anchor.getBox(); const objc = selectCtrl.objContainer as ObjsContainer; let min = 10000; let max = -10000; let step = 0; if (flag == 3) { //Y轴均匀排布 objc.parent.children.forEach((c) => { const child = c as CompObject; const r = child.getBox(); const y = r.y + r.h / 2.0; if (y < min) min = y; if (y > max) max = y; }); const stepCount = objc.parent.children.length; step = (max - min) / (stepCount - 1); const stepIndexMap: any = {}; objc.parent.children.forEach((c) => { const child = c as CompObject; const r = child.getBox(); const y = r.y + r.h / 2.0; let minIndex = -1; let minV = 10000; for (let i = 0; i < stepCount; i++) { const ty = i * step + min; if (Math.abs(y - ty) < minV && !stepIndexMap[i]) { minV = Math.abs(y - ty); minIndex = i; } } stepIndexMap[minIndex] = true; child.translate(0, minIndex * step + min - y); }); objc.updateSize(); selectCtrl.upgateGizmoStyle(); return; } objc.parent.children.forEach((c) => { const child = c as CompObject; if (child.comp.id == this.store.lastSelected) return; const r = child.getBox(); switch (flag) { case 0: child.translate(0, anchorRect.y - r.y); break; case 1: child.translate( 0, anchorRect.y + anchorRect.h / 2.0 - (r.y + r.h / 2.0) ); break; case 2: child.translate(0, anchorRect.y + anchorRect.h - (r.y + r.h)); break; } }); objc.updateSize(); selectCtrl.upgateGizmoStyle(); }, // 宽度铺满 fullCompWidth(comp: DesignComp) { comp.layout.size[0] = this.controls.screenCtrl.getCurrScreenWidth(); }, // setCompAlign(comp: DesignComp, align: string) { comp.layout.alignSelf = align; if (comp.layout.transform?.x) { comp.layout.transform.x = 0; } }, // 开启组合模式 enableGroupMode() { this.store.setGroupIds( this.store.currCompId ? [this.store.currCompId] : [] ); this.store.setGroupMode(true); }, // 关闭组合模式 async disableGroupMode() { const groupId = await this.controls.transferCtrl.groupCtrl.combineGroup(); if (groupId) { this.store.setCurrComp(groupId); } this.store.setGroupIds([]); this.store.setGroupMode(false); }, // 取消打组 cancelGroupComps(groupComp: DesignComp) { const childs = groupComp.children.default || []; const objC = this.controls.selectCtrl.objContainer as ObjsContainer; const parentMtrx = objC.parent.worldTransform.clone(); childs.forEach((o) => { const obj = this.helper.findComp(o) as DesignComp; const mxt = Matrix.createFromMatrixStr( obj.layout.transformMatrix as string ); mxt.prepend(parentMtrx); obj.layout.transformMatrix = mxt.getMatrixStr(); }); const paths = this.helper.getCompTrees(groupComp.id); const card = paths[1]; const parentChilds = (card.children.default || []).filter( (item) => item != groupComp.id ); parentChilds.push(...childs); card.children.default = parentChilds; this.actions.selectObjs([childs[0]]); }, createGroupComps() { const selectCtrl = this.controls.selectCtrl; const Objc = this.controls.selectCtrl.objContainer as ObjsContainer; const id = this.controls.compUICtrl.createCompId("Group"); const comp = this.helper.findComp(id) as DesignComp; comp.layout.position = "absolute"; //先删除现有的节点 const sels = this.store.selected.slice(0); const chils = this.store.currStreamCard.children.default || []; const newChilds: any = []; const groupChilds: any = []; chils.forEach((c) => { if (sels.indexOf(c) == -1) newChilds.push(c); else { groupChilds.push(c); } }); newChilds.push(id); this.store.currStreamCard.children.default = newChilds; //更新节点的新位置 Objc.parent.children.forEach((obj) => { const cobj = obj as CompObject; const comp = cobj.comp; comp.layout.transformMatrix = cobj.localTransform.getMatrixStr(); }); //再添加新的节点 comp.layout.size = [ this.helper.pxToDesignSize(Objc.width), this.helper.pxToDesignSize(Objc.height), ]; comp.layout.transformMatrix = selectCtrl.transferStyle.matrix; comp.children.default = groupChilds; this.actions.selectObjs([]); setTimeout(() => { this.actions.pickComp(comp.id); }, 0); }, handleSelectMoving(key: string) { if (this.store.selected.length < 1) return; let x = 0, y = 0; switch (key) { case "left": x = -1; break; case "right": x = 1; break; case "up": y = -1; break; case "down": y = 1; break; } this.controls.selectCtrl.translate(x * 0.5, y * 0.5); this.controls.selectCtrl.assistCtrl?.flashDrawCardDists(); }, // 点击模板 async clickTplToDesign(record) { const res = await queenApi.showConfirm({ title: "", content: "要替换正在编辑的内容?", }); if (!res) return; const frameData = await this.https.getDesignDetail(record._id, { isSys: true, }); const { compMap, content, desc, thumbnail, title } = frameData.result; const designData = { ...this.store.designData, compMap, content, desc, thumbnail, title, }; this.actions.selectObjs([]); this.store.setCurrComp("root"); this.store.setDesignData(designData); this.store.currStreamCardId = this.store.streamCardIds[0]; }, });