提交 | 用户 | 时间
|
820397
|
1 |
import { HotZoneItemProperty } from '@/components/DiyEditor/components/mobile/HotZone/config' |
H |
2 |
import { StyleValue } from 'vue' |
|
3 |
|
|
4 |
// 热区的最小宽高 |
|
5 |
export const HOT_ZONE_MIN_SIZE = 100 |
|
6 |
|
|
7 |
// 控制的类型 |
|
8 |
export enum CONTROL_TYPE_ENUM { |
|
9 |
LEFT, |
|
10 |
TOP, |
|
11 |
WIDTH, |
|
12 |
HEIGHT |
|
13 |
} |
|
14 |
|
|
15 |
// 定义热区的控制点 |
|
16 |
export interface ControlDot { |
|
17 |
position: string |
|
18 |
types: CONTROL_TYPE_ENUM[] |
|
19 |
style: StyleValue |
|
20 |
} |
|
21 |
|
|
22 |
// 热区的8个控制点 |
|
23 |
export const CONTROL_DOT_LIST = [ |
|
24 |
{ |
|
25 |
position: '左上角', |
|
26 |
types: [ |
|
27 |
CONTROL_TYPE_ENUM.LEFT, |
|
28 |
CONTROL_TYPE_ENUM.TOP, |
|
29 |
CONTROL_TYPE_ENUM.WIDTH, |
|
30 |
CONTROL_TYPE_ENUM.HEIGHT |
|
31 |
], |
|
32 |
style: { left: '-5px', top: '-5px', cursor: 'nwse-resize' } |
|
33 |
}, |
|
34 |
{ |
|
35 |
position: '上方中间', |
|
36 |
types: [CONTROL_TYPE_ENUM.TOP, CONTROL_TYPE_ENUM.HEIGHT], |
|
37 |
style: { left: '50%', top: '-5px', cursor: 'n-resize', transform: 'translateX(-50%)' } |
|
38 |
}, |
|
39 |
{ |
|
40 |
position: '右上角', |
|
41 |
types: [CONTROL_TYPE_ENUM.TOP, CONTROL_TYPE_ENUM.WIDTH, CONTROL_TYPE_ENUM.HEIGHT], |
|
42 |
style: { right: '-5px', top: '-5px', cursor: 'nesw-resize' } |
|
43 |
}, |
|
44 |
{ |
|
45 |
position: '右侧中间', |
|
46 |
types: [CONTROL_TYPE_ENUM.WIDTH], |
|
47 |
style: { right: '-5px', top: '50%', cursor: 'e-resize', transform: 'translateX(-50%)' } |
|
48 |
}, |
|
49 |
{ |
|
50 |
position: '右下角', |
|
51 |
types: [CONTROL_TYPE_ENUM.WIDTH, CONTROL_TYPE_ENUM.HEIGHT], |
|
52 |
style: { right: '-5px', bottom: '-5px', cursor: 'nwse-resize' } |
|
53 |
}, |
|
54 |
{ |
|
55 |
position: '下方中间', |
|
56 |
types: [CONTROL_TYPE_ENUM.HEIGHT], |
|
57 |
style: { left: '50%', bottom: '-5px', cursor: 's-resize', transform: 'translateX(-50%)' } |
|
58 |
}, |
|
59 |
{ |
|
60 |
position: '左下角', |
|
61 |
types: [CONTROL_TYPE_ENUM.LEFT, CONTROL_TYPE_ENUM.WIDTH, CONTROL_TYPE_ENUM.HEIGHT], |
|
62 |
style: { left: '-5px', bottom: '-5px', cursor: 'nesw-resize' } |
|
63 |
}, |
|
64 |
{ |
|
65 |
position: '左侧中间', |
|
66 |
types: [CONTROL_TYPE_ENUM.LEFT, CONTROL_TYPE_ENUM.WIDTH], |
|
67 |
style: { left: '-5px', top: '50%', cursor: 'w-resize', transform: 'translateX(-50%)' } |
|
68 |
} |
|
69 |
] as ControlDot[] |
|
70 |
|
|
71 |
//region 热区的缩放 |
|
72 |
// 热区的缩放比例 |
|
73 |
export const HOT_ZONE_SCALE_RATE = 2 |
|
74 |
// 缩小:缩回适合手机屏幕的大小 |
|
75 |
export const zoomOut = (list?: HotZoneItemProperty[]) => { |
|
76 |
return ( |
|
77 |
list?.map((hotZone) => ({ |
|
78 |
...hotZone, |
|
79 |
left: (hotZone.left /= HOT_ZONE_SCALE_RATE), |
|
80 |
top: (hotZone.top /= HOT_ZONE_SCALE_RATE), |
|
81 |
width: (hotZone.width /= HOT_ZONE_SCALE_RATE), |
|
82 |
height: (hotZone.height /= HOT_ZONE_SCALE_RATE) |
|
83 |
})) || [] |
|
84 |
) |
|
85 |
} |
|
86 |
// 放大:作用是为了方便在电脑屏幕上编辑 |
|
87 |
export const zoomIn = (list?: HotZoneItemProperty[]) => { |
|
88 |
return ( |
|
89 |
list?.map((hotZone) => ({ |
|
90 |
...hotZone, |
|
91 |
left: (hotZone.left *= HOT_ZONE_SCALE_RATE), |
|
92 |
top: (hotZone.top *= HOT_ZONE_SCALE_RATE), |
|
93 |
width: (hotZone.width *= HOT_ZONE_SCALE_RATE), |
|
94 |
height: (hotZone.height *= HOT_ZONE_SCALE_RATE) |
|
95 |
})) || [] |
|
96 |
) |
|
97 |
} |
|
98 |
//endregion |
|
99 |
|
|
100 |
/** |
|
101 |
* 封装热区拖拽 |
|
102 |
* |
|
103 |
* 注:为什么不使用vueuse的useDraggable。在本场景下,其使用方式比较复杂 |
|
104 |
* @param hotZone 热区 |
|
105 |
* @param downEvent 鼠标按下事件 |
|
106 |
* @param callback 回调函数 |
|
107 |
*/ |
|
108 |
export const useDraggable = ( |
|
109 |
hotZone: HotZoneItemProperty, |
|
110 |
downEvent: MouseEvent, |
|
111 |
callback: ( |
|
112 |
left: number, |
|
113 |
top: number, |
|
114 |
width: number, |
|
115 |
height: number, |
|
116 |
moveWidth: number, |
|
117 |
moveHeight: number |
|
118 |
) => void |
|
119 |
) => { |
|
120 |
// 阻止事件冒泡 |
|
121 |
downEvent.stopPropagation() |
|
122 |
|
|
123 |
// 移动前的鼠标坐标 |
|
124 |
const { clientX: startX, clientY: startY } = downEvent |
|
125 |
// 移动前的热区坐标、大小 |
|
126 |
const { left, top, width, height } = hotZone |
|
127 |
|
|
128 |
// 监听鼠标移动 |
|
129 |
document.onmousemove = (e) => { |
|
130 |
// 移动宽度 |
|
131 |
const moveWidth = e.clientX - startX |
|
132 |
// 移动高度 |
|
133 |
const moveHeight = e.clientY - startY |
|
134 |
// 移动回调 |
|
135 |
callback(left, top, width, height, moveWidth, moveHeight) |
|
136 |
} |
|
137 |
|
|
138 |
// 松开鼠标后,结束拖拽 |
|
139 |
document.onmouseup = () => { |
|
140 |
document.onmousemove = null |
|
141 |
document.onmouseup = null |
|
142 |
} |
|
143 |
} |