diff --git a/src/components/AppLinkInput/AppLinkSelectDialog.vue b/src/components/AppLinkInput/AppLinkSelectDialog.vue index a536ac13..63f19662 100644 --- a/src/components/AppLinkInput/AppLinkSelectDialog.vue +++ b/src/components/AppLinkInput/AppLinkSelectDialog.vue @@ -29,10 +29,11 @@ :key="appLinkIndex" :content="appLink.path" placement="bottom" + :show-after="300" > {{ appLink.name }} @@ -63,7 +64,7 @@ diff --git a/src/components/DiyEditor/components/mobile/HotZone/components/HotZoneEditDialog/controller.ts b/src/components/DiyEditor/components/mobile/HotZone/components/HotZoneEditDialog/controller.ts new file mode 100644 index 00000000..a7bd7622 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/HotZone/components/HotZoneEditDialog/controller.ts @@ -0,0 +1,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 + } +} diff --git a/src/components/DiyEditor/components/mobile/HotZone/components/HotZoneEditDialog/index.vue b/src/components/DiyEditor/components/mobile/HotZone/components/HotZoneEditDialog/index.vue new file mode 100644 index 00000000..39250572 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/HotZone/components/HotZoneEditDialog/index.vue @@ -0,0 +1,236 @@ + + + + + diff --git a/src/components/DiyEditor/components/mobile/HotZone/config.ts b/src/components/DiyEditor/components/mobile/HotZone/config.ts new file mode 100644 index 00000000..9dcebcc2 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/HotZone/config.ts @@ -0,0 +1,42 @@ +import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util' + +/** 热区属性 */ +export interface HotZoneProperty { + // 图片地址 + imgUrl: string + // 导航菜单列表 + list: HotZoneItemProperty[] + // 组件样式 + style: ComponentStyle +} +/** 热区项目属性 */ +export interface HotZoneItemProperty { + // 链接的名称 + name: string + // 链接 + url: string + // 宽 + width: number + // 高 + height: number + // 上 + top: number + // 左 + left: number +} + +// 定义组件 +export const component = { + id: 'HotZone', + name: '热区', + icon: 'tabler:hand-click', + property: { + imgUrl: '', + list: [] as HotZoneItemProperty[], + style: { + bgType: 'color', + bgColor: '#fff', + marginBottom: 8 + } as ComponentStyle + } +} as DiyComponent diff --git a/src/components/DiyEditor/components/mobile/HotZone/index.vue b/src/components/DiyEditor/components/mobile/HotZone/index.vue new file mode 100644 index 00000000..3a9b842e --- /dev/null +++ b/src/components/DiyEditor/components/mobile/HotZone/index.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/components/DiyEditor/components/mobile/HotZone/property.vue b/src/components/DiyEditor/components/mobile/HotZone/property.vue new file mode 100644 index 00000000..495cbdce --- /dev/null +++ b/src/components/DiyEditor/components/mobile/HotZone/property.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/src/components/DiyEditor/components/mobile/MenuSwiper/index.vue b/src/components/DiyEditor/components/mobile/MenuSwiper/index.vue index 6ae6439c..f8e2bbc6 100644 --- a/src/components/DiyEditor/components/mobile/MenuSwiper/index.vue +++ b/src/components/DiyEditor/components/mobile/MenuSwiper/index.vue @@ -28,7 +28,7 @@ - +