lianghongjie 1 year ago
parent
commit
35ba67f9f0

+ 3 - 3
src/modules/editor/components/CompUI/basicUI/Container/index.ts

@@ -15,9 +15,9 @@ export const { createComp, useCompData } = createCompHooks({
   },
   layout: {
     size: [750, 700],
-    background: {
-      color: "#ffffff",
-    },
+    // background: {
+    //   color: "#ffffff",
+    // },
   },
 });
 

+ 11 - 7
src/modules/editor/components/CompUI/basicUI/Image2/component.tsx

@@ -14,13 +14,17 @@ export const Component = defineComponent({
     const { store, controls, helper } = useEditor();
 
     async function changeVal() {
-      const url = await controls.pickCtrl.pickOneImage();
-      if (!url) return;
+      try {
+        const url = await controls.pickCtrl.pickOneImage();
+        if (!url) return;
 
-      comp.value.url = url;
-      comp.value.x = 0;
-      comp.value.y = 0;
-      comp.value.s = 1;
+        comp.value.url = url;
+        comp.value.x = 0;
+        comp.value.y = 0;
+        comp.value.s = 1;
+      } catch (error) {
+        console.log(error);
+      }
     }
 
     return () => {
@@ -51,7 +55,7 @@ export const Component = defineComponent({
                 ? value.url
                 : value.url + "?editMode=" + store.isEditMode
             }
-            onLoad={(e) => {
+            onLoad={() => {
               if (helper.isCurrComp(props.compId)) {
                 controls.transferCtrl.initStyle();
               }

+ 3 - 0
src/modules/editor/components/CompUI/basicUI/Image2/index.ts

@@ -11,6 +11,9 @@ export const options = {
 
 export const { createComp, useCompData } = createCompHooks({
   value: { url: Dict_Imgs.Default, x: 0, y: 0, s: 1 },
+  layout: {
+    size: [400, 400],
+  },
 });
 
 export const Form = createAttrsForm([

+ 17 - 5
src/modules/editor/components/CompUI/basicUI/Video/component.tsx

@@ -1,4 +1,4 @@
-import { defineComponent } from "vue";
+import { defineComponent, watch } from "vue";
 import { string } from "vue-types";
 import { useCompData } from ".";
 import { View } from "../View";
@@ -12,14 +12,26 @@ export const Component = defineComponent({
   },
   setup(props) {
     const { store, controls } = useEditor();
-    const { value } = useCompData(props.compId);
+    const comp = useCompData(props.compId);
+    const { value } = comp;
 
     async function changeVal() {
-      const url = await controls.pickCtrl.pickOneImage();
-      if (!url) return;
-      value.url = url;
+      try {
+        const url = await controls.pickCtrl.pickOneImage();
+        if (!url) return;
+        value.url = url;
+      } catch (error) {
+        console.log(error);
+      }
     }
 
+    watch(
+      () => [value.ratio],
+      () => {
+        comp.setH(comp.getW() / value.ratio);
+      }
+    );
+
     return () => {
       const options: any = {};
       if (value.autoplay) options.autoplay = true;

+ 3 - 0
src/modules/editor/components/CompUI/basicUI/Video/index.ts

@@ -16,6 +16,9 @@ export const { createComp, useCompData } = createCompHooks({
     loop: true,
     controls: true,
   },
+  layout: {
+    size: [750, 750],
+  },
 });
 
 export const Form = createAttrsForm([

+ 13 - 10
src/modules/editor/components/CompUI/basicUI/Web3D/component.tsx

@@ -1,8 +1,8 @@
 import { Icon3D } from "@/assets/icons";
 import { useEditor } from "@/modules/editor";
 import { css } from "@linaria/core";
-import { queenApi, useModal } from "queenjs";
-import { defineComponent, reactive } from "vue";
+import { Effect, queenApi, useModal } from "queenjs";
+import { defineComponent, reactive, watch, watchEffect } from "vue";
 import { string } from "vue-types";
 import { useCompData } from ".";
 import { View } from "../View";
@@ -15,7 +15,8 @@ export const Component = defineComponent({
   },
   setup(props) {
     const { store } = useEditor();
-    const { value } = useCompData(props.compId);
+    const comp = useCompData(props.compId);
+    const { value } = comp;
 
     async function pickPack() {
       // await controls.pickCtrl.onPickPack();
@@ -38,6 +39,13 @@ export const Component = defineComponent({
       show3d: false,
     });
 
+    watch(
+      () => [value.ratio],
+      () => {
+        comp.setH(comp.getW() / value.ratio);
+      }
+    );
+
     return () => {
       return (
         <View
@@ -45,16 +53,11 @@ export const Component = defineComponent({
           onDblclick={store.isEditMode ? pickPack : undefined}
         >
           {state.show3d ? (
-            <iframe
-              class="w-full border-none"
-              src={value.url}
-              style={{ aspectRatio: value.ratio }}
-            />
+            <iframe class="w-full border-none" src={value.url} />
           ) : (
             <>
               <Image
-                class="w-full pointer-events-none"
-                style={{ aspectRatio: value.ratio }}
+                class="w-full h-full pointer-events-none object-cover"
                 size={480}
                 src={value.poster}
               />

+ 3 - 0
src/modules/editor/components/CompUI/basicUI/Web3D/index.ts

@@ -17,6 +17,9 @@ export const { createComp, useCompData } = createCompHooks({
     poster: Dict_Imgs.Default,
     ratio: 1,
   },
+  layout: {
+    size: [750, 750]
+  }
 });
 
 export const Form = createAttrsForm([

+ 1 - 2
src/modules/editor/components/CompUI/defines/createCompHooks.ts

@@ -30,10 +30,9 @@ export function createCompHooks<T, C extends { [name: string]: AnyFun }>(
   function useCompData(compId: string) {
     const editor = useEditor();
     const comp = editor.store.designData.compMap[compId];
-    return comp as {
+    return comp as DesignComp & {
       value: T;
       children: { [name in keyof C]: ReturnType<C[name]> };
-      layout: Layout;
     };
   }
 

+ 1 - 1
src/modules/editor/components/Viewport/Slider/SliderLeft/index.tsx

@@ -57,7 +57,7 @@ export default defineUI({
                   <div
                     class="draggable-item p-4px text-center"
                     onClick={() =>
-                      editor.actions.addCompToDesign(item.compKey as ICompKeys)
+                      editor.actions.clickCompToDesign(item.compKey as ICompKeys)
                     }
                   >
                     <img

+ 2 - 2
src/modules/editor/components/Viewport/Toolbar/index.tsx

@@ -9,7 +9,7 @@ export default defineUI({
     const { history } = controls.historyCtrl;
     return () => (
       <>
-        <div class="absolute top-20px left-20px space-x-10px">
+        <div class="absolute top-20px left-20px space-x-10px z-10">
           <TipIcons.Undo
             disable={!history.state.canUndo}
             class={btnCls}
@@ -21,7 +21,7 @@ export default defineUI({
             onClick={() => history.redo()}
           />
         </div>
-        <div class="absolute top-20px right-20px">
+        <div class="absolute top-20px right-20px z-10">
           <TipIcons.Screenshot
             class={btnCls}
             onClick={() => actions.updateThumbnailByScreenshot(true)}

+ 31 - 32
src/modules/editor/controllers/DragAddCtrl/index.ts

@@ -2,45 +2,44 @@ import { ModuleControl } from "queenjs";
 import { EditorModule } from "../../module";
 
 export class DragAddCtrl extends ModuleControl<EditorModule> {
-    dragingCompKey = ""
+  dragingCompKey = "";
 
-    _cancel?:()=>void
-    _mouseUping = false
+  _cancel?: () => void;
+  _mouseUping = false;
 
-    updateCompKey(k:string) {
-        if (this._mouseUping) return;
+  updateCompKey(k: string) {
+    if (this._mouseUping) return;
 
-        const isSame = (k == this.dragingCompKey);
-        this.dragingCompKey = k;
-        if (!isSame && k) {
-            if (this._cancel) this._cancel();
-            this._cancel = this.initEvent();
-        }
+    const isSame = k == this.dragingCompKey;
+    this.dragingCompKey = k;
+    if (!isSame && k) {
+      if (this._cancel) this._cancel();
+      this._cancel = this.initEvent();
     }
+  }
 
-    initEvent() {
-        const scope = this;
+  initEvent() {
+    const scope = this;
 
-        function mouseup(e:MouseEvent) {
-            console.log("mouseup=>", scope.dragingCompKey)
-            scope._mouseUping = true;
-            setTimeout(() => {
-                scope._mouseUping = false;
-            }, 400);
+    function mouseup(e: MouseEvent) {
+      console.log("mouseup=>", scope.dragingCompKey);
+      scope._mouseUping = true;
+      setTimeout(() => {
+        scope._mouseUping = false;
+      }, 1000);
 
-            if (scope._cancel) scope._cancel();
+      if (scope._cancel) scope._cancel();
 
-            if (!scope.dragingCompKey ) return;
-            scope.actions.addCompToDesign(scope.dragingCompKey as any)
-            scope.dragingCompKey = "";
-          
-        }
+      if (!scope.dragingCompKey) return;
+      scope.actions.dragCompToDesign(e, scope.dragingCompKey as any);
+      scope.dragingCompKey = "";
+    }
 
-        document.addEventListener("mouseup", mouseup)
+    document.addEventListener("mouseup", mouseup);
 
-        return ()=> {
-            document.removeEventListener("mouseup", mouseup)
-            scope._cancel = undefined;
-        }
-    }
-}
+    return () => {
+      document.removeEventListener("mouseup", mouseup);
+      scope._cancel = undefined;
+    };
+  }
+}

+ 58 - 0
src/modules/editor/controllers/ScreenshotCtrl/index.ts

@@ -0,0 +1,58 @@
+import domtoimage from "dom-to-image";
+
+export class ScreenshotCtrl {
+  async snap(options: { element: HTMLElement; ratio?: number }): Promise<Blob> {
+    const dom = options.element;
+
+    const transferEl = document.querySelector(".transfer") as
+      | HTMLElement
+      | undefined;
+    if (transferEl) {
+      transferEl.style.display = "none";
+    }
+
+    if (options.ratio) {
+      const result = await domtoimage.toJpeg(dom);
+      const img = await new Promise<HTMLImageElement>((resolve) => {
+        const image = new Image();
+        image.src = result;
+        image.onload = function () {
+          if (transferEl) {
+            transferEl.style.display = "block";
+          }
+          resolve(image);
+        };
+      });
+      const canvas = document.createElement("canvas");
+      canvas.width = img.naturalWidth;
+      canvas.height = Math.min(
+        img.naturalWidth / options.ratio,
+        img.naturalHeight
+      );
+      const ctx = canvas.getContext("2d");
+      ctx?.drawImage(
+        img,
+        0,
+        0,
+        canvas.width,
+        canvas.height,
+        0,
+        0,
+        canvas.width,
+        canvas.height
+      );
+      return new Promise((resolve) => {
+        canvas.toBlob((blob) => {
+          if (transferEl) {
+            transferEl.style.display = "block";
+          }
+          if (blob) {
+            resolve(blob);
+          }
+        });
+      });
+    } else {
+      return domtoimage.toBlob(dom);
+    }
+  }
+}

+ 123 - 0
src/modules/editor/controllers/TransferCtrl/GroupCtrl.ts

@@ -1,5 +1,7 @@
 import { ModuleControl } from "queenjs";
 import { EditorModule } from "../../module";
+import { DesignComp } from "../../objects/DesignTemp/DesignComp";
+import { Matrix } from "./Matrix";
 
 export class GroupActionCtrl extends ModuleControl<EditorModule> {
   init() {
@@ -20,4 +22,125 @@ export class GroupActionCtrl extends ModuleControl<EditorModule> {
   destroy() {
     document.body.removeEventListener("keydown", this.enableGroupMode);
   }
+
+  async combineGroup() {
+    const { helper, store } = this;
+    const { groupIds } = store;
+    if (groupIds.length < 2) return;
+    const compsRect: Record<
+      string,
+      { t: number; l: number; r: number; b: number }
+    > = {};
+    const parentComp = helper.findParentComp(groupIds[0]) as DesignComp;
+    const parentRect = parentComp.$el.getBoundingClientRect();
+    groupIds.forEach((id) => {
+      const comp = helper.findComp(id) as DesignComp;
+      const itemRect = comp.$el.getBoundingClientRect();
+      compsRect[id] = {
+        t: itemRect.top - parentRect.top,
+        l: itemRect.left - parentRect.left,
+        r: itemRect.right - parentRect.left,
+        b: itemRect.bottom - parentRect.top,
+      };
+    });
+
+    const confVals = Object.values(compsRect);
+    const groupConf = {
+      t: Math.min(...confVals.map((d) => d.t)),
+      l: Math.min(...confVals.map((d) => d.l)),
+      r: Math.max(...confVals.map((d) => d.r)),
+      b: Math.max(...confVals.map((d) => d.b)),
+    };
+
+    const groupId = await this.store.insertCompContainer("Group", parentComp);
+
+    const groupComp = helper.findComp(groupId) as DesignComp;
+
+    groupComp.layout = {
+      size: [
+        helper.pxToDesignSize(groupConf.r - groupConf.l),
+        helper.pxToDesignSize(groupConf.b - groupConf.t),
+      ],
+      position: "absolute",
+      transform: {
+        x: helper.pxToDesignSize(groupConf.l),
+        y: helper.pxToDesignSize(groupConf.t),
+      },
+    };
+
+    groupIds.forEach((id) => {
+      const comp = helper.findComp(id) as DesignComp;
+      comp.layout.transform || (comp.layout.transform = {});
+      comp.layout.transform.x =
+        (comp.layout.transform.x || 0) - (groupComp.layout.transform?.x || 0);
+
+      comp.layout.transform.y =
+        (comp.layout.transform.y || 0) - (groupComp.layout.transform?.y || 0);
+    });
+
+    groupComp.children.default = parentComp.children.default?.filter((d) =>
+      groupIds.includes(d)
+    );
+    parentComp.children.default = parentComp.children.default?.filter(
+      (d) => !groupIds.includes(d)
+    );
+
+    return groupId;
+  }
+
+  async cancelGroup(groupComp: DesignComp) {
+    const { helper } = this;
+    const groupChildIds = groupComp.children.default as string[];
+
+    const parentComp = helper.findParentComp(groupComp.id) as DesignComp;
+
+    const parentMatrix = new Matrix();
+
+    groupChildIds.forEach((id) => {
+      const comp = helper.findComp(id) as DesignComp;
+
+      parentMatrix.setFormDiv(groupComp.$el);
+      const originArr = window
+        .getComputedStyle(groupComp.$el)
+        .transformOrigin.split(" ")
+        .map(parseFloat);
+
+      const porigin = new Matrix();
+      porigin.translate(originArr[0], originArr[1]);
+      const invOrigin = new Matrix();
+      invOrigin.translate(-originArr[0], -originArr[1]);
+
+      const childOrigArr = window
+        .getComputedStyle(comp.$el)
+        .transformOrigin.split(" ")
+        .map(parseFloat);
+      const corigin = new Matrix();
+      corigin.translate(childOrigArr[0], childOrigArr[1]);
+      const cinvOrigin = new Matrix();
+      cinvOrigin.translate(-childOrigArr[0], -childOrigArr[1]);
+
+      const childMatrix = new Matrix();
+      childMatrix.setFormDiv(comp.$el);
+
+      const result = cinvOrigin
+        .multipy(porigin)
+        .multipy(parentMatrix)
+        .multipy(invOrigin)
+        .multipy(corigin)
+        .multipy(childMatrix);
+
+      comp.layout.transform || (comp.layout.transform = {});
+      comp.layout.transform.x = helper.pxToDesignSize(result.getX());
+      comp.layout.transform.y = helper.pxToDesignSize(result.getY());
+      comp.layout.transform.s = result.getScale();
+      comp.layout.transform.r = result.getRotate();
+    });
+
+    const childIds = [...(parentComp.children.default as string[])];
+
+    const groupIndex = childIds.findIndex((id) => groupComp.id === id);
+    childIds.splice(groupIndex, 1, ...groupChildIds);
+
+    parentComp.children.default = childIds;
+  }
 }

+ 30 - 124
src/modules/editor/module/actions/edit.ts

@@ -1,11 +1,34 @@
 import { cloneDeep, pick, set } from "lodash";
 import { Exception, queenApi } from "queenjs";
 import { EditorModule } from "..";
+import { ScreenshotCtrl } from "../../controllers/ScreenshotCtrl";
 import { DesignComp } from "../../objects/DesignTemp/DesignComp";
-import { Matrix } from "../../controllers/TransferCtrl/Matrix";
 import { ICompKeys, Layout } from "../../typings";
 
 export const editActions = EditorModule.action({
+  // 通过拖拽添加组件到画布
+  async dragCompToDesign(event: MouseEvent, compKey: ICompKeys) {
+    await this.actions.addCompToDesign(compKey);
+    const cardPoints = this.helper.getPointOffsetWith(
+      event,
+      this.store.currStreamCard.$el
+    );
+    const { currComp } = this.store;
+    currComp.translate(
+      375 - (currComp.layout.size?.[0] || 750) / 2,
+      this.helper.pxToDesignSize(cardPoints.y)
+    );
+  },
+  // 通过点击添加组件到画布
+  async clickCompToDesign(compKey: ICompKeys) {
+    await this.actions.addCompToDesign(compKey);
+    const { currStreamCard, currComp } = this.store;
+
+    const y = currStreamCard.getH();
+    currStreamCard.setH(y + currComp.getH());
+    currComp.translate(0, y);
+  },
+
   // 添加组件到画布
   async addCompToDesign(compKey: ICompKeys, index?: number) {
     if (!this.store.currStreamCardId) {
@@ -68,7 +91,7 @@ export const editActions = EditorModule.action({
     if (this.store.currCompId == compId) {
       return;
     }
- 
+
     this.store.setCurrComp(compId);
     if (this.store.currCompId == this.store.currStreamCardId) {
       this.controls.transferCtrl.destroy();
@@ -116,7 +139,7 @@ export const editActions = EditorModule.action({
   async saveAsComp(comp: DesignComp) {
     try {
       // 组件封面
-      const blob = await this.helper.screenshot({
+      const blob = await new ScreenshotCtrl().snap({
         element: comp.$el,
       });
       const thumbnail = URL.createObjectURL(blob);
@@ -176,7 +199,7 @@ export const editActions = EditorModule.action({
       const rootComp = this.helper.findRootComp();
       if (!rootComp) return;
       queenApi.showLoading("截屏中");
-      const blob = await this.helper.screenshot({
+      const blob = await new ScreenshotCtrl().snap({
         element: rootComp.$el,
         ratio: this.store.isEditComp ? 0 : 1,
       });
@@ -256,133 +279,16 @@ export const editActions = EditorModule.action({
   },
   // 关闭组合模式
   async disableGroupMode() {
-    const groupId = await this.actions.combineGroupComps();
+    const groupId = await this.controls.transferCtrl.groupCtrl.combineGroup();
     if (groupId) {
       this.store.setCurrComp(groupId);
     }
     this.store.setGroupIds([]);
     this.store.setGroupMode(false);
   },
-  // 合并组件
-  async combineGroupComps() {
-    const { helper, store } = this;
-    const { groupIds } = store;
-    if (groupIds.length < 2) return;
-    const compsRect: Record<
-      string,
-      { t: number; l: number; r: number; b: number }
-    > = {};
-    const parentComp = helper.findParentComp(groupIds[0]) as DesignComp;
-    const parentRect = parentComp.$el.getBoundingClientRect();
-    groupIds.forEach((id) => {
-      const comp = helper.findComp(id) as DesignComp;
-      const itemRect = comp.$el.getBoundingClientRect();
-      compsRect[id] = {
-        t: itemRect.top - parentRect.top,
-        l: itemRect.left - parentRect.left,
-        r: itemRect.right - parentRect.left,
-        b: itemRect.bottom - parentRect.top,
-      };
-    });
-
-    const confVals = Object.values(compsRect);
-    const groupConf = {
-      t: Math.min(...confVals.map((d) => d.t)),
-      l: Math.min(...confVals.map((d) => d.l)),
-      r: Math.max(...confVals.map((d) => d.r)),
-      b: Math.max(...confVals.map((d) => d.b)),
-    };
-
-    const groupId = await this.store.insertCompContainer("Group", parentComp);
-
-    const groupComp = helper.findComp(groupId) as DesignComp;
-
-    groupComp.layout = {
-      size: [
-        helper.pxToDesignSize(groupConf.r - groupConf.l),
-        helper.pxToDesignSize(groupConf.b - groupConf.t),
-      ],
-      position: "absolute",
-      transform: {
-        x: helper.pxToDesignSize(groupConf.l),
-        y: helper.pxToDesignSize(groupConf.t),
-      },
-    };
-
-    groupIds.forEach((id) => {
-      const comp = helper.findComp(id) as DesignComp;
-      comp.layout.transform || (comp.layout.transform = {});
-      comp.layout.transform.x =
-        (comp.layout.transform.x || 0) - (groupComp.layout.transform?.x || 0);
-
-      comp.layout.transform.y =
-        (comp.layout.transform.y || 0) - (groupComp.layout.transform?.y || 0);
-    });
-
-    groupComp.children.default = parentComp.children.default?.filter((d) =>
-      groupIds.includes(d)
-    );
-    parentComp.children.default = parentComp.children.default?.filter(
-      (d) => !groupIds.includes(d)
-    );
-
-    return groupId;
-  },
   // 取消打组
   cancelGroupComps(groupComp: DesignComp) {
-    const { helper } = this;
-    const groupChildIds = groupComp.children.default as string[];
-
-    const parentComp = helper.findParentComp(groupComp.id) as DesignComp;
-
-    const parentMatrix = new Matrix();
-
-    groupChildIds.forEach((id) => {
-      const comp = helper.findComp(id) as DesignComp;
-
-      parentMatrix.setFormDiv(groupComp.$el);
-      const originArr = window
-        .getComputedStyle(groupComp.$el)
-        .transformOrigin.split(" ")
-        .map(parseFloat);
-
-      const porigin = new Matrix();
-      porigin.translate(originArr[0], originArr[1]);
-      const invOrigin = new Matrix();
-      invOrigin.translate(-originArr[0], -originArr[1]);
-
-      const childOrigArr = window
-        .getComputedStyle(comp.$el)
-        .transformOrigin.split(" ")
-        .map(parseFloat);
-      const corigin = new Matrix();
-      corigin.translate(childOrigArr[0], childOrigArr[1]);
-      const cinvOrigin = new Matrix();
-      cinvOrigin.translate(-childOrigArr[0], -childOrigArr[1]);
-
-      const childMatrix = new Matrix();
-      childMatrix.setFormDiv(comp.$el);
-
-      const result = cinvOrigin
-        .multipy(porigin)
-        .multipy(parentMatrix)
-        .multipy(invOrigin)
-        .multipy(corigin)
-        .multipy(childMatrix);
-
-      comp.layout.transform || (comp.layout.transform = {});
-      comp.layout.transform.x = helper.pxToDesignSize(result.getX());
-      comp.layout.transform.y = helper.pxToDesignSize(result.getY());
-      comp.layout.transform.s = result.getScale();
-      comp.layout.transform.r = result.getRotate();
-    });
-
-    const childIds = [...(parentComp.children.default as string[])];
-
-    const groupIndex = childIds.findIndex((id) => groupComp.id === id);
-    childIds.splice(groupIndex, 1, ...groupChildIds);
-
-    parentComp.children.default = childIds;
-    this.store.setCurrComp(groupChildIds[0]);
+    this.controls.transferCtrl.groupCtrl.cancelGroup(groupComp);
+    this.store.setCurrComp(groupComp.children.default?.[0] as string);
   },
 });

+ 6 - 57
src/modules/editor/module/helpers/index.ts

@@ -1,4 +1,3 @@
-import domtoimage from "dom-to-image";
 import { EditorModule } from "..";
 import { DesignComp } from "../../objects/DesignTemp/DesignComp";
 import { createCompStyle } from "../../objects/DesignTemp/creates/createCompStyle";
@@ -99,61 +98,11 @@ export const helpers = EditorModule.helper({
       }
     });
   },
-  async screenshot(options: {
-    element: HTMLElement;
-    ratio?: number;
-  }): Promise<Blob> {
-    const dom = options.element;
-
-    const transferEl = document.querySelector(".transfer") as
-      | HTMLElement
-      | undefined;
-    if (transferEl) {
-      transferEl.style.display = "none";
-    }
-
-    if (options.ratio) {
-      const result = await domtoimage.toJpeg(dom);
-      const img = await new Promise<HTMLImageElement>((resolve) => {
-        const image = new Image();
-        image.src = result;
-        image.onload = function () {
-          if (transferEl) {
-            transferEl.style.display = "block";
-          }
-          resolve(image);
-        };
-      });
-      const canvas = document.createElement("canvas");
-      canvas.width = img.naturalWidth;
-      canvas.height = Math.min(
-        img.naturalWidth / options.ratio,
-        img.naturalHeight
-      );
-      const ctx = canvas.getContext("2d");
-      ctx?.drawImage(
-        img,
-        0,
-        0,
-        canvas.width,
-        canvas.height,
-        0,
-        0,
-        canvas.width,
-        canvas.height
-      );
-      return new Promise((resolve) => {
-        canvas.toBlob((blob) => {
-          if (transferEl) {
-            transferEl.style.display = "block";
-          }
-          if (blob) {
-            resolve(blob);
-          }
-        });
-      });
-    } else {
-      return domtoimage.toBlob(dom);
-    }
+  getPointOffsetWith(e: MouseEvent, dom: HTMLElement) {
+    const domRect = dom.getBoundingClientRect();
+    return {
+      x: e.clientX - domRect.left,
+      y: e.clientY - domRect.top,
+    };
   },
 });

+ 16 - 0
src/modules/editor/objects/DesignTemp/DesignComp.ts

@@ -44,4 +44,20 @@ export class DesignComp {
     const w = this.layout.size?.[0];
     return !w || w === 750;
   }
+
+  translate(x: number, y: number) {
+    this.layout.transform || (this.layout.transform = {});
+    x && (this.layout.transform.x = x);
+    y && (this.layout.transform.y = y);
+  }
+  getW() {
+    return this.layout.size?.[0] || 0;
+  }
+  getH() {
+    return this.layout.size?.[1] || 0;
+  }
+  setH(height: number) {
+    if (!this.layout.size) this.layout.size = [];
+    this.layout.size[1] = height;
+  }
 }

+ 6 - 1
src/pages/editor/EditPage/index.tsx

@@ -10,7 +10,12 @@ export default defineComponent(() => {
 
   const params = new URLSearchParams(location.hash.split("?")[1]);
   editor.actions.switchMode((params.get("mode") || "editPage") as EditorMode);
-  editor.actions.initDesign(params.get("id") || "");
+  const prodId = params.get("id");
+  if (prodId) {
+    editor.actions.initDesign(prodId);
+  } else {
+    editor.jumpIndexHtml();
+  }
 
   editor.controls.pickCtrl.onPickImage = async (maxCount: number) => {
     if (maxCount <= 1) {