diff --git a/packages/editor/src/layouts/workspace/viewer/Stage.vue b/packages/editor/src/layouts/workspace/viewer/Stage.vue index f77842c4..67e7665d 100644 --- a/packages/editor/src/layouts/workspace/viewer/Stage.vue +++ b/packages/editor/src/layouts/workspace/viewer/Stage.vue @@ -45,7 +45,8 @@ import { computed, inject, markRaw, nextTick, onBeforeUnmount, onMounted, ref, t import { cloneDeep } from 'lodash-es'; import type { MApp, MContainer } from '@tmagic/schema'; -import StageCore, { calcValueByFontsize, getOffset, Runtime } from '@tmagic/stage'; +import StageCore, { getOffset, Runtime } from '@tmagic/stage'; +import { calcValueByFontsize } from '@tmagic/utils'; import ScrollViewer from '@editor/components/ScrollViewer.vue'; import { useStage } from '@editor/hooks/use-stage'; @@ -223,18 +224,18 @@ const dropHandler = async (e: DragEvent) => { top = e.clientY - containerRect.top + scrollTop; left = e.clientX - containerRect.left + scrollLeft; - if (parentEl && doc) { + if (parentEl) { const { left: parentLeft, top: parentTop } = getOffset(parentEl); - left = left - calcValueByFontsize(doc, parentLeft) * zoom.value; - top = top - calcValueByFontsize(doc, parentTop) * zoom.value; + left = left - parentLeft * zoom.value; + top = top - parentTop * zoom.value; } } config.data.style = { ...style, position, - top: top / zoom.value, - left: left / zoom.value, + top: calcValueByFontsize(doc, top / zoom.value), + left: calcValueByFontsize(doc, left / zoom.value), }; config.data.inputEvent = e; diff --git a/packages/editor/src/services/editor.ts b/packages/editor/src/services/editor.ts index a94889f0..2ef0fb57 100644 --- a/packages/editor/src/services/editor.ts +++ b/packages/editor/src/services/editor.ts @@ -23,7 +23,7 @@ import { Writable } from 'type-fest'; import { DepTargetType } from '@tmagic/dep'; import type { Id, MApp, MComponent, MContainer, MNode, MPage, MPageFragment } from '@tmagic/schema'; import { NodeType } from '@tmagic/schema'; -import { getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils'; +import { calcValueByFontsize, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils'; import BaseService from '@editor/services//BaseService'; import propsService from '@editor/services//props'; @@ -741,7 +741,7 @@ class Editor extends BaseService { const el = doc.getElementById(`${node.id}`); const parentEl = layout === Layout.FIXED ? doc.body : el?.offsetParent; if (parentEl && el) { - node.style.left = (parentEl.clientWidth - el.clientWidth) / 2; + node.style.left = calcValueByFontsize(doc, (parentEl.clientWidth - el.clientWidth) / 2); node.style.right = ''; } } else if (parent.style && isNumber(parent.style?.width) && isNumber(node.style?.width)) { diff --git a/packages/editor/src/utils/content-menu.ts b/packages/editor/src/utils/content-menu.ts index 786ce421..27a0ea93 100644 --- a/packages/editor/src/utils/content-menu.ts +++ b/packages/editor/src/utils/content-menu.ts @@ -2,7 +2,7 @@ import { computed, markRaw, Ref } from 'vue'; import { CopyDocument, Delete, DocumentCopy } from '@element-plus/icons-vue'; import { Id, MContainer, NodeType } from '@tmagic/schema'; -import { isPage, isPageFragment } from '@tmagic/utils'; +import { calcValueByFontsize, isPage, isPageFragment } from '@tmagic/utils'; import ContentMenu from '@editor/components/ContentMenu.vue'; import type { MenuButton, Services } from '@editor/type'; @@ -46,8 +46,12 @@ export const usePasteMenu = (menu?: Ref | undef const stage = services?.editorService?.get('stage'); const rect = menu.value.$el.getBoundingClientRect(); const parentRect = stage?.container?.getBoundingClientRect(); - const initialLeft = (rect.left || 0) - (parentRect?.left || 0); - const initialTop = (rect.top || 0) - (parentRect?.top || 0); + const initialLeft = + calcValueByFontsize(stage?.renderer.getDocument(), (rect.left || 0) - (parentRect?.left || 0)) / + services.uiService.get('zoom'); + const initialTop = + calcValueByFontsize(stage?.renderer.getDocument(), (rect.top || 0) - (parentRect?.top || 0)) / + services.uiService.get('zoom'); services?.editorService?.paste({ left: initialLeft, top: initialTop }); } else { services?.editorService?.paste(); diff --git a/packages/editor/src/utils/editor.ts b/packages/editor/src/utils/editor.ts index 942b4afd..2d482fe9 100644 --- a/packages/editor/src/utils/editor.ts +++ b/packages/editor/src/utils/editor.ts @@ -21,7 +21,7 @@ import serialize from 'serialize-javascript'; import type { Id, MApp, MContainer, MNode, MPage, MPageFragment } from '@tmagic/schema'; import { NodeType } from '@tmagic/schema'; import type StageCore from '@tmagic/stage'; -import { getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils'; +import { calcValueByFontsize, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils'; import { Layout } from '@editor/type'; export const COPY_STORAGE_KEY = '$MagicEditorCopyData'; @@ -106,13 +106,16 @@ const getMiddleTop = (node: MNode, parentNode: MNode, stage: StageCore | null) = } const { height: parentHeight } = parentNode.style; - + // wrapperHeight 是未 calcValue的高度, 所以要将其calcValueByFontsize一下, 否则在pad or pc端计算的结果有误 + const { scrollTop = 0, wrapperHeight } = stage.mask; + const wrapperHeightDeal = calcValueByFontsize(stage.renderer.getDocument()!, wrapperHeight); + const scrollTopDeal = calcValueByFontsize(stage.renderer.getDocument()!, scrollTop); if (isPage(parentNode)) { - const { scrollTop = 0, wrapperHeight } = stage.mask; - return (wrapperHeight - height) / 2 + scrollTop; + return (wrapperHeightDeal - height) / 2 + scrollTopDeal; } - return (parentHeight - height) / 2; + // 如果容器的元素高度大于当前视口高度的2倍, 添加的元素居中位置也会看不见, 所以要取最小值计算 + return (Math.min(parentHeight, wrapperHeightDeal) - height) / 2; }; export const getInitPositionStyle = (style: Record = {}, layout: Layout) => { @@ -238,8 +241,12 @@ export const fixNodeLeft = (config: MNode, parent: MContainer, doc?: Document) = const parentEl = doc.getElementById(`${parent.id}`); const left = Number(config.style?.left) || 0; - if (el && parentEl && el.offsetWidth + left > parentEl.offsetWidth) { - return parentEl.offsetWidth - el.offsetWidth; + if (el && parentEl) { + const calcParentOffsetWidth = calcValueByFontsize(doc, parentEl.offsetWidth); + const calcElOffsetWidth = calcValueByFontsize(doc, el.offsetWidth); + if (calcElOffsetWidth + left > calcParentOffsetWidth) { + return calcParentOffsetWidth - calcElOffsetWidth; + } } return config.style.left; diff --git a/packages/stage/src/DragResizeHelper.ts b/packages/stage/src/DragResizeHelper.ts index 571e223d..9a4ce8b5 100644 --- a/packages/stage/src/DragResizeHelper.ts +++ b/packages/stage/src/DragResizeHelper.ts @@ -32,10 +32,12 @@ import type { } from 'moveable'; import MoveableHelper from 'moveable-helper'; +import { calcValueByFontsize } from '@tmagic/utils'; + import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, Mode, ZIndex } from './const'; import TargetShadow from './TargetShadow'; import type { DragResizeHelperConfig, Rect, TargetElement } from './types'; -import { calcValueByFontsize, getAbsolutePosition, getBorderWidth, getMarginValue, getOffset } from './util'; +import { getAbsolutePosition, getBorderWidth, getMarginValue, getOffset } from './util'; /** * 拖拽/改变大小等操作发生时,moveable会抛出各种状态事件,DragResizeHelper负责响应这些事件,对目标节点target和拖拽节点targetShadow进行修改; diff --git a/packages/stage/src/util.ts b/packages/stage/src/util.ts index d41c9925..10a2c264 100644 --- a/packages/stage/src/util.ts +++ b/packages/stage/src/util.ts @@ -161,17 +161,6 @@ export const addSelectedClassName = (el: Element, doc: Document) => { }); }; -export const calcValueByFontsize = (doc: Document, value: number) => { - const { fontSize } = doc.documentElement.style; - - if (fontSize) { - const times = globalThis.parseFloat(fontSize) / 100; - return Number((value / times).toFixed(2)); - } - - return value; -}; - /** * 下移组件位置 * @param {number} deltaTop 偏移量 diff --git a/packages/utils/src/dom.ts b/packages/utils/src/dom.ts index 814702fe..25f3a189 100644 --- a/packages/utils/src/dom.ts +++ b/packages/utils/src/dom.ts @@ -110,3 +110,15 @@ export const createDiv = ({ className, cssText }: { className: string; cssText: }; export const getDocument = () => globalThis.document; + +export const calcValueByFontsize = (doc: Document | undefined, value: number) => { + if (!doc) return value; + const { fontSize } = doc.documentElement.style; + + if (fontSize) { + const times = globalThis.parseFloat(fontSize) / 100; + return Number((value / times).toFixed(2)); + } + + return value; +};