Эх сурвалжийг харах

Merge pull request #44 from emibcn/master

Add a debouncer mechanism to prevent start dragging until mouse moves 10 pixels at least while mousedown is active
ZhengFang 6 жил өмнө
parent
commit
da03c18ba2

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
build/react-dragger-layout.js


+ 97 - 6
dist/src/lib/dragger/index.js

@@ -17,7 +17,7 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
     }
     return t;
 };
-Object.defineProperty(exports, "__esModule", { value: true });
+exports.__esModule = true;
 var React = require("react");
 var utils_1 = require("../utils");
 var doc = null;
@@ -44,7 +44,8 @@ var Dragger = /** @class */ (function (_super) {
             w: _this.props.w || 0,
             h: _this.props.h || 0,
             lastW: 0,
-            lastH: 0
+            lastH: 0,
+            originalEvent: null
         };
         _this.move = function (event) {
             var _a = _this.state, lastX = _a.lastX, lastY = _a.lastY;
@@ -136,6 +137,96 @@ var Dragger = /** @class */ (function (_super) {
                 y: deltaY
             });
         };
+        _this.moveDebounce = function (event) {
+            var _a = _this.state, lastX = _a.lastX, lastY = _a.lastY;
+            /*  event.client - this.state.origin 表示的是移动的距离,
+            *   elX表示的是原来已经有的位移
+            */
+            var deltaX, deltaY;
+            if (event.type.indexOf('mouse') >= 0) {
+                deltaX = event.clientX - _this.state.originX + lastX;
+                deltaY = event.clientY - _this.state.originY + lastY;
+            }
+            else {
+                deltaX =
+                    event.touches[0].clientX -
+                        _this.state.originX +
+                        lastX;
+                deltaY =
+                    event.touches[0].clientY -
+                        _this.state.originY +
+                        lastY;
+            }
+            /*
+             * Remove Debounce event listeners and add legitimate ones
+             * after 10 pixels motion
+             */
+            if ((Math.abs(deltaX) + Math.abs(deltaY)) > 10) {
+                // Remove debounce event listeners
+                if (event.type.indexOf('mouse') >= 0) {
+                    doc.removeEventListener('mousemove', _this.moveDebounce);
+                    doc.removeEventListener('mouseup', _this.onDragEndDebounce);
+                }
+                else {
+                    doc.removeEventListener('touchmove', _this.moveDebounce);
+                    doc.removeEventListener('touchend', _this.onDragEndDebounce);
+                }
+                // Initiate real dragStart with original event
+                _this.onDragStart(_this.state.originalEvent);
+                // Trigger real movement with current event");
+                _this.move(event);
+            }
+        };
+        // Saves initial state and event, but add event listeners for debounce only
+        _this.onDragStartDebounce = function (event) {
+            var originX, originY;
+            if (event.type.indexOf('mouse') >= 0) {
+                originX = event.clientX;
+                originY = event.clientY;
+            }
+            else {
+                originX = event.touches[0].clientX;
+                originY = event.touches[0].clientY;
+            }
+            event.persist();
+            _this.setState({
+                originalEvent: event,
+                originX: originX,
+                originY: originY,
+                lastX: _this.state.x,
+                lastY: _this.state.y,
+                zIndex: 10
+            });
+            // Add event listeners at the end to prevent firing them before
+            // having the original event saved into state
+            if (event.type.indexOf('mouse') >= 0) {
+                doc.addEventListener('mousemove', _this.moveDebounce);
+                doc.addEventListener('mouseup', _this.onDragEndDebounce);
+            }
+            else {
+                doc.addEventListener('touchmove', _this.moveDebounce);
+                doc.addEventListener('touchend', _this.onDragEndDebounce);
+            }
+        };
+        // Cleans debounce events
+        _this.onDragEndDebounce = function (event) {
+            /** 取消用户选择限制,用户可以重新选择 */
+            doc.body.style.userSelect = '';
+            _this.parent = null;
+            _this.self = null;
+            if (event.type.indexOf('mouse') >= 0) {
+                // Remove debounce event listeners");
+                doc.removeEventListener('mousemove', _this.moveDebounce);
+                doc.removeEventListener('mouseup', _this.onDragEndDebounce);
+            }
+            else {
+                doc.removeEventListener('touchmove', _this.moveDebounce);
+                doc.removeEventListener('touchend', _this.onDragEndDebounce);
+            }
+            _this.setState({
+                originalEvent: null
+            });
+        };
         _this.onDragStart = function (event) {
             /** 保证用户在移动元素的时候不会选择到元素内部的东西 */
             doc.body.style.userSelect = 'none';
@@ -271,10 +362,10 @@ var Dragger = /** @class */ (function (_super) {
         };
         _this.mixin = function () {
             var dragMix = {
-                onMouseDown: _this.onDragStart,
-                onTouchStart: _this.onDragStart,
-                onTouchEnd: _this.onDragEnd,
-                onMouseUp: _this.onDragEnd
+                onMouseDown: _this.onDragStartDebounce,
+                onTouchStart: _this.onDragStartDebounce,
+                onTouchEnd: _this.onDragEndDebounce,
+                onMouseUp: _this.onDragEndDebounce
             };
             var resizeMix = {
                 onMouseDown: _this.onResizeStart,

+ 1 - 3
package.json

@@ -53,7 +53,7 @@
     "@types/react-dom": "^16.0.4",
     "@types/reselect": "^2.2.0",
     "agentframework": "^0.9.9",
-    "babel-jest": "^22.2.2",
+    "babel-jest": "23.6.0",
     "babel-plugin-transform-object-rest-spread": "^6.26.0",
     "babel-plugin-transform-react-jsx": "^6.24.1",
     "babel-plugin-transform-runtime": "^6.23.0",
@@ -68,5 +68,3 @@
     "typescript-babel-jest": "^1.0.5"
   }
 }
-
-

+ 99 - 5
src/lib/dragger/index.tsx

@@ -58,7 +58,9 @@ export class Dragger extends React.Component<DraggerProps, {}> {
         h: this.props.h || 0,
 
         lastW: 0,
-        lastH: 0
+        lastH: 0,
+
+        originalEvent: null
     }
 
     move = (event: any) => {
@@ -163,6 +165,98 @@ export class Dragger extends React.Component<DraggerProps, {}> {
         })
     }
 
+    moveDebounce = (event: any) => {
+        let { lastX, lastY } = this.state
+        /*  event.client - this.state.origin 表示的是移动的距离,
+        *   elX表示的是原来已经有的位移
+        */
+
+        let deltaX, deltaY
+        if (event.type.indexOf('mouse') >= 0) {
+            deltaX = (event as MouseEvent).clientX - this.state.originX + lastX
+            deltaY = (event as MouseEvent).clientY - this.state.originY + lastY
+        } else {
+            deltaX =
+                (event as TouchEvent).touches[0].clientX -
+                this.state.originX +
+                lastX
+            deltaY =
+                (event as TouchEvent).touches[0].clientY -
+                this.state.originY +
+                lastY
+        }
+
+        /*
+         * Remove Debounce event listeners and add legitimate ones
+         * after 10 pixels motion
+         */
+        if((Math.abs(deltaX) + Math.abs(deltaY)) > 10) {
+            // Remove debounce event listeners
+            if (event.type.indexOf('mouse') >= 0) {
+                doc.removeEventListener('mousemove', this.moveDebounce)
+                doc.removeEventListener('mouseup', this.onDragEndDebounce)
+            } else {
+                doc.removeEventListener('touchmove', this.moveDebounce)
+                doc.removeEventListener('touchend', this.onDragEndDebounce)
+            }
+            // Initiate real dragStart with original event
+            this.onDragStart(this.state.originalEvent);
+
+            // Trigger real movement with current event");
+            this.move(event);
+        }
+    }
+
+    // Saves initial state and event, but add event listeners for debounce only
+    onDragStartDebounce = (event: any) => {
+        let originX, originY
+        if (event.type.indexOf('mouse') >= 0) {
+            originX = (event as MouseEvent).clientX
+            originY = (event as MouseEvent).clientY
+        } else {
+            originX = (event as TouchEvent).touches[0].clientX
+            originY = (event as TouchEvent).touches[0].clientY
+        }
+        event.persist();
+        this.setState({
+            originalEvent: event,
+            originX: originX,
+            originY: originY,
+            lastX: this.state.x,
+            lastY: this.state.y,
+            zIndex: 10
+        })
+        // Add event listeners at the end to prevent firing them before
+        // having the original event saved into state
+        if (event.type.indexOf('mouse') >= 0) {
+            doc.addEventListener('mousemove', this.moveDebounce)
+            doc.addEventListener('mouseup', this.onDragEndDebounce)
+        } else {
+            doc.addEventListener('touchmove', this.moveDebounce)
+            doc.addEventListener('touchend', this.onDragEndDebounce)
+        }
+    }
+
+    // Cleans debounce events
+    onDragEndDebounce = (event: any) => {
+        /** 取消用户选择限制,用户可以重新选择 */
+        doc.body.style.userSelect = ''
+        this.parent = null
+        this.self = null
+
+        if (event.type.indexOf('mouse') >= 0) {
+            // Remove debounce event listeners");
+            doc.removeEventListener('mousemove', this.moveDebounce)
+            doc.removeEventListener('mouseup', this.onDragEndDebounce)
+        } else {
+            doc.removeEventListener('touchmove', this.moveDebounce)
+            doc.removeEventListener('touchend', this.onDragEndDebounce)
+        }
+        this.setState({
+            originalEvent: null
+        })
+    }
+
     onDragStart = (event: any) => {
         /** 保证用户在移动元素的时候不会选择到元素内部的东西 */
         doc.body.style.userSelect = 'none'
@@ -351,10 +445,10 @@ export class Dragger extends React.Component<DraggerProps, {}> {
 
     mixin = () => {
         var dragMix = {
-            onMouseDown: this.onDragStart,
-            onTouchStart: this.onDragStart,
-            onTouchEnd: this.onDragEnd,
-            onMouseUp: this.onDragEnd
+            onMouseDown: this.onDragStartDebounce,
+            onTouchStart: this.onDragStartDebounce,
+            onTouchEnd: this.onDragEndDebounce,
+            onMouseUp: this.onDragEndDebounce
         }
 
         var resizeMix = {

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно