houzhongjian
2024-08-08 820397e43a0b64d35c6d31d2a55475061438593b
提交 | 用户 | 时间
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 }