Procházet zdrojové kódy

fix: fixed-layout drag element portal (#901)

* fix: eslint spell

* fix: drag dom portal global

* fix: client dragOffset

* fix: test
chenjiawei.inizio před 3 měsíci
rodič
revize
6b80d48f4d

+ 0 - 1
config/eslint-config/.eslintrc.base.js

@@ -88,7 +88,6 @@ module.exports = {
         'react/jsx-no-useless-fragment': 'off',
         'no-unused-vars': 'off',
         'no-redeclare': 'off',
-        'no-empty-fuNction': 'off',
         'prefer-destructurin': 'off',
         'no-underscore-dangle': 'off',
         'no-empty-function': 'off',

+ 5 - 5
packages/canvas-engine/renderer/__tests__/entities/flow-drag-entities.test.ts

@@ -62,12 +62,12 @@ describe('flow-drag-entity', () => {
   it('flow drag scroll', () => {
     const el = global.document.createElement('div');
     // 页面不滚动
-    expect(flowDragEntity.scrollDirection(NOT_SCROLL_EVENT, el, 0, 0)).toMatchSnapshot();
+    expect(flowDragEntity.scrollDirection(NOT_SCROLL_EVENT, 0, 0)).toMatchSnapshot();
     // 页面滚动
-    expect(flowDragEntity.scrollDirection(SCROLL_TOP_EVENT, el, 0, 0)).toMatchSnapshot();
-    expect(flowDragEntity.scrollDirection(SCROLL_LEFT_EVENT, el, 0, 0)).toMatchSnapshot();
-    expect(flowDragEntity.scrollDirection(SCROLL_RIGHT_EVENT, el, 0, 0)).toMatchSnapshot();
-    expect(flowDragEntity.scrollDirection(SCROLL_BOTTOM_EVENT, el, 0, 0)).toMatchSnapshot();
+    expect(flowDragEntity.scrollDirection(SCROLL_TOP_EVENT, 0, 0)).toMatchSnapshot();
+    expect(flowDragEntity.scrollDirection(SCROLL_LEFT_EVENT, 0, 0)).toMatchSnapshot();
+    expect(flowDragEntity.scrollDirection(SCROLL_RIGHT_EVENT, 0, 0)).toMatchSnapshot();
+    expect(flowDragEntity.scrollDirection(SCROLL_BOTTOM_EVENT, 0, 0)).toMatchSnapshot();
     // 停止滚动
     flowDragEntity.stopAllScroll();
     expect(flowDragEntity.hasScroll).toEqual(false);

+ 1 - 16
packages/canvas-engine/renderer/src/entities/flow-drag-entity.tsx

@@ -42,8 +42,6 @@ export class FlowDragEntity extends ConfigEntity<FlowDragEntityConfig> {
 
   static type = 'FlowDragEntity';
 
-  private containerDom: HTMLDivElement;
-
   private containerX = 0;
 
   private containerY = 0;
@@ -179,7 +177,6 @@ export class FlowDragEntity extends ConfigEntity<FlowDragEntityConfig> {
         } else {
           this.containerX -= SCROLL_DELTA;
         }
-        this.setDomStyle();
       }
     }, SCROLL_INTERVAL);
     this._scrollXInterval = { interval, origin };
@@ -213,7 +210,6 @@ export class FlowDragEntity extends ConfigEntity<FlowDragEntityConfig> {
         } else {
           this.containerY -= SCROLL_DELTA;
         }
-        this.setDomStyle();
       }
     }, SCROLL_INTERVAL);
     this._scrollYInterval = { interval, origin };
@@ -231,21 +227,10 @@ export class FlowDragEntity extends ConfigEntity<FlowDragEntityConfig> {
     this._stopScrollY();
   }
 
-  setDomStyle() {
-    this.containerDom.style.left = `${this.containerX}px`;
-    this.containerDom.style.top = `${this.containerY}px`;
-  }
-
-  scrollDirection(
-    e: MouseEvent,
-    containerDom: HTMLDivElement,
-    x: number,
-    y: number
-  ): ScrollDirection | undefined {
+  scrollDirection(e: MouseEvent, x: number, y: number): ScrollDirection | undefined {
     const playgroundConfig = this.playgroundConfigEntity.config;
     const currentScrollX = playgroundConfig.scrollX;
     const currentScrollY = playgroundConfig.scrollY;
-    this.containerDom = containerDom;
     this.containerX = x;
     this.containerY = y;
     const clientRect = this.playgroundConfigEntity.playgroundDomNode.getBoundingClientRect();

+ 18 - 11
packages/canvas-engine/renderer/src/layers/flow-drag-layer.tsx

@@ -3,6 +3,7 @@
  * SPDX-License-Identifier: MIT
  */
 
+import ReactDOM from 'react-dom';
 import React from 'react';
 
 import { inject, injectable } from 'inversify';
@@ -114,7 +115,7 @@ export class FlowDragLayer extends Layer<FlowDragOptions> {
     dropEntity: FlowNodeEntity
   ) => Promise<FlowNodeEntity>;
 
-  private dragOffset = {
+  dragOffset = {
     x: DEFAULT_DRAG_OFFSET_X,
     y: DEFAULT_DRAG_OFFSET_Y,
   };
@@ -242,18 +243,18 @@ export class FlowDragLayer extends Layer<FlowDragOptions> {
 
         this.containerRef.current.style.visibility = 'visible';
         this.pipelineNode.parentElement!.appendChild(this.draggingNodeMask);
-        this.containerRef.current.style.left = `${dragBlockX}px`;
-        this.containerRef.current.style.top = `${dragBlockY}px`;
+
+        this.containerRef.current.style.left = `${
+          dragBlockX + this.pipelineNode.offsetLeft + clientBounds.x + window.scrollX
+        }px`;
+        this.containerRef.current.style.top = `${
+          dragBlockY + this.pipelineNode.offsetTop + clientBounds.y + window.scrollY
+        }px`;
         this.containerRef.current.style.transformOrigin = 'top left';
         this.containerRef.current.style.transform = `scale(${scale})`;
 
         if (!this.disableDragScroll) {
-          this.flowDragConfigEntity.scrollDirection(
-            event,
-            this.containerRef.current,
-            dragBlockX,
-            dragBlockY
-          );
+          this.flowDragConfigEntity.scrollDirection(event, dragBlockX, dragBlockY);
         }
       }
     }
@@ -383,11 +384,16 @@ export class FlowDragLayer extends Layer<FlowDragOptions> {
     }
   }
 
+  dispose(): void {
+    this._dragger.dispose();
+    super.dispose();
+  }
+
   render() {
     // styled-component component type 为 any
     const DragComp: any = this.dragNodeComp.renderer;
 
-    return (
+    return ReactDOM.createPortal(
       <div
         ref={this.containerRef}
         style={{ position: 'absolute', zIndex: 99999, visibility: 'hidden' }}
@@ -398,7 +404,8 @@ export class FlowDragLayer extends Layer<FlowDragOptions> {
           dragStart={this.dragStartEntity}
           dragNodes={this.dragEntities}
         />
-      </div>
+      </div>,
+      document.body
     );
   }
 }

+ 6 - 2
packages/client/fixed-layout-editor/src/hooks/use-node-render.tsx

@@ -111,7 +111,7 @@ export function useNodeRender(nodeFromProps?: FlowNodeEntity): NodeRenderReturnT
   const nodeCache = useRef<FlowNodeEntity | undefined>();
   const renderData = renderNode.getData<FlowNodeRenderData>(FlowNodeRenderData)!;
   const { expanded, dragging, activated } = renderData;
-  const { startDrag: startDragOrigin } = useStartDragNode();
+  const { startDrag: startDragOrigin, dragOffset } = useStartDragNode();
   const playground = usePlayground();
   const isBlockOrderIcon = renderNode.flowNodeType === FlowNodeBaseType.BLOCK_ORDER_ICON;
   const isBlockIcon = renderNode.flowNodeType === FlowNodeBaseType.BLOCK_ICON;
@@ -129,7 +129,11 @@ export function useNodeRender(nodeFromProps?: FlowNodeEntity): NodeRenderReturnT
 
   const startDrag = useCallback(
     (e: React.MouseEvent) => {
-      startDragOrigin(e, { dragStartEntity: renderNode }, { dragOffsetX: 30, dragOffsetY: 30 });
+      startDragOrigin(
+        e,
+        { dragStartEntity: renderNode },
+        { dragOffsetX: dragOffset.x, dragOffsetY: dragOffset.y }
+      );
     },
     [renderNode, startDragOrigin]
   );

+ 6 - 0
packages/plugins/fixed-drag-plugin/src/hooks/use-start-drag-node.ts

@@ -16,6 +16,12 @@ export function useStartDragNode() {
   return useMemo(
     () => ({
       startDrag: dragLayer ? dragLayer.startDrag.bind(dragLayer) : (e: any) => {},
+      dragOffset: dragLayer
+        ? dragLayer.dragOffset
+        : {
+            x: 0,
+            y: 0,
+          },
     }),
     [dragLayer]
   );