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