From 49ebadd748157cb814a7a203f449a0feb2ed23c3 Mon Sep 17 00:00:00 2001 From: owen Date: Sun, 12 Nov 2023 19:29:24 +0800 Subject: [PATCH] =?UTF-8?q?=E8=90=A5=E9=94=80=EF=BC=9A=E9=80=82=E9=85=8D?= =?UTF-8?q?=E5=95=86=E5=9F=8E=E8=A3=85=E4=BF=AE=E7=BB=84=E4=BB=B6=E3=80=90?= =?UTF-8?q?=E5=B9=BF=E5=91=8A=E9=AD=94=E6=96=B9=E3=80=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/ComponentContainer.vue | 7 + .../components/mobile/Carousel/index.vue | 2 +- .../components/mobile/MagicCube/config.ts | 48 ++++ .../components/mobile/MagicCube/index.vue | 73 +++++ .../components/mobile/MagicCube/property.vue | 76 +++++ src/components/DiyEditor/util.ts | 2 +- src/components/MagicCubeEditor/index.vue | 270 ++++++++++++++++++ src/components/MagicCubeEditor/util.ts | 72 +++++ .../mall/promotion/diy/template/decorate.vue | 1 - 9 files changed, 548 insertions(+), 3 deletions(-) create mode 100644 src/components/DiyEditor/components/mobile/MagicCube/config.ts create mode 100644 src/components/DiyEditor/components/mobile/MagicCube/index.vue create mode 100644 src/components/DiyEditor/components/mobile/MagicCube/property.vue create mode 100644 src/components/MagicCubeEditor/index.vue create mode 100644 src/components/MagicCubeEditor/util.ts diff --git a/src/components/DiyEditor/components/ComponentContainer.vue b/src/components/DiyEditor/components/ComponentContainer.vue index 6c6463f2..2d8c2f13 100644 --- a/src/components/DiyEditor/components/ComponentContainer.vue +++ b/src/components/DiyEditor/components/ComponentContainer.vue @@ -135,8 +135,11 @@ $toolbar-position: -55px; position: relative; z-index: 1; } + /* 用于包裹组件,为组件提供 组件名称、工具栏、边框等样式 */ .component-wrap { z-index: 0; + // 不可以被点击 + // component-wrap会遮挡组件,导致组件不能触发鼠标事件,所以这里要先禁用,然后在组件名称、工具栏上开启。 pointer-events: none; display: block; position: absolute; @@ -146,6 +149,8 @@ $toolbar-position: -55px; height: 100%; /* 左侧:组件名称 */ .component-name { + // 可以被点击 + pointer-events: auto; display: block; position: absolute; width: 80px; @@ -174,6 +179,8 @@ $toolbar-position: -55px; } /* 右侧:组件操作工具栏 */ .component-toolbar { + // 可以被点击 + pointer-events: auto; display: none; position: absolute; top: 0; diff --git a/src/components/DiyEditor/components/mobile/Carousel/index.vue b/src/components/DiyEditor/components/mobile/Carousel/index.vue index 940a9a56..360b4a49 100644 --- a/src/components/DiyEditor/components/mobile/Carousel/index.vue +++ b/src/components/DiyEditor/components/mobile/Carousel/index.vue @@ -21,7 +21,7 @@
{{ currentIndex }} / {{ property.items.length }}
diff --git a/src/components/DiyEditor/components/mobile/MagicCube/config.ts b/src/components/DiyEditor/components/mobile/MagicCube/config.ts new file mode 100644 index 00000000..ce5d21a3 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/MagicCube/config.ts @@ -0,0 +1,48 @@ +import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util' + +/** 广告魔方属性 */ +export interface MagicCubeProperty { + // 上圆角 + borderRadiusTop: number + // 下圆角 + borderRadiusBottom: number + // 间隔 + space: number + // 导航菜单列表 + list: MagicCubeItemProperty[] + // 组件样式 + style: ComponentStyle +} +/** 广告魔方项目属性 */ +export interface MagicCubeItemProperty { + // 图标链接 + imgUrl: string + // 链接 + url: string + // 宽 + width: number + // 高 + height: number + // 上 + top: number + // 左 + left: number +} + +// 定义组件 +export const component = { + id: 'MagicCube', + name: '广告魔方', + icon: 'fluent:puzzle-cube-piece-20-filled', + property: { + borderRadiusTop: 0, + borderRadiusBottom: 0, + space: 0, + list: [], + style: { + bgType: 'color', + bgColor: '#fff', + marginBottom: 8 + } as ComponentStyle + } +} as DiyComponent diff --git a/src/components/DiyEditor/components/mobile/MagicCube/index.vue b/src/components/DiyEditor/components/mobile/MagicCube/index.vue new file mode 100644 index 00000000..48fb6c75 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/MagicCube/index.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/src/components/DiyEditor/components/mobile/MagicCube/property.vue b/src/components/DiyEditor/components/mobile/MagicCube/property.vue new file mode 100644 index 00000000..57c0af79 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/MagicCube/property.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/components/DiyEditor/util.ts b/src/components/DiyEditor/util.ts index 5ae0a93f..8f8c2c0c 100644 --- a/src/components/DiyEditor/util.ts +++ b/src/components/DiyEditor/util.ts @@ -105,7 +105,7 @@ export const PAGE_LIBS = [ { name: '图文组件', extended: true, - components: ['ImageBar', 'Carousel', 'TitleBar', 'VideoPlayer', 'Divider'] + components: ['ImageBar', 'Carousel', 'TitleBar', 'VideoPlayer', 'Divider', 'MagicCube'] }, { name: '商品组件', extended: true, components: ['ProductCard'] }, { diff --git a/src/components/MagicCubeEditor/index.vue b/src/components/MagicCubeEditor/index.vue new file mode 100644 index 00000000..26ea179d --- /dev/null +++ b/src/components/MagicCubeEditor/index.vue @@ -0,0 +1,270 @@ + + + diff --git a/src/components/MagicCubeEditor/util.ts b/src/components/MagicCubeEditor/util.ts new file mode 100644 index 00000000..e7c64658 --- /dev/null +++ b/src/components/MagicCubeEditor/util.ts @@ -0,0 +1,72 @@ +// 坐标点 +export interface Point { + x: number + y: number +} + +// 矩形 +export interface Rect { + // 左上角 X 轴坐标 + left: number + // 左上角 Y 轴坐标 + top: number + // 右下角 X 轴坐标 + right: number + // 右下角 Y 轴坐标 + bottom: number + // 矩形宽度 + width: number + // 矩形高度 + height: number +} + +/** + * 判断两个矩形是否重叠 + * @param a 矩形 A + * @param b 矩形 B + */ +export const isOverlap = (a: Rect, b: Rect): boolean => { + return ( + a.left < b.left + b.width && + a.left + a.width > b.left && + a.top < b.top + b.height && + a.height + a.top > b.top + ) +} +/** + * 检查坐标点是否在矩形内 + * @param hotArea 矩形 + * @param point 坐标 + */ +export const isContains = (hotArea: Rect, point: Point): boolean => { + return ( + point.x >= hotArea.left && + point.x < hotArea.right && + point.y >= hotArea.top && + point.y < hotArea.bottom + ) +} + +/** + * 在两个坐标点中间,创建一个矩形 + * + * 存在以下情况: + * 1. 两个坐标点是同一个位置,只占一个位置的正方形,宽高都为 1 + * 2. X 轴坐标相同,只占一行的矩形,高度为 1 + * 3. Y 轴坐标相同,只占一列的矩形,宽度为 1 + * 4. 多行多列的矩形 + * + * @param a 坐标点一 + * @param b 坐标点二 + */ +export const createRect = (a: Point, b: Point): Rect => { + // 计算矩形的范围 + const [left, left2] = [a.x, b.x].sort() + const [top, top2] = [a.y, b.y].sort() + const right = left2 + 1 + const bottom = top2 + 1 + const height = bottom - top + const width = right - left + + return { left, right, top, bottom, height, width } +} diff --git a/src/views/mall/promotion/diy/template/decorate.vue b/src/views/mall/promotion/diy/template/decorate.vue index 8304088a..f2ae7bc0 100644 --- a/src/views/mall/promotion/diy/template/decorate.vue +++ b/src/views/mall/promotion/diy/template/decorate.vue @@ -78,7 +78,6 @@ const handleTemplateItemChange = () => { currentFormData.value = formData.value!.pages.find( (page: DiyPageApi.DiyPageVO) => page.name === templateItems[selectedTemplateItem.value].name ) - console.log(currentFormData.value) } // 提交表单