@ohkit/draggable-box 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/index.es.js +1 -1
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.modern.mjs +1 -1
- package/dist/index.modern.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/types/index.d.ts +4 -2
- package/dist/types/type.d.ts +5 -0
- package/dist/types/utils.d.ts +6 -0
- package/package.json +3 -3
- package/src/index.tsx +67 -24
- package/src/type.ts +5 -0
- package/src/utils.ts +10 -0
package/src/index.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
classNames as cx,
|
|
5
5
|
} from "@ohkit/prefix-classname";
|
|
6
6
|
import {addEventListener, addClass} from '@ohkit/dom-helper';
|
|
7
|
-
import {findFixedPositionParent, findAbsolutePositionParent, getScaleRatio, clamp} from './utils';
|
|
7
|
+
import {findFixedPositionParent, findAbsolutePositionParent, getScaleRatio, clamp, supportsTouchEvents} from './utils';
|
|
8
8
|
import {ValidPlacement} from './constants';
|
|
9
9
|
import {DraggableBoxProps, DraggableBoxState} from './type';
|
|
10
10
|
|
|
@@ -20,6 +20,7 @@ export class DraggableBox extends React.Component<DraggableBoxProps, DraggableBo
|
|
|
20
20
|
disabled: false,
|
|
21
21
|
lockAxis: 'none',
|
|
22
22
|
showDragArea: false,
|
|
23
|
+
showDragAreaOverMoveDistanse: 5,
|
|
23
24
|
positionMode: 'fixed',
|
|
24
25
|
};
|
|
25
26
|
|
|
@@ -226,6 +227,7 @@ export class DraggableBox extends React.Component<DraggableBoxProps, DraggableBo
|
|
|
226
227
|
__bodyClassDisposer?: () => void;
|
|
227
228
|
__upDisposer?: () => void;
|
|
228
229
|
__resizeDisposer?: () => void;
|
|
230
|
+
__preventScrollDisposer?: () => void;
|
|
229
231
|
|
|
230
232
|
dragAreaRef: HTMLDivElement | null = null;
|
|
231
233
|
|
|
@@ -245,15 +247,19 @@ export class DraggableBox extends React.Component<DraggableBoxProps, DraggableBo
|
|
|
245
247
|
}
|
|
246
248
|
}
|
|
247
249
|
|
|
248
|
-
enableDrag = () => {
|
|
250
|
+
enableDrag = (isTouch = false) => {
|
|
249
251
|
this.reportStartPosition();
|
|
250
252
|
this.__moveDisposer?.();
|
|
251
|
-
this.__moveDisposer = addEventListener(document, 'mousemove', (evt) => {
|
|
253
|
+
this.__moveDisposer = addEventListener(isTouch && this.draggerRef ? this.draggerRef : document, isTouch ? 'touchmove' : 'mousemove', (evt) => {
|
|
254
|
+
evt.stopPropagation();
|
|
255
|
+
if (isTouch) {
|
|
256
|
+
evt.preventDefault();
|
|
257
|
+
}
|
|
252
258
|
// INFO: 移动过程中禁止click事件
|
|
253
259
|
if (!this.__clickDisposer) {
|
|
254
260
|
const moveDistanse = Math.sqrt(Math.pow(this.dX, 2) + Math.pow(this.dY, 2));
|
|
255
|
-
// INFO: 移动超过
|
|
256
|
-
if (moveDistanse > 5) {
|
|
261
|
+
// INFO: 移动超过px?? 确保用户有真实的移动意愿,而不是手抖~~
|
|
262
|
+
if (moveDistanse > (this.props.showDragAreaOverMoveDistanse || 5)) {
|
|
257
263
|
this.__clickDisposer = addEventListener(
|
|
258
264
|
document,
|
|
259
265
|
'click',
|
|
@@ -270,17 +276,17 @@ export class DraggableBox extends React.Component<DraggableBoxProps, DraggableBo
|
|
|
270
276
|
}
|
|
271
277
|
}
|
|
272
278
|
}
|
|
273
|
-
this.dragging(evt);
|
|
274
|
-
},
|
|
279
|
+
this.dragging(evt as TouchEvent | MouseEvent);
|
|
280
|
+
}, {
|
|
281
|
+
passive: !isTouch
|
|
282
|
+
});
|
|
275
283
|
|
|
276
284
|
this.__upDisposer?.();
|
|
277
285
|
this.__upDisposer = addEventListener(
|
|
278
286
|
document,
|
|
279
287
|
'mouseup',
|
|
280
|
-
(
|
|
288
|
+
() => {
|
|
281
289
|
this.endDrag();
|
|
282
|
-
evt.stopPropagation();
|
|
283
|
-
evt.preventDefault();
|
|
284
290
|
},
|
|
285
291
|
true
|
|
286
292
|
);
|
|
@@ -294,11 +300,11 @@ export class DraggableBox extends React.Component<DraggableBoxProps, DraggableBo
|
|
|
294
300
|
this.axisX = evt.nativeEvent.pageX;
|
|
295
301
|
this.axisY = evt.nativeEvent.pageY;
|
|
296
302
|
if (!this.props.disabled) {
|
|
297
|
-
|
|
303
|
+
this.enableDrag();
|
|
298
304
|
}
|
|
299
305
|
};
|
|
300
306
|
|
|
301
|
-
dragging = (evt: MouseEvent) => {
|
|
307
|
+
dragging = (evt: MouseEvent | TouchEvent) => {
|
|
302
308
|
this.isDragging = true;
|
|
303
309
|
const { lockAxis } = this.props;
|
|
304
310
|
const { minX, maxX, minY, maxY } = this.dragPositionBoundaries;
|
|
@@ -307,9 +313,21 @@ export class DraggableBox extends React.Component<DraggableBoxProps, DraggableBo
|
|
|
307
313
|
const scaleX = this.cachedScaleX;
|
|
308
314
|
const scaleY = this.cachedScaleY;
|
|
309
315
|
|
|
316
|
+
// 获取坐标
|
|
317
|
+
let pageX: number, pageY: number;
|
|
318
|
+
if (evt instanceof TouchEvent) {
|
|
319
|
+
const touch = evt.touches[0];
|
|
320
|
+
if (!touch) return;
|
|
321
|
+
pageX = touch.pageX;
|
|
322
|
+
pageY = touch.pageY;
|
|
323
|
+
} else {
|
|
324
|
+
pageX = evt.pageX;
|
|
325
|
+
pageY = evt.pageY;
|
|
326
|
+
}
|
|
327
|
+
|
|
310
328
|
// 计算原始偏移量(需要除以缩放比例)
|
|
311
|
-
this.dX = (
|
|
312
|
-
this.dY = (
|
|
329
|
+
this.dX = (pageX - (this.axisX || 0)) / scaleX;
|
|
330
|
+
this.dY = (pageY - (this.axisY || 0)) / scaleY;
|
|
313
331
|
|
|
314
332
|
// 应用方向锁定并计算变换值
|
|
315
333
|
let translateX = this.dX;
|
|
@@ -346,7 +364,16 @@ export class DraggableBox extends React.Component<DraggableBoxProps, DraggableBo
|
|
|
346
364
|
if (this.draggerRef) {
|
|
347
365
|
this.draggerRef.style.transform = `translate(${translateX}px, ${translateY}px)`;
|
|
348
366
|
}
|
|
349
|
-
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
startTouchDrag = (evt: React.TouchEvent<HTMLDivElement>) => {
|
|
370
|
+
const touch = evt.touches[0];
|
|
371
|
+
if (!touch) return;
|
|
372
|
+
this.axisX = touch.pageX;
|
|
373
|
+
this.axisY = touch.pageY;
|
|
374
|
+
if (!this.props.disabled) {
|
|
375
|
+
this.enableDrag(true);
|
|
376
|
+
}
|
|
350
377
|
};
|
|
351
378
|
|
|
352
379
|
endDrag = () => {
|
|
@@ -362,8 +389,10 @@ export class DraggableBox extends React.Component<DraggableBoxProps, DraggableBo
|
|
|
362
389
|
}
|
|
363
390
|
}
|
|
364
391
|
|
|
365
|
-
this.__moveDisposer
|
|
366
|
-
|
|
392
|
+
if (this.__moveDisposer) {
|
|
393
|
+
this.__moveDisposer();
|
|
394
|
+
this.__moveDisposer = undefined;
|
|
395
|
+
}
|
|
367
396
|
if (this.__clickDisposer) {
|
|
368
397
|
requestAnimationFrame(() => {
|
|
369
398
|
if (this.__clickDisposer) {
|
|
@@ -372,10 +401,14 @@ export class DraggableBox extends React.Component<DraggableBoxProps, DraggableBo
|
|
|
372
401
|
}
|
|
373
402
|
});
|
|
374
403
|
}
|
|
375
|
-
this.__upDisposer
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
404
|
+
if (this.__upDisposer) {
|
|
405
|
+
this.__upDisposer();
|
|
406
|
+
this.__upDisposer = undefined;
|
|
407
|
+
}
|
|
408
|
+
if (this.__bodyClassDisposer) {
|
|
409
|
+
this.__bodyClassDisposer();
|
|
410
|
+
this.__bodyClassDisposer = undefined;
|
|
411
|
+
}
|
|
379
412
|
|
|
380
413
|
this.isDragging = false;
|
|
381
414
|
};
|
|
@@ -464,6 +497,13 @@ export class DraggableBox extends React.Component<DraggableBoxProps, DraggableBo
|
|
|
464
497
|
this.__resizeDisposer = addEventListener(window, 'resize', () => {
|
|
465
498
|
this.calcPosition();
|
|
466
499
|
});
|
|
500
|
+
|
|
501
|
+
// 触屏设备时,阻止拖拽时滚动页面
|
|
502
|
+
if (supportsTouchEvents() && this.draggerRef) {
|
|
503
|
+
this.__preventScrollDisposer = addEventListener(this.draggerRef, 'touchmove', (evt) => {
|
|
504
|
+
evt.preventDefault();
|
|
505
|
+
});
|
|
506
|
+
}
|
|
467
507
|
}
|
|
468
508
|
|
|
469
509
|
componentWillUnmount() {
|
|
@@ -472,11 +512,12 @@ export class DraggableBox extends React.Component<DraggableBoxProps, DraggableBo
|
|
|
472
512
|
this.__moveDisposer?.();
|
|
473
513
|
this.__clickDisposer?.();
|
|
474
514
|
this.__upDisposer?.();
|
|
515
|
+
this.__preventScrollDisposer?.();
|
|
475
516
|
}
|
|
476
517
|
|
|
477
518
|
render() {
|
|
478
519
|
const { className, zIndex, children, showDragArea, positionMode = 'fixed' } = this.props;
|
|
479
|
-
const { startDrag, endDrag } = this;
|
|
520
|
+
const { startDrag, startTouchDrag, endDrag } = this;
|
|
480
521
|
const stl = {
|
|
481
522
|
zIndex,
|
|
482
523
|
...this.position,
|
|
@@ -508,8 +549,10 @@ export class DraggableBox extends React.Component<DraggableBoxProps, DraggableBo
|
|
|
508
549
|
ref={(r) => {
|
|
509
550
|
this.draggerRef = r;
|
|
510
551
|
}}
|
|
511
|
-
|
|
512
|
-
|
|
552
|
+
onMouseDownCapture={startDrag}
|
|
553
|
+
onMouseUpCapture={endDrag}
|
|
554
|
+
onTouchStartCapture={startTouchDrag}
|
|
555
|
+
onTouchEndCapture={endDrag}
|
|
513
556
|
>
|
|
514
557
|
{children}
|
|
515
558
|
</div>
|
package/src/type.ts
CHANGED
|
@@ -51,6 +51,11 @@ export interface DraggableBoxProps {
|
|
|
51
51
|
* @default false
|
|
52
52
|
*/
|
|
53
53
|
showDragArea?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* 拖拽过程中,超出多少px时才显示拖拽区域可视化
|
|
56
|
+
* @default 5
|
|
57
|
+
*/
|
|
58
|
+
showDragAreaOverMoveDistanse?: number;
|
|
54
59
|
/**
|
|
55
60
|
* 定位模式
|
|
56
61
|
* 'fixed' - 使用 fixed 定位(默认),动态查找影响 fixed 定位的父元素
|
package/src/utils.ts
CHANGED
|
@@ -86,3 +86,13 @@ export function getScaleRatio(dom?: HTMLElement | null): { scaleX: number; scale
|
|
|
86
86
|
export function clamp(value: number, min: number, max: number) {
|
|
87
87
|
return Math.min(Math.max(value, min), max);
|
|
88
88
|
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 检测当前环境是否支持触摸事件
|
|
93
|
+
*
|
|
94
|
+
* @returns 如果环境支持触摸事件返回 true,否则返回 false
|
|
95
|
+
*/
|
|
96
|
+
export function supportsTouchEvents() {
|
|
97
|
+
return typeof window !== 'undefined' && ('ontouchstart' in window || navigator.maxTouchPoints > 0);
|
|
98
|
+
};
|