Kaynağa Gözat

Merge branch 'dev' of http://124.70.149.18:10880/lianghj/queenshow into dev

qinyan 1 yıl önce
ebeveyn
işleme
448d1fdcc2

+ 23 - 10
src/modules/editor/components/CompUI/basicUI/Text/component.tsx

@@ -7,7 +7,7 @@ import { FontColor, FontFamily, FontSize } from "@ckeditor/ckeditor5-font";
 import { Link } from "@ckeditor/ckeditor5-link";
 import { Paragraph } from "@ckeditor/ckeditor5-paragraph";
 import { css } from "@linaria/core";
-import { defineComponent, watch, watchEffect } from "vue";
+import { defineComponent, ref, watch, watchEffect, reactive } from "vue";
 import { string } from "vue-types";
 import { useCompData } from ".";
 import { View } from "../View";
@@ -18,7 +18,7 @@ export const Component = defineComponent({
   },
   setup(props) {
     const comp = useCompData(props.compId);
-    const { store, helper, actions } = useEditor();
+    const { store, helper, actions, controls } = useEditor();
     const config = {
       language: "zh-cn",
       plugins: [
@@ -53,12 +53,24 @@ export const Component = defineComponent({
     };
 
     let editorInstance: InlineEditor;
+    let timeOut = ref();
+    const state = reactive({
+      textEditing: false,
+    });
 
     watchEffect(() => {
-      if (!store.textEditingState) {
+      if (!state.textEditing) {
         editorInstance?.setData(comp.value);
       }
     });
+    const toolbarClickListener = () => {
+      editorInstance.ui.view.toolbar.element?.addEventListener("click", () => {
+        if (timeOut.value) {
+          clearTimeout(timeOut.value);
+          timeOut.value = null;
+        }
+      });
+    };
 
     return () => (
       <View
@@ -69,19 +81,19 @@ export const Component = defineComponent({
           class={textStyle}
           editor={InlineEditor}
           onBlur={() => {
-            // actions.updateCompData(
-            //   helper.findComp(props.compId) as DesignComp,
-            //   "value",
-            //   editorInstance.getData()
-            // );
-            // store.setTextEditingState(false);
+            timeOut.value = setTimeout(() => {
+              state.textEditing = false;
+              store.setTextEditingState(false);
+              controls.historyCtrl.history.submit();
+            }, 500);
           }}
           onFocus={() => {
             store.setTextEditingState(true);
+            state.textEditing = true;
           }}
           onInput={(e: any) => {
             if (editorInstance) {
-              actions.updateCompData(
+              actions.setTextarea(
                 helper.findComp(props.compId) as DesignComp,
                 "value",
                 e
@@ -91,6 +103,7 @@ export const Component = defineComponent({
           onReady={(editor: InlineEditor) => {
             editorInstance = editor;
             editor.setData(comp.value);
+            toolbarClickListener();
             if (store.isPreview) {
               editor.enableReadOnlyMode("editor");
             }

+ 91 - 35
src/modules/editor/components/Viewport/Slider/SliderLeft/MySources.tsx

@@ -1,43 +1,99 @@
-import { useResource } from "@/modules/resource";
+import { useEditor } from "@/modules/editor";
+import { initResource, useResource } from "@/modules/resource";
+import { css } from "@linaria/core";
 import { Image, List, Loadmore } from "@queenjs/ui";
 import { Radio } from "ant-design-vue";
-import { defineComponent } from "vue";
+import { defineComponent, reactive } from "vue";
 
 export const MySources = defineComponent({
   setup() {
+    const editor = useEditor();
     const resource = useResource();
-    const matListCtrl = resource.controls.materialImageListCtrl;
-    matListCtrl.hasLimit = true;
-    matListCtrl.loadPage(1);
-
-    return () => (
-      <div class="scrollbar">
-        <Radio.Group>
-          <Radio.Button>图片</Radio.Button>
-          <Radio.Button>视频</Radio.Button>
-        </Radio.Group>
-
-        <List data={matListCtrl.state.list} columns={2} gap="20px">
-          {{
-            item(item: any) {
-              return (
-                <div style={{ aspectRatio: 1 }}>
-                  <Image class="w-full h-full" src={item.file.url} size={240} />
-                </div>
-              );
-            },
-            loadmore() {
-              return (
-                <Loadmore
-                  loading={matListCtrl.state.loading}
-                  canLoad={matListCtrl.state.canLoadNext}
-                  onChange={matListCtrl.loadNextPage}
-                />
-              );
-            },
-          }}
-        </List>
-      </div>
-    );
+    const state = reactive({
+      sourceType: "Image" as "Image" | "Video",
+    });
+
+    function getCurrCtrl() {
+      return resource.controls[
+        state.sourceType === "Image"
+          ? "materialImageListCtrl"
+          : "materialVideoListCtrl"
+      ];
+    }
+
+    function switchSource(v: "Image" | "Video") {
+      state.sourceType = v;
+      const ctrl = getCurrCtrl();
+      ctrl.hasLimit = true;
+      ctrl.loadPage(1);
+    }
+
+    function clickToDesign(url: string) {
+      editor.actions.clickCompToDesign(state.sourceType, (comp) => {
+        comp.value.url = url;
+      });
+    }
+
+    switchSource("Image");
+
+    return () => {
+      const control =
+        resource.controls[
+          state.sourceType === "Image"
+            ? "materialImageListCtrl"
+            : "materialVideoListCtrl"
+        ];
+      return (
+        <div class="space-y-20px -mt-10px">
+          <Radio.Group
+            class={radioCls}
+            value={state.sourceType}
+            size="small"
+            onChange={(e) => switchSource(e.target.value)}
+          >
+            <Radio.Button value="Image">图片</Radio.Button>
+            <Radio.Button value="Video">视频</Radio.Button>
+          </Radio.Group>
+
+          <List data={control.state.list} columns={2} gap="20px">
+            {{
+              item(item: any) {
+                return (
+                  <div
+                    style={{ aspectRatio: 1 }}
+                    onClick={() => clickToDesign(item.file.url)}
+                  >
+                    <Image
+                      class="w-full h-full"
+                      src={item.file.url}
+                      size={240}
+                    />
+                  </div>
+                );
+              },
+              loadmore() {
+                return (
+                  <Loadmore
+                    class="mt-20px"
+                    loading={control.state.loading}
+                    canLoad={control.state.canLoadNext}
+                    onChange={control.loadNextPage}
+                  />
+                );
+              },
+            }}
+          </List>
+        </div>
+      );
+    };
   },
 });
+
+const radioCls = css`
+  display: flex;
+  > label {
+    flex: 1;
+    width: 0;
+    text-align: center;
+  }
+`;

+ 5 - 2
src/modules/editor/controllers/HistoryCtrl/HistoryController.ts

@@ -22,8 +22,8 @@ export class HistoryController {
   cacheGroupAction = new GroupAction();
 
   // 添加缓存记录
-  record(action: Action) {
-    this.cacheGroupAction.record(action);
+  record(action: Action, options?: RecordOptions) {
+    this.cacheGroupAction.record(action, options);
   }
 
   // 保存缓存记录到历史栈中
@@ -45,16 +45,19 @@ export class HistoryController {
     state.currLen = queue.length;
     // 更新当前缓存GroupAction
     this.cacheGroupAction = new GroupAction();
+    console.log(this);
   }
 
   undo() {
     if (!this.state.canUndo) return;
     this.queue[this.state.opIndex--].undo();
+    console.log(this)
   }
 
   redo() {
     if (!this.state.canRedo) return;
     this.queue[++this.state.opIndex].redo();
+    console.log(this)
   }
 
   //清除操作

+ 2 - 1
src/modules/editor/controllers/HistoryCtrl/index.ts

@@ -5,6 +5,7 @@ import { Action, HistoryController } from "./HistoryController";
 export class HistoryCtrl {
   history: HistoryController;
   historyActionDoing = false;
+  historyCombine = false;
 
   constructor(protected module: EditorModule, historyTotal = 50) {
     this.history = new HistoryController();
@@ -20,7 +21,7 @@ export class HistoryCtrl {
   ) {
     if (this.historyActionDoing) {
       const action = new Action(type, root, paths.join("."), value, oldValue);
-      this.history.record(action);
+      this.history.record(action, {combine: this.historyCombine});
     }
   }
 

+ 36 - 29
src/modules/editor/controllers/SelectCtrl/ObjsContainer.ts

@@ -2,6 +2,7 @@ import { Bounds } from './objects/bounds';
 import { Rectangle } from './objects/rectangle';
 import { Container } from './objects/container';
 import { CompObject } from './compObj';
+import { Matrix } from './matrix';
 
 export class ObjsContainer {
     aabb = new Bounds();
@@ -216,7 +217,6 @@ export class ObjsContainer {
 
     scaleX(x:number) {
         this.parent.scale.x = x;
-
         this.parent.updateTransform();
         this.updateCompState();
     }
@@ -227,40 +227,47 @@ export class ObjsContainer {
         this.updateCompState();
     }
 
-    // scaleSize(w:number, h:number) {
-
-    // }
-
-    scaleWidth(w:number) {
-         
-        //怎么改对应的偏移值
-        this.parent.scale.x = w / this.rect.width
-
-
-        this.rect.width = w;
-        this.selected[0].width = w;
+    applyChildWidth(option:{Width?:number, Height?:number}) {
+        const obj = this.selected[0];
+        //先移除
+        this.parent.removeChildWorldNoChange(obj);
+        const m = new Matrix();
+        m.scale(option.Width ? option.Width/obj.width :1 , option.Height? option.Height / obj.height: 1)
+        m.invert();
+        m.prepend(obj.worldTransform)
+        obj.transform.setFromMatrix(m)
+        if (option.Width) {
+            obj.width = option.Width
+        }
+        if (option.Height) {
+            obj.height = option.Height
+        }
+        obj.updateTransform();
+        this.parent.addChildWorldNoChange(obj);
     }
-    // scaleHeight(w:number) {
-
-    // }
-    //清除当前元素的缩放 改为类容的宽度
-    applyScaleToChildSize() {
-        if (this.selected.length  != 1 ) return;
-       
-        const w = this.width *this.parent.scale.x;
-        const h = this.height  *this.parent.scale.y;
-        this.parent.scale.x = 1;
-        this.parent.scale.y = 1;
+    scaleSize(Width:number, Height:number) {
+        this.parent.scale.y = Height / this.rect.height
+        this.parent.scale.x = Width / this.rect.width
         this.parent.updateTransform();
+        this.applyChildWidth({Width, Height})
+        this.updateCompState();
+    }
 
-        this.rect.width = w;
-        this.rect.height = h;
-        this.selected[0].width = w;
-        this.selected[0].height = h;
-
+    scaleWidth(Width:number) {
+        //怎么改对应的偏移值
+        this.parent.scale.x = Width / this.rect.width
+        this.parent.updateTransform();
+        this.applyChildWidth({Width})
         this.updateCompState();
     }
 
+    scaleHeight(Height:number) {
+        this.parent.scale.y = Height / this.rect.height
+        this.parent.updateTransform();
+        this.applyChildWidth({Height});
+        this.updateCompState();
+    }
+    
     translate(x:number, y:number) {
         this.parent.x += x;
         this.parent.y += y;

+ 40 - 17
src/modules/editor/controllers/SelectCtrl/index.ts

@@ -59,9 +59,13 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
   _downClientY = 0;
   //groupCtrl = new GroupActionCtrl(this.module);
   bus = new Event();
-  viewport?:HTMLElement;
+  viewport?: HTMLElement;
 
-  initEvents(pageEl: HTMLElement, selCanvas: HTMLCanvasElement, viewport:HTMLElement) {
+  initEvents(
+    pageEl: HTMLElement,
+    selCanvas: HTMLCanvasElement,
+    viewport: HTMLElement
+  ) {
     this.viewport = viewport;
     this.pageEl = pageEl;
     this.selCanvas = selCanvas;
@@ -125,13 +129,17 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
         //判断是否有点击到card stream
         const comps = this.compClickTest(e);
         this.mouseDownSelects = comps;
-        console.log("comps=>", 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;
-            }
+          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];
@@ -250,7 +258,7 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
     }
   }
 
-  translate(xOffset:number, yOffset:number) {
+  translate(xOffset: number, yOffset: number) {
     const objContainer = this.objContainer as ObjsContainer;
     objContainer.translate(xOffset, yOffset);
     this.upgateGizmoStyle();
@@ -388,7 +396,6 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
 
     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();
@@ -472,7 +479,7 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
       return;
 
     if (objs.length == 1) {
-        this.actions.pickComp(objs[0].comp.id);
+      this.actions.pickComp(objs[0].comp.id);
     }
 
     // objs = this.getSceneObjOrderArr(objs);
@@ -659,6 +666,8 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
   scaleCmd = false;
   lastScale = { x: 1, y: 1 };
 
+  initScaleWith = {w: 0, h:0};
+
   scaleMousemove(event: MouseEvent) {
     let dirIndexs = [
       "scaleBottomright",
@@ -690,6 +699,8 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
       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
@@ -715,7 +726,10 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
       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);
+    //   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;
@@ -724,13 +738,22 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
       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);
+        // objContainer.scale(this.lastScale.x, this.lastScale.y);
+        const currW = this.initScaleWith.w * this.lastScale.x;
+        objContainer.scaleSize(currW, this.initScaleWith.h *this.lastScale.y);
+        // objContainer.scaleHeight(, dtaScale);
+
       } else if (i == 0 || i == 1) {
         this.lastScale.x = dtaScale * this.initScale.x;
-        objContainer.scaleX(this.lastScale.x);
+        // objContainer.scaleX(this.lastScale.x);
+        const currW = this.initScaleWith.w * this.lastScale.x;
+        objContainer.scaleWidth(currW);
+
       } else if (i == 2 || i == 3) {
         this.lastScale.y = dtaScale * this.initScale.y;
-        objContainer.scaleY(this.lastScale.y);
+        
+        // objContainer.scaleY(this.lastScale.y);
+        objContainer.scaleHeight(this.lastScale.y * this.initScaleWith.h);
       }
     }
 
@@ -743,8 +766,8 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
       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.objContainer?.applyScaleToChildSize();
-      this.upgateGizmoStyle();
+    //   this.objContainer?.applyScaleToChildSize();
+    //   this.upgateGizmoStyle();
       // this.editor.history.record({
       //     undo:()=>{
       //         this.objContainer.setPivot( scaleIndex );

+ 2 - 1
src/modules/editor/module/actions/edit.ts

@@ -22,12 +22,13 @@ export const editActions = EditorModule.action({
 
   },
   // 通过点击添加组件到画布
-  async clickCompToDesign(compKey: ICompKeys) {
+  async clickCompToDesign(compKey: ICompKeys, cb?: (comp: DesignComp) => void) {
 
     const bound = this.helper.getCardCompBound(this.store.currCompId);
 
     await this.actions.addCompToDesign(compKey);
     const { currComp } = this.store;
+    cb?.(currComp);
 
     //添加组件到当前选中的组件下面
     const obj = new CompObject(currComp);

+ 14 - 0
src/modules/editor/module/actions/text.ts

@@ -0,0 +1,14 @@
+import { set } from "lodash";
+import { EditorModule } from "..";
+import { DesignComp } from "../../objects/DesignTemp/DesignComp";
+
+export const textActions = EditorModule.action({
+  setTextarea(comp: DesignComp, path: string, value: any) {
+    const { historyCtrl } = this.controls;
+    historyCtrl.historyActionDoing = true;
+    historyCtrl.historyCombine = true;
+    set(comp, path, value);
+    historyCtrl.historyCombine = false;
+    historyCtrl.historyActionDoing = false;
+  },
+});

+ 2 - 1
src/modules/editor/module/index.ts

@@ -16,6 +16,7 @@ import { store } from "./stores";
 import { DragAddCtrl } from "../controllers/DragAddCtrl";
 import { SelectCtrl } from "../controllers/SelectCtrl";
 import { CompObject } from "../controllers/SelectCtrl/compObj";
+import { textActions } from "./actions/text";
 
 export class EditorModule extends ModuleRoot {
   config = this.setConfig({
@@ -25,7 +26,7 @@ export class EditorModule extends ModuleRoot {
   });
   components = this.useComponents(components);
 
-  actions = this.createActions([initActions, editActions, ImgCompActions]);
+  actions = this.createActions([initActions, editActions, ImgCompActions, textActions]);
   https = this.createHttps(https);
   store = this.createStore(store, {
     transform: (state) => createProxy(state),