From 4ad7faa1c99a0e3eca4fb5c87c79e7c7facdc574 Mon Sep 17 00:00:00 2001 From: zxc <1171051090@qq.com> Date: Sun, 17 May 2026 13:58:16 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E8=A3=81=E5=89=AA?= =?UTF-8?q?=E5=90=8E=E7=9A=84=E5=9B=BE=E7=89=87=E6=9B=BF=E6=8D=A2=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useImageHandler.ts | 72 +++++++++++++++++++ .../FloatingToolbar/ImageToolbar.vue | 46 ++---------- .../ElementStylePanel/ImageStylePanel.vue | 37 +--------- 3 files changed, 78 insertions(+), 77 deletions(-) create mode 100644 src/hooks/useImageHandler.ts diff --git a/src/hooks/useImageHandler.ts b/src/hooks/useImageHandler.ts new file mode 100644 index 00000000..13ac1b99 --- /dev/null +++ b/src/hooks/useImageHandler.ts @@ -0,0 +1,72 @@ +import { type Ref } from 'vue' +import { storeToRefs } from 'pinia' +import { useMainStore, useSlidesStore } from '@/store' +import type { PPTImageElement } from '@/types/slides' +import { getImageDataURL, getImageSize } from '@/utils/image' +import useHistorySnapshot from '@/hooks/useHistorySnapshot' + +export default () => { + const mainStore = useMainStore() + const slidesStore = useSlidesStore() + const { handleElement, handleElementId } = storeToRefs(mainStore) + + const handleImageElement = handleElement as Ref + + const { addHistorySnapshot } = useHistorySnapshot() + + const replaceImage = (files: FileList) => { + const imageFile = files[0] + const imageElement = handleImageElement.value + const imageElementId = handleElementId.value + if (!imageFile || !imageElement || imageElement.type !== 'image' || !imageElementId) return + + getImageDataURL(imageFile).then(dataURL => { + const originWidth = imageElement.width + const originHeight = imageElement.height + const originLeft = imageElement.left + const originTop = imageElement.top + const centerX = originLeft + originWidth / 2 + const centerY = originTop + originHeight / 2 + + getImageSize(dataURL).then(({ width, height }) => { + const h = originHeight + const w = width * (originHeight / height) + const l = centerX - w / 2 + const t = centerY - h / 2 + + const clip = imageElement.clip + if (clip && clip.shape !== 'rect') { + slidesStore.updateElement({ + id: imageElementId, + props: { + src: dataURL, + width: w, + height: h, + left: l, + top: t, + clip: { + ...clip, + range: [[0, 0], [100, 100]], + }, + }, + }) + } + else { + slidesStore.removeElementProps({ + id: imageElementId, + propName: 'clip', + }) + slidesStore.updateElement({ + id: imageElementId, + props: { src: dataURL, width: w, height: h, left: l, top: t }, + }) + } + addHistorySnapshot() + }) + }) + } + + return { + replaceImage, + } +} diff --git a/src/views/Editor/Canvas/ElementFloatLayer/FloatingToolbar/ImageToolbar.vue b/src/views/Editor/Canvas/ElementFloatLayer/FloatingToolbar/ImageToolbar.vue index 706bc10d..ffd9b112 100644 --- a/src/views/Editor/Canvas/ElementFloatLayer/FloatingToolbar/ImageToolbar.vue +++ b/src/views/Editor/Canvas/ElementFloatLayer/FloatingToolbar/ImageToolbar.vue @@ -14,12 +14,10 @@