mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2026-09-21 05:51:11 +08:00
perf: 优化裁剪后的图片替换逻辑
This commit is contained in:
@@ -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<PPTImageElement>
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
@@ -14,12 +14,10 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { type Ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useMainStore, useSlidesStore } from '@/store'
|
||||
import { useMainStore } from '@/store'
|
||||
import type { PPTImageElement } from '@/types/slides'
|
||||
import { getImageDataURL, getImageSize } from '@/utils/image'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
import useImageHandler from '@/hooks/useImageHandler'
|
||||
|
||||
import FileInput from '@/components/FileInput.vue'
|
||||
|
||||
@@ -28,49 +26,13 @@ defineProps<{
|
||||
}>()
|
||||
|
||||
const mainStore = useMainStore()
|
||||
const slidesStore = useSlidesStore()
|
||||
const { handleElement, handleElementId } = storeToRefs(mainStore)
|
||||
|
||||
const handleImageElement = handleElement as Ref<PPTImageElement>
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
const { handleElementId } = storeToRefs(mainStore)
|
||||
const { replaceImage } = useImageHandler()
|
||||
|
||||
const clipImage = () => {
|
||||
mainStore.setClipingImageElementId(handleElementId.value)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
slidesStore.removeElementProps({
|
||||
id: imageElementId,
|
||||
propName: 'clip',
|
||||
})
|
||||
slidesStore.updateElement({
|
||||
id: imageElementId,
|
||||
props: { src: dataURL, width: w, height: h, left: l, top: t },
|
||||
})
|
||||
addHistorySnapshot()
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -74,8 +74,8 @@ import { storeToRefs } from 'pinia'
|
||||
import { useMainStore, useSlidesStore } from '@/store'
|
||||
import type { PPTImageElement, SlideBackground } from '@/types/slides'
|
||||
import { CLIPPATHS } from '@/configs/imageClip'
|
||||
import { getImageDataURL, getImageSize } from '@/utils/image'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
import useImageHandler from '@/hooks/useImageHandler'
|
||||
|
||||
import ElementOutline from '../common/ElementOutline.vue'
|
||||
import ElementShadow from '../common/ElementShadow.vue'
|
||||
@@ -133,6 +133,7 @@ const handleImageElement = handleElement as Ref<PPTImageElement>
|
||||
const clipPanelVisible = ref(false)
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
const { replaceImage } = useImageHandler()
|
||||
|
||||
// 打开自由裁剪
|
||||
const clipImage = () => {
|
||||
@@ -217,40 +218,6 @@ const presetImageClip = (shape: string, ratio = 0) => {
|
||||
clipImage()
|
||||
}
|
||||
|
||||
// 替换图片(保持当前的样式)
|
||||
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
|
||||
|
||||
slidesStore.removeElementProps({
|
||||
id: imageElementId,
|
||||
propName: 'clip',
|
||||
})
|
||||
slidesStore.updateElement({
|
||||
id: imageElementId,
|
||||
props: { src: dataURL, width: w, height: h, left: l, top: t },
|
||||
})
|
||||
addHistorySnapshot()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 重置图片:清除全部样式
|
||||
const resetImage = () => {
|
||||
const _handleElement = handleElement.value as PPTImageElement
|
||||
|
||||
Reference in New Issue
Block a user