@ohkit/draggable-box 0.0.1

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/src/type.ts ADDED
@@ -0,0 +1,68 @@
1
+ import type {ValidPlacement} from './constants';
2
+
3
+ export interface DraggableBoxProps {
4
+ className?: string;
5
+ children?: React.ReactNode;
6
+ /**
7
+ * z-index 层级
8
+ * @default 9999
9
+ */
10
+ zIndex?: number;
11
+ /**
12
+ * 初始位置 横向偏移量
13
+ * @default 20
14
+ */
15
+ offsetX?: number;
16
+ /**
17
+ * 初始位置 纵向偏移量
18
+ * @default 20
19
+ */
20
+ offsetY?: number;
21
+ /**
22
+ * 是否禁用拖拽
23
+ * @default false
24
+ */
25
+ disabled?: boolean;
26
+ /**
27
+ * 拖拽位置,可选值:'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
28
+ * @default 'bottom-right'
29
+ */
30
+ placement?: typeof ValidPlacement[number]; // 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
31
+ /**
32
+ * 锁定拖拽方向
33
+ * 'none' - 自由拖拽 (默认)
34
+ * 'x' - 只允许水平方向拖拽
35
+ * 'y' - 只允许垂直方向拖拽
36
+ * @default 'none'
37
+ */
38
+ lockAxis?: 'none' | 'x' | 'y';
39
+ /**
40
+ * X轴相对边界 [min, max] - 基于placement的相对距离范围
41
+ * 比如:placement='top-left'时,boundsX=[左边最小距离, 左边最大距离]
42
+ */
43
+ boundsX?: [number?, number?];
44
+ /**
45
+ * Y轴相对边界 [min, max] - 基于placement的相对距离范围
46
+ * 比如:placement='top-left'时,boundsY=[顶边最小距离, 顶边最大距离]
47
+ */
48
+ boundsY?: [number?, number?];
49
+ /**
50
+ * 是否在拖拽过程中展示拖拽区域可视化
51
+ * @default false
52
+ */
53
+ showDragArea?: boolean;
54
+ /**
55
+ * 定位模式
56
+ * 'fixed' - 使用 fixed 定位(默认),动态查找影响 fixed 定位的父元素
57
+ * 'absolute' - 使用 absolute 定位,基于最近的定位父元素
58
+ * @default 'fixed'
59
+ */
60
+ positionMode?: 'fixed' | 'absolute';
61
+ }
62
+
63
+ export interface DraggableBoxState {
64
+ top?: number;
65
+ bottom?: number;
66
+ left?: number;
67
+ right?: number;
68
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,57 @@
1
+ import {findParent} from '@ohkit/dom-helper';
2
+
3
+ /**
4
+ * 查找影响 fixed 定位的父元素
5
+ * 当父元素有 transform/filter/perspective 等属性时,fixed 定位会相对于该父元素
6
+ */
7
+ export function findFixedPositionParent(dom?: HTMLElement | null): HTMLElement {
8
+ if (!dom) {
9
+ return document.documentElement;
10
+ }
11
+ const fixedPositionParent = findParent(dom, (parent) => {
12
+ const style = window.getComputedStyle(parent);
13
+ const transform = style.getPropertyValue('transform');
14
+ const filter = style.getPropertyValue('filter');
15
+ const perspective = style.getPropertyValue('perspective');
16
+
17
+ // 检查是否有影响 fixed 定位的属性
18
+ if (transform !== 'none' || filter !== 'none' || perspective !== 'none') {
19
+ return true;
20
+ }
21
+ }, {excludeOwn: true}) || document.documentElement; // 没有找到,返回 window(通过 document.documentElement)
22
+ return fixedPositionParent;
23
+ }
24
+
25
+ /**
26
+ * 查找 absolute 定位的父元素
27
+ * 查找最近的 position 不为 static 的元素
28
+ */
29
+ export function findAbsolutePositionParent(dom?: HTMLElement | null): HTMLElement {
30
+ if (!dom) {
31
+ return document.body;
32
+ }
33
+ return findParent(dom, (parent) => {
34
+ const style = window.getComputedStyle(parent);
35
+ const position = style.getPropertyValue('position');
36
+ if (position !== 'static') {
37
+ return true;
38
+ }
39
+ }, {excludeOwn: true}) || document.body;
40
+ }
41
+
42
+ /**
43
+ * 获取容器的缩放比例
44
+ * 通过比较元素的实际尺寸和 getBoundingClientRect 返回的尺寸来计算缩放比例
45
+ */
46
+ export function getScaleRatio(dom?: HTMLElement | null): { scaleX: number; scaleY: number } {
47
+ if (!dom) {
48
+ return { scaleX: 1, scaleY: 1 };
49
+ }
50
+ // 通过比较 offsetWidth 和 getBoundingClientRect().width 来获取缩放比例
51
+ const rect = dom.getBoundingClientRect();
52
+ // 扩大10倍进行计算,避免浮点数精度问题
53
+ const scaleX = dom.offsetWidth > 0 ? Math.round(rect.width / dom.offsetWidth * 10) / 10 : 1;
54
+ const scaleY = dom.offsetHeight > 0 ? Math.round(rect.height / dom.offsetHeight * 10) / 10 : 1;
55
+ // console.log('scaleX', scaleX, 'scaleY', scaleY);
56
+ return { scaleX, scaleY };
57
+ }