Ver Fonte

添加框选流程

liwei há 1 ano atrás
pai
commit
5dcdcfc015

+ 85 - 73
src/modules/editor/components/Viewport/Content/index.tsx

@@ -27,6 +27,7 @@ export default defineUI({
     const NotFoundComp = () => <div>无效的组件</div>;
     const flagRef = ref();
     const containRef = ref();
+    const selectCanvasRef = ref();
 
     return () => {
       const pageRoot = helper.findRootComp();
@@ -37,87 +38,90 @@ export default defineUI({
       if (!flagRef.value) {
         flagRef.value = true;
         setTimeout(() => {
-          actions.onViewReady();
+          actions.onViewReady(pageRoot.$el, selectCanvasRef.value);
         }, 0);
       }
 
       return (
         <div class="scrollbar overflow-y-auto h-1/1">
-          <div class={"w-375px my-60px mx-auto select-none " + contentCls}>
-            <CompUI.Page.Component compId={pageRoot.id}>
-              {{
-                Container(children: any) {
-                  return (
-                    <>
-                      <Container
-                        behaiver="drop-zone"
-                        class={store.isEditPage ? "!min-h-750px" : ""}
-                        drag-handle-selector=".draganchor"
-                        drop-placeholder={false}
-                        animation-duration={0}
-                        ref={containRef}
-                        should-accept-drop={(
-                          sourceContainerOptions: any,
-                          payload: any
-                        ) => {
-                          console.log(
-                            "sourceContainerOptions:any, payload:any",
-                            sourceContainerOptions,
-                            payload
-                          );
-                          if (sourceContainerOptions.groupName != "canvas")
+          <div class="relative">
+            <div class={"w-375px my-60px mx-auto select-none " + contentCls}>
+              <CompUI.Page.Component compId={pageRoot.id}>
+                {{
+                  Container(children: any) {
+                    return (
+                      <>
+                        <Container
+                          behaiver="drop-zone"
+                          class={store.isEditPage ? "!min-h-750px" : ""}
+                          drag-handle-selector=".draganchor"
+                          drop-placeholder={false}
+                          animation-duration={0}
+                          ref={containRef}
+                          should-accept-drop={(
+                            sourceContainerOptions: any,
+                            payload: any
+                          ) => {
+                            console.log(
+                              "sourceContainerOptions:any, payload:any",
+                              sourceContainerOptions,
+                              payload
+                            );
+                            if (sourceContainerOptions.groupName != "canvas")
+                              return false;
+                            controls.dragAddCtrl.updateCompKey(payload);
                             return false;
-                          controls.dragAddCtrl.updateCompKey(payload);
-                          return false;
-                        }}
-                        drop-not-allowed={(p: any) => {
-                          console.log("p", p);
-                        }}
-                        onDrop={(e: any) => {
-                          console.log(e);
-                          return;
+                          }}
+                          drop-not-allowed={(p: any) => {
+                            console.log("p", p);
+                          }}
+                          onDrop={(e: any) => {
+                            console.log(e);
+                            return;
 
-                          if (e.payload) {
-                            actions.addCompToDesign(e.payload, e.addedIndex);
-                          } else {
-                            actions.moveComp(e.removedIndex, e.addedIndex);
-                          }
-                        }}
-                        onDragStart={() => (state.draging = true)}
-                        onDragEnd={() => (state.draging = false)}
-                        non-drag-area-selector={".drag-disable"}
-                      >
-                        {children}
-                      </Container>
-                      {store.currStreamCardId && (
-                        <StreamCardTransfer
-                          key={store.currStreamCardId + streamCardIndex}
-                        />
-                      )}
-
-                      {store.currCompId &&
-                        store.currStreamCardId &&
-                        store.currCompId !== "root" &&
-                        !store.textEditingState &&
-                        store.currCompId !== store.currStreamCardId &&
-                        !state.draging && (
-                          <Transfer key={store.currCompId + streamCardIndex} />
+                            if (e.payload) {
+                              actions.addCompToDesign(e.payload, e.addedIndex);
+                            } else {
+                              actions.moveComp(e.removedIndex, e.addedIndex);
+                            }
+                          }}
+                          onDragStart={() => (state.draging = true)}
+                          onDragEnd={() => (state.draging = false)}
+                          non-drag-area-selector={".drag-disable"}
+                        >
+                          {children}
+                        </Container>
+                        {store.currStreamCardId && (
+                          <StreamCardTransfer
+                            key={store.currStreamCardId + streamCardIndex}
+                          />
                         )}
-                    </>
-                  );
-                },
-                CompItem(comp: DesignComp) {
-                  const Comp =
-                    controls.compUICtrl.state.components.get(comp.compKey)
-                      ?.Component || NotFoundComp;
-                  return (
-                    <Draggable key={comp.id}>
-                      <Comp compId={comp.id} />
-                    </Draggable>
-                  );
-                },
-              }}
-            </CompUI.Page.Component>
+
+                        {store.currCompId &&
+                          store.currStreamCardId &&
+                          store.currCompId !== "root" &&
+                          !store.textEditingState &&
+                          store.currCompId !== store.currStreamCardId &&
+                          !state.draging && (
+                            <Transfer key={store.currCompId + streamCardIndex} />
+                          )}
+                      </>
+                    );
+                  },
+                  CompItem(comp: DesignComp) {
+                    const Comp =
+                      controls.compUICtrl.state.components.get(comp.compKey)
+                        ?.Component || NotFoundComp;
+                    return (
+                      <Draggable key={comp.id}>
+                        <Comp compId={comp.id} />
+                      </Draggable>
+                    );
+                  },
+                }}
+              </CompUI.Page.Component>
+            </div>
+            <canvas class={selectCls}  ref={selectCanvasRef} />
           </div>
         </div>
       );
@@ -130,3 +134,11 @@ const contentCls = css`
     overflow: unset;
   }
 `;
+const selectCls = css`
+  pointer-events: none;
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+`;

+ 164 - 0
src/modules/editor/controllers/SelectCtrl/index.ts

@@ -0,0 +1,164 @@
+import { ModuleControl } from "queenjs";
+import { reactive } from "vue";
+import { EditorModule } from "../../module";
+import { DesignComp } from "../../objects/DesignTemp/DesignComp";
+import { Matrix } from "../TransferCtrl/Matrix";
+
+/**
+ *  页面画布空间进行选择
+ */
+const MODE_SEL_RECT = 1;
+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({
+    width: "",
+    height: "",
+    transform: {
+      rotate: "0deg",
+      translateX: 0,
+      translateY: 0,
+      scale: 1,
+    },
+  });
+  selectIds = []; //选中的所有组件ids
+
+  pageEl?:HTMLElement
+  selCanvas= {} as HTMLCanvasElement
+
+  _downed = false;
+  _selCtx = {} as CanvasRenderingContext2D
+  _state = MODE_SEL_RECT;
+
+  _selDownX = 0;
+  _selDownY = 0;
+  _selBox = {} as DOMRect;
+  _selCanvaseSize = {w: 0, h: 0};
+
+  initEvents(pageEl: HTMLElement, selCanvas: HTMLCanvasElement) {
+    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;
+
+    document.addEventListener("mousedown", this.onDocMouseDown.bind(this))
+    document.addEventListener("mousemove", this.onDocMouseMove.bind(this))
+    document.addEventListener("mouseup", this.onDocMouseUp.bind(this))
+
+    window.addEventListener("resize", this.onResize.bind(this));
+  }
+
+  onDocMouseDown(e: MouseEvent) {
+    if (!this.pageEl || !this.selCanvas ) return;
+
+    let box = this.pageEl.getBoundingClientRect();
+    const pageX = e.clientX- box?.left
+    const pageY = e.clientY- box?.top
+    
+    const card = this.store.currStreamCard.$el;
+    box = card.getBoundingClientRect();
+    const cardX = pageX;
+    const cardY = e.clientY - box.top;
+
+    const sel = this.selCanvas.getBoundingClientRect();
+    const selX = (e.clientX - sel.left);
+    const sely = (e.clientY - sel.top);
+    this._selDownX = selX;
+    this._selDownY = sely;
+    this._selBox = sel;
+
+    console.log(cardX,selX, cardY, sely)
+
+    this._downed = true;
+    this._state = MODE_SEL_RECT;
+
+  }
+
+  onDocMouseMove(e: MouseEvent) {
+    if (!this.pageEl ) return;
+
+    if (!this._downed) {
+        this.checkHover();
+    }
+
+    switch (this._state) {
+        case MODE_SEL_RECT: //选框模式
+            this.drawSelRect(e);
+            break;
+    }
+  }
+
+  onDocMouseUp(e: MouseEvent) {
+    console.log("up");
+    this._state = MODE_NONE;
+    this._selCtx?.clearRect(0, 0, this._selCanvaseSize.w, this._selCanvaseSize.h)
+  }
+  
+  selectId(id :string) { //选中ids之前 id对应组件必须已经渲染
+    console.log("selectId=>", id)
+  }
+
+  drawSelRect(e:MouseEvent) {
+
+    const ctx = this._selCtx;
+
+    const dx = this._selDownX;
+    const dy = this._selDownY;
+    const currX =  e.clientX - this._selBox.left;
+    const currY =  e.clientY - this._selBox.top;
+    const x = Math.min(currX, dx), y = Math.min(dy, currY)
+     ctx.clearRect(0, 0, this._selCanvaseSize.w, this._selCanvaseSize.h)
+
+     ctx.fillStyle = "rgba(232, 139, 0, 0.16)";
+     ctx.fillRect(x*2, y*2, Math.abs(currX-dx)*2, Math.abs(currY-dy)*2);
+
+     ctx.lineWidth = 2;
+     ctx.strokeStyle = "#E88B00";
+     ctx.strokeRect(x*2, y*2, Math.abs(currX-dx)*2, Math.abs(currY-dy)*2);
+  }
+
+  checkHover() {
+    this.selectIds;
+  }
+
+  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)
+
+  }
+}

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

@@ -29,7 +29,8 @@ export const initActions = EditorModule.action({
     this.store.setMode(v);
   },
 
-  onViewReady() {
+  onViewReady(pageEl, selEl) {
     this.store.currStreamCardId = this.store.streamCardIds[0];
+    this.controls.selectCtrl.initEvents(pageEl, selEl);
   },
 });

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

@@ -14,6 +14,7 @@ import { helpers } from "./helpers";
 import { https } from "./https";
 import { store } from "./stores";
 import { DragAddCtrl } from "../controllers/DragAddCtrl";
+import { SelectCtrl } from "../controllers/SelectCtrl";
 
 export class EditorModule extends ModuleRoot {
   config = this.setConfig({
@@ -43,6 +44,7 @@ export class EditorModule extends ModuleRoot {
     historyCtrl: new HistoryCtrl(this),
     pickCtrl: new ImagePickController(),
     compUICtrl: new CompUICtrl(this),
+    selectCtrl: new SelectCtrl(this),
   };
 
   onReady() {