From cda5413fd134228cef78c9d1196619d9616e101e Mon Sep 17 00:00:00 2001 From: moonszhang Date: Thu, 22 Feb 2024 19:54:53 +0800 Subject: [PATCH] =?UTF-8?q?refactor(editor):=20floatbox=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=85=AC=E5=85=B1=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/editor/src/hooks/use-float-box.ts | 149 ++++-------------- .../editor/src/layouts/sidebar/Sidebar.vue | 67 +++----- packages/editor/src/theme/floatbox.scss | 48 ------ packages/editor/src/theme/sidebar.scss | 16 ++ packages/editor/src/theme/theme.scss | 1 - 5 files changed, 73 insertions(+), 208 deletions(-) delete mode 100644 packages/editor/src/theme/floatbox.scss diff --git a/packages/editor/src/hooks/use-float-box.ts b/packages/editor/src/hooks/use-float-box.ts index b6cfad17..f65e7047 100644 --- a/packages/editor/src/hooks/use-float-box.ts +++ b/packages/editor/src/hooks/use-float-box.ts @@ -1,124 +1,38 @@ -import { computed, ComputedRef, inject, nextTick, ref, watch } from 'vue'; -import Moveable from 'moveable'; - -import { type Services } from '@editor/type'; +import { computed, ComputedRef, ref, watch } from 'vue'; export const useFloatBox = (slideKeys: ComputedRef) => { - const services = inject('services'); - const moveable = ref(); - const floatBox = ref(); - - const floatBoxStates = computed(() => services?.uiService.get('floatBox')); - - const curKey = ref(''); - const target = computed(() => - floatBox.value - ? floatBox.value.find((item) => item.classList.contains(`m-editor-float-box-${curKey.value}`)) - : undefined, + const floatBoxStates = ref<{ + [key in (typeof slideKeys.value)[number]]: { + status: boolean; + top: number; + left: number; + }; + }>( + slideKeys.value.reduce( + (total, cur) => ({ + ...total, + [cur]: { + status: false, + top: 0, + left: 0, + }, + }), + {}, + ), ); const showingBoxKeys = computed(() => - [...(floatBoxStates.value?.keys() ?? [])].filter((key) => floatBoxStates.value?.get(key)?.status), + Object.keys(floatBoxStates.value).filter((key) => floatBoxStates.value[key].status), ); - const isDraging = ref(false); - const showFloatBox = async (key: string) => { - const curBoxStatus = floatBoxStates.value?.get(curKey.value)?.status; - if (curKey.value === key && curBoxStatus) return; - curKey.value = key; - setSlideState(key, { - zIndex: getMaxZIndex() + 1, - status: true, - }); - - await nextTick(); - if (moveable.value) { - moveable.value.target = target.value; - moveable.value.dragTarget = getDragTarget(); - moveable.value.updateRect(); - } else { - initFloatBoxMoveable(); - } - }; - - const setSlideState = (key: string, data: Record) => { - const slideState = floatBoxStates.value?.get(key); - if (!slideState) return; - floatBoxStates.value?.set(key, { - ...slideState, - ...data, - }); - }; - - const getDragTarget = (key?: string) => `.m-editor-float-box-header-${key ?? curKey.value}`; - - const closeFloatBox = (key: string) => { - setSlideState(key, { - status: false, - }); - - // 如果只有一个,关掉后需要销毁moveable实例 - if (!floatBoxStates.value?.values) return; - const keys = [...floatBoxStates.value?.keys()]; - const values = [...floatBoxStates.value?.values()]; - const lastFloatBoxLen = values.filter((state) => state.status).length; - if (lastFloatBoxLen === 0) { - moveable.value?.destroy(); - moveable.value = undefined; - return; - } - - // 如果关掉的 box 是最大的,需要选中下面的一层 - if (key === curKey.value) { - // 查找显示的最大 zIndex 对应的 index - const zIndexList = values.filter((item) => item.status).map((item) => item.zIndex); - const maxZIndex = Math.max(...zIndexList); - const key = keys.find((key) => floatBoxStates.value?.get(key)?.zIndex === maxZIndex); - if (!key) return; - showFloatBox(key); - } - }; - - const getMaxZIndex = () => { - if (!floatBoxStates.value?.values()) return 0; - const list = [...floatBoxStates.value?.values()].map((state) => state.zIndex); - return Math.max(...list) ?? 0; - }; - - const initFloatBoxMoveable = () => { - const dragTarget = getDragTarget(); - moveable.value = new Moveable(document.body, { - target: target.value, - draggable: true, - resizable: true, - edge: true, - keepRatio: false, - origin: false, - snappable: true, - dragTarget, - dragTargetSelf: false, - linePadding: 10, - controlPadding: 10, - elementGuidelines: [...(floatBoxStates.value?.keys() ?? [])].map((key) => getDragTarget(key)), - bounds: { left: 0, top: 0, right: 0, bottom: 0, position: 'css' }, - }); - moveable.value.on('drag', (e) => { - e.target.style.transform = e.transform; - }); - moveable.value.on('resize', (e) => { - e.target.style.width = `${e.width}px`; - e.target.style.height = `${e.height}px`; - e.target.style.transform = e.drag.transform; - }); - }; - + const dragstartHandler = () => (isDraging.value = true); const dragendHandler = (key: string, e: DragEvent) => { - setSlideState(key, { + floatBoxStates.value[key] = { left: e.clientX, top: e.clientY, - }); - showFloatBox(key); + status: true, + }; isDraging.value = false; }; @@ -127,13 +41,17 @@ export const useFloatBox = (slideKeys: ComputedRef) => { e.preventDefault(); }); - const dragstartHandler = () => (isDraging.value = true); - - // 监听 slide 长度变化,更新 ui serice map watch( () => slideKeys.value, () => { - services?.uiService.setFloatBox(slideKeys.value); + for (const key in slideKeys.value) { + if (floatBoxStates.value[key]) continue; + floatBoxStates.value[key] = { + status: false, + top: 0, + left: 0, + }; + } }, { deep: true, @@ -142,12 +60,9 @@ export const useFloatBox = (slideKeys: ComputedRef) => { ); return { - showFloatBox, - closeFloatBox, dragstartHandler, dragendHandler, floatBoxStates, - floatBox, showingBoxKeys, }; }; diff --git a/packages/editor/src/layouts/sidebar/Sidebar.vue b/packages/editor/src/layouts/sidebar/Sidebar.vue index 417a7ddd..3f969e88 100644 --- a/packages/editor/src/layouts/sidebar/Sidebar.vue +++ b/packages/editor/src/layouts/sidebar/Sidebar.vue @@ -4,7 +4,7 @@
-
-
+ -
-
{{ config.text }}
- -
-
- -
-
-
+ + +