From cc804f0749beb1b12405af9481d20dbbc6124799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BB=9D=E5=B0=98?= <237809796@qq.com> Date: Mon, 24 Aug 2026 02:13:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D:=20=E6=BC=94=E7=A4=BA?= =?UTF-8?q?=E5=85=83=E7=B4=A0=E6=B6=88=E5=A4=B1+=E7=94=BB=E5=B8=83?= =?UTF-8?q?=E9=94=99=E4=BD=8D+PDF=E6=A8=AA=E7=89=88=E5=AF=BC=E5=87=BA+?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E6=A0=8F=E4=BF=A1=E6=81=AF=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/editor/Canvas.vue | 52 ++++++-- src/components/editor/Toolbar.vue | 151 +++++++++++++++++++++--- src/components/modals/PrintModal.vue | 33 +++--- src/components/modals/TemplateModal.vue | 75 +++++++++--- src/styles/base.css | 26 ++++ src/styles/present.css | 8 +- 6 files changed, 292 insertions(+), 53 deletions(-) diff --git a/src/components/editor/Canvas.vue b/src/components/editor/Canvas.vue index 7b99ccd..8f15084 100644 --- a/src/components/editor/Canvas.vue +++ b/src/components/editor/Canvas.vue @@ -9,17 +9,30 @@ import { useEditor } from '../../composables/useEditor' import ElementView from './ElementView.vue' const canvasRef = ref() -const canvasFrameRef = ref() +const canvasFrameRef = ref() // 注意:绑定 .canvas-frame(不含 stage 的 padding),scale 以它为基准 const { - drag, editing, + drag, marquee, editing, onCanvasMouseDown, onMouseMove, onMouseUp, onContentEditableFocus } = useEditor() const slide = computed(() => store.currentSlide.value) const selectedId = computed(() => store.selectedId.value) +const selectedIds = computed(() => store.selectedIds.value || []) const HANDLES = ['tl', 'tm', 'tr', 'lm', 'rm', 'bl', 'bm', 'br'] +/** 框选矩形样式(% → CSS) */ +const marqueeBox = computed(() => { + const m = marquee.value + if (!m) return null + return { + left: Math.min(m.x0, m.x1) + '%', + top: Math.min(m.y0, m.y1) + '%', + width: Math.abs(m.x1 - m.x0) + '%', + height: Math.abs(m.y1 - m.y0) + '%' + } +}) + function fitCanvas() { if (!canvasFrameRef.value || !canvasRef.value) return const rect = canvasFrameRef.value.getBoundingClientRect() @@ -53,24 +66,42 @@ function liveBox(elId: string) { return null } +/** 多选组拖拽中各元素的实时位置 */ +function liveMultiBox(elId: string) { + const d = drag.value + if (d && d.mode === 'multi-move' && d.multiResult) { + const r = d.multiResult.find(t => t.id === elId) + if (r) return { left: r.x + '%', top: r.y + '%' } + } + return null +} + const onResize = () => fitCanvas() +/** 监听 frame 尺寸:v-show 隐藏→显示、窗口缩放、布局变化都会触发(隐藏时 rect=0,onMounted 的 rAF 会空跑) */ +let frameObserver: ResizeObserver | null = null + onMounted(() => { window.addEventListener('resize', onResize) document.addEventListener('mousemove', onMouseMove) document.addEventListener('mouseup', onMouseUp) requestAnimationFrame(fitCanvas) + if (typeof ResizeObserver !== 'undefined' && canvasFrameRef.value) { + frameObserver = new ResizeObserver(() => fitCanvas()) + frameObserver.observe(canvasFrameRef.value) + } }) onUnmounted(() => { window.removeEventListener('resize', onResize) document.removeEventListener('mousemove', onMouseMove) document.removeEventListener('mouseup', onMouseUp) + if (frameObserver) { frameObserver.disconnect(); frameObserver = null } }) + + diff --git a/src/components/modals/PrintModal.vue b/src/components/modals/PrintModal.vue index 2f7f55e..1cf6be5 100644 --- a/src/components/modals/PrintModal.vue +++ b/src/components/modals/PrintModal.vue @@ -1,30 +1,32 @@