Browse Source

Fix: [Image] fix the drag and drop problem after the Image component is enlarged (#1146)

* fix: [Image] fix the drag and drop problem after the Image component is enlarged

* docs: API in alphabetical order & fix doc error

* docs: optimize example

* fix: [Image] change event.path to event.composePath()

* style: remove useless css
YyumeiZhang 3 years ago
parent
commit
edd8b1d8fb

+ 1 - 1
content/show/dropdown/index-en-US.md

@@ -427,7 +427,7 @@ function DropdownEvents() {
 | children | Child elements wrapped by the drop layer | ReactNode |  |  |
 | clickToHide | Whether to close the drop-down layer automatically when clicking on the drop-down layer | boolean |  | **0.24.0** |
 | contentClassName | Drop-down menu root element class name | string |  |  |
-| getPopupContainer | Specifies the parent DOM, and the bullet layer will be rendered to the DOM, you need to set 'position: relative` | function():HTMLElement | () = > document.body |
+| getPopupContainer | Specifies the parent DOM, and the bullet layer will be rendered to the DOM, you need to set 'position: relative` | function():HTMLElement | () => document.body |
 | mouseEnterDelay | After the mouse is moved into the Trigger, the display time is delayed, in milliseconds (only effective when the trigger is hover/focus) | number | 50 |  |
 | mouseLeaveDelay | The time for the delay to disappear after the mouse moves out of the pop-up layer, in milliseconds (only effective when the trigger is hover/focus) | number | 50 |  |
 | menu | Menu content config | Array<DropdownMenuItem\> | [] | **1.12.0** |

File diff suppressed because it is too large
+ 2 - 0
content/show/image/index-en-US.md


File diff suppressed because it is too large
+ 2 - 0
content/show/image/index.md


+ 3 - 0
packages/semi-foundation/image/image.scss

@@ -13,6 +13,7 @@ $module: #{$prefix}-image;
     &-img {
         vertical-align: middle;
         border-radius: inherit;
+        user-select: none;
 
         &-preview {
             cursor: zoom-in;
@@ -135,6 +136,7 @@ $module: #{$prefix}-image;
         }
 
         &-page {
+            user-select: none;
             color: $color-image_preview_footer_icon;
             @include font-size-header-6;
             margin: $spacing-image_preview_footer_page-marginY $spacing-image_preview_footer_page-marginX;
@@ -192,6 +194,7 @@ $module: #{$prefix}-image;
             transform: scale3d($transform_scale3d-image_preview_image_img) $transform_rotate-image_preview_image_img;
             transition: transform $transition_duration-image_preview_image_img  $transition_delay-image_preview_image_img;
             z-index: 0;
+            user-select: none;
         }
 
         &-spin {

+ 5 - 5
packages/semi-foundation/image/previewImageFoundation.ts

@@ -220,16 +220,16 @@ export default class PreviewImageFoundation<P = Record<string, any>, S = Record<
     };
 
     handleMoveImage = (e: any): void => {
-        const { offset, width, height, left, top } = this.getStates();
-        const { rotation } = this.getProps();
+        const { offset, width, height } = this.getStates();
         const startMouseMove = this._adapter.getMouseMove();
         const startMouseOffset = this._adapter.getMouseOffset();
         const { canDragVertical, canDragHorizontal } = this.calcCanDragDirection();
         if (startMouseMove && (canDragVertical || canDragHorizontal)) {
-            const { pageX, pageY } = e;
+            const { clientX, clientY } = e;
+            const { left: containerLeft, top: containerTop } = this._getContainerBounds();
             const { left: extremeLeft, top: extremeTop } = this.calcExtremeBounds();
-            let newX = canDragHorizontal ? pageX - startMouseOffset.x : offset.x;
-            let newY = canDragVertical ? pageY - startMouseOffset.y : offset.y;
+            let newX = canDragHorizontal ? clientX - containerLeft - startMouseOffset.x : offset.x;
+            let newY = canDragVertical ? clientY - containerTop - startMouseOffset.y : offset.y;
             if (canDragHorizontal) {
                 newX = newX > 0 ? 0 : newX < extremeLeft ? extremeLeft : newX;
             }

+ 5 - 1
packages/semi-foundation/image/previewInnerFoundation.ts

@@ -77,7 +77,11 @@ export default class PreviewInnerFoundation<P = Record<string, any>, S = Record<
         let couldClose = !isTargetEmit(e.nativeEvent, NOT_CLOSE_TARGETS);
         const { clientX, clientY } = e;
         const { x, y } = this._adapter.getStartMouseDown();
-        if (clientX !== x || y !== clientY) {
+        // 对鼠标移动做容错处理,当 x 和 y 方向在 mouseUp 的时候移动距离都小于等于 5px 时候就可以关闭预览
+        // Error-tolerant processing of mouse movement, when the movement distance in the x and y directions is less than or equal to 5px in mouseUp, the preview can be closed
+        // 不做容错处理的话,直接用 clientX !== x || y !== clientY 做判断,鼠标在用户点击时候无意识的轻微移动无法关闭预览,不符合用户预期
+        // If you do not do fault-tolerant processing, but directly use clientX !== x || y !== clientY to make judgments, the slight movement of the mouse when the user clicks will not be able to close the preview, which does not meet the user's expectations.
+        if (Math.abs(clientX - x) > 5 || Math.abs(y - clientY) > 5) {
             couldClose = false;
         }
         if (couldClose && maskClosable) {

+ 5 - 3
packages/semi-foundation/image/utils.ts

@@ -1,7 +1,9 @@
 export const isTargetEmit = (event, targetClasses): boolean => {
-    // e.path is the event-triggered bubbling path, which stores each node through which bubbling passes.
-    // e.path.length-4 is to remove elements above the root node, such as body, html, document, window
-    const isTarget = event?.path?.slice(0, event.path.length - 4).some((node): boolean => {
+    // event.path usage is discouraged, use event.composedPath() as it's standard and is more future-proof
+    // path is the event-triggered bubbling path, which stores each node through which bubbling passes.
+    // path.length-4 is to remove elements above the root node, such as body, html, document, window
+    const path = event?.composedPath();
+    const isTarget = path?.slice(0, path.length - 4).some((node): boolean => {
         if (node.className && typeof node.className === "string") {
             return targetClasses.some(c => node.className.includes(c));
         }

Some files were not shown because too many files changed in this diff