perf: 数据类型/结构优化

This commit is contained in:
zxc 2024-08-10 19:56:47 +08:00
parent 2e4a5b6999
commit bcd8749a75
8 changed files with 61 additions and 40 deletions

View File

@ -389,8 +389,8 @@ export default () => {
if (slide.background) { if (slide.background) {
const background = slide.background const background = slide.background
if (background.type === 'image' && background.image) { if (background.type === 'image' && background.image) {
if (isBase64Image(background.image)) pptxSlide.background = { data: background.image } if (isBase64Image(background.image.src)) pptxSlide.background = { data: background.image.src }
else pptxSlide.background = { path: background.image } else pptxSlide.background = { path: background.image.src }
} }
else if (background.type === 'solid' && background.color) { else if (background.type === 'solid' && background.color) {
const c = formatColor(background.color) const c = formatColor(background.color)

View File

@ -113,8 +113,10 @@ export default () => {
if (type === 'image') { if (type === 'image') {
background = { background = {
type: 'image', type: 'image',
image: value.picBase64, image: {
imageSize: 'cover', src: value.picBase64,
size: 'cover',
},
} }
} }
else if (type === 'gradient') { else if (type === 'gradient') {

View File

@ -10,7 +10,6 @@ export default (background: Ref<SlideBackground | undefined>) => {
type, type,
color, color,
image, image,
imageSize,
gradient, gradient,
} = background.value } = background.value
@ -19,19 +18,20 @@ export default (background: Ref<SlideBackground | undefined>) => {
// 背景图模式 // 背景图模式
// 包括:背景图、背景大小,是否重复 // 包括:背景图、背景大小,是否重复
else if (type === 'image') { else if (type === 'image' && image) {
if (!image) return { backgroundColor: '#fff' } const { src, size } = image
if (imageSize === 'repeat') { if (!src) return { backgroundColor: '#fff' }
if (size === 'repeat') {
return { return {
backgroundImage: `url(${image}`, backgroundImage: `url(${src}`,
backgroundRepeat: 'repeat', backgroundRepeat: 'repeat',
backgroundSize: 'contain', backgroundSize: 'contain',
} }
} }
return { return {
backgroundImage: `url(${image}`, backgroundImage: `url(${src}`,
backgroundRepeat: 'no-repeat', backgroundRepeat: 'no-repeat',
backgroundSize: imageSize || 'cover', backgroundSize: size || 'cover',
} }
} }

View File

@ -87,6 +87,8 @@ export interface PPTElementOutline {
color?: string color?: string
} }
export type ElementLinkType = 'web' | 'slide'
/** /**
* *
* *
@ -95,7 +97,7 @@ export interface PPTElementOutline {
* target: 目标地址ID * target: 目标地址ID
*/ */
export interface PPTElementLink { export interface PPTElementLink {
type: 'web' | 'slide' type: ElementLinkType
target: string target: string
} }
@ -429,6 +431,7 @@ export interface PPTChartElement extends PPTBaseElement {
} }
export type TextAlign = 'left' | 'center' | 'right' | 'justify'
/** /**
* *
* *
@ -459,7 +462,7 @@ export interface TableCellStyle {
backcolor?: string backcolor?: string
fontsize?: string fontsize?: string
fontname?: string fontname?: string
align?: 'left' | 'center' | 'right' | 'justify' align?: TextAlign
} }
@ -635,6 +638,13 @@ export interface PPTAnimation {
trigger: AnimationTrigger trigger: AnimationTrigger
} }
export type SlideBackgroundType = 'solid' | 'image' | 'gradient'
export type SlideBackgroundImageSize = 'cover' | 'contain' | 'repeat'
export interface SlideBackgroundImage {
src: string
size: SlideBackgroundImageSize,
}
/** /**
* *
* *
@ -642,21 +652,14 @@ export interface PPTAnimation {
* *
* color?: 背景颜色 * color?: 背景颜色
* *
* image?: 图片地址 * image?: 图片背景
* *
* imageSize?: 图片填充方式 * gradientType?: 渐变背景
*
* gradientType?: 渐变类型线
*
* gradientColor?: 渐变颜色
*
* gradientRotate?: 渐变角度线
*/ */
export interface SlideBackground { export interface SlideBackground {
type: 'solid' | 'image' | 'gradient' type: SlideBackgroundType
color?: string color?: string
image?: string image?: SlideBackgroundImage
imageSize?: 'cover' | 'contain' | 'repeat'
gradient?: Gradient gradient?: Gradient
} }

View File

@ -36,7 +36,7 @@
import { computed, onMounted, ref } from 'vue' import { computed, onMounted, ref } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { useMainStore, useSlidesStore } from '@/store' import { useMainStore, useSlidesStore } from '@/store'
import type { PPTElementLink } from '@/types/slides' import type { ElementLinkType, PPTElementLink } from '@/types/slides'
import useLink from '@/hooks/useLink' import useLink from '@/hooks/useLink'
import ThumbnailSlide from '@/views/components/ThumbnailSlide/index.vue' import ThumbnailSlide from '@/views/components/ThumbnailSlide/index.vue'
@ -45,9 +45,8 @@ import Input from '@/components/Input.vue'
import Button from '@/components/Button.vue' import Button from '@/components/Button.vue'
import Select from '@/components/Select.vue' import Select from '@/components/Select.vue'
type TypeKey = 'web' | 'slide'
interface TabItem { interface TabItem {
key: TypeKey key: ElementLinkType
label: string label: string
} }
@ -58,7 +57,7 @@ const emit = defineEmits<{
const { handleElement } = storeToRefs(useMainStore()) const { handleElement } = storeToRefs(useMainStore())
const { slides, currentSlide } = storeToRefs(useSlidesStore()) const { slides, currentSlide } = storeToRefs(useSlidesStore())
const type = ref<TypeKey>('web') const type = ref<ElementLinkType>('web')
const address = ref('') const address = ref('')
const slideId = ref('') const slideId = ref('')

View File

@ -255,8 +255,10 @@ const setBackgroundImage = () => {
const background: SlideBackground = { const background: SlideBackground = {
...currentSlide.value.background, ...currentSlide.value.background,
type: 'image', type: 'image',
image: _handleElement.src, image: {
imageSize: 'cover', src: _handleElement.src,
size: 'cover'
},
} }
slidesStore.updateSlide({ background }) slidesStore.updateSlide({ background })
addHistorySnapshot() addHistorySnapshot()

View File

@ -84,7 +84,7 @@
class="row" class="row"
button-style="solid" button-style="solid"
:value="textAttrs.align" :value="textAttrs.align"
@update:value="value => updateTextAttrs({ align: value as 'left' | 'center' | 'right' | 'justify' })" @update:value="value => updateTextAttrs({ align: value as TextAlign })"
> >
<RadioButton value="left" v-tooltip="'左对齐'" style="flex: 1;"><IconAlignTextLeft /></RadioButton> <RadioButton value="left" v-tooltip="'左对齐'" style="flex: 1;"><IconAlignTextLeft /></RadioButton>
<RadioButton value="center" v-tooltip="'居中'" style="flex: 1;"><IconAlignTextCenter /></RadioButton> <RadioButton value="center" v-tooltip="'居中'" style="flex: 1;"><IconAlignTextCenter /></RadioButton>
@ -173,7 +173,7 @@ import { computed, onMounted, ref, watch } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { nanoid } from 'nanoid' import { nanoid } from 'nanoid'
import { useMainStore, useSlidesStore } from '@/store' import { useMainStore, useSlidesStore } from '@/store'
import type { PPTTableElement, TableCell, TableCellStyle, TableTheme } from '@/types/slides' import type { PPTTableElement, TableCell, TableCellStyle, TableTheme, TextAlign } from '@/types/slides'
import { WEB_FONTS } from '@/configs/font' import { WEB_FONTS } from '@/configs/font'
import useHistorySnapshot from '@/hooks/useHistorySnapshot' import useHistorySnapshot from '@/hooks/useHistorySnapshot'

View File

@ -26,8 +26,8 @@
<Select <Select
style="flex: 1;" style="flex: 1;"
:value="background.imageSize || 'cover'" :value="background.image?.size || 'cover'"
@update:value="value => updateBackground({ imageSize: value as 'repeat' | 'cover' | 'contain' })" @update:value="value => updateImageBackground({ size: value as SlideBackgroundImageSize })"
v-else-if="background.type === 'image'" v-else-if="background.type === 'image'"
:options="[ :options="[
{ label: '缩放', value: 'contain' }, { label: '缩放', value: 'contain' },
@ -51,7 +51,7 @@
<div class="background-image-wrapper" v-if="background.type === 'image'"> <div class="background-image-wrapper" v-if="background.type === 'image'">
<FileInput @change="files => uploadBackgroundImage(files)"> <FileInput @change="files => uploadBackgroundImage(files)">
<div class="background-image"> <div class="background-image">
<div class="content" :style="{ backgroundImage: `url(${background.image})` }"> <div class="content" :style="{ backgroundImage: `url(${background.image?.src})` }">
<IconPlus /> <IconPlus />
</div> </div>
</div> </div>
@ -301,7 +301,15 @@
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { useMainStore, useSlidesStore } from '@/store' import { useMainStore, useSlidesStore } from '@/store'
import type { Gradient, GradientType, SlideBackground, SlideTheme } from '@/types/slides' import type {
Gradient,
GradientType,
SlideBackground,
SlideBackgroundType,
SlideTheme,
SlideBackgroundImage,
SlideBackgroundImageSize,
} from '@/types/slides'
import { PRESET_THEMES } from '@/configs/theme' import { PRESET_THEMES } from '@/configs/theme'
import { WEB_FONTS } from '@/configs/font' import { WEB_FONTS } from '@/configs/font'
import useHistorySnapshot from '@/hooks/useHistorySnapshot' import useHistorySnapshot from '@/hooks/useHistorySnapshot'
@ -347,7 +355,7 @@ const {
} = useSlideTheme() } = useSlideTheme()
// //
const updateBackgroundType = (type: 'solid' | 'image' | 'gradient') => { const updateBackgroundType = (type: SlideBackgroundType) => {
if (type === 'solid') { if (type === 'solid') {
const newBackground: SlideBackground = { const newBackground: SlideBackground = {
...background.value, ...background.value,
@ -360,8 +368,10 @@ const updateBackgroundType = (type: 'solid' | 'image' | 'gradient') => {
const newBackground: SlideBackground = { const newBackground: SlideBackground = {
...background.value, ...background.value,
type: 'image', type: 'image',
image: background.value.image || '', image: background.value.image || {
imageSize: background.value.imageSize || 'cover', src: '',
size: 'cover',
},
} }
slidesStore.updateSlide({ background: newBackground }) slidesStore.updateSlide({ background: newBackground })
} }
@ -401,11 +411,16 @@ const updateGradientBackgroundColors = (color: string) => {
updateGradientBackground({ colors }) updateGradientBackground({ colors })
} }
//
const updateImageBackground = (props: Partial<SlideBackgroundImage>) => {
updateBackground({ image: { ...background.value.image!, ...props } })
}
// //
const uploadBackgroundImage = (files: FileList) => { const uploadBackgroundImage = (files: FileList) => {
const imageFile = files[0] const imageFile = files[0]
if (!imageFile) return if (!imageFile) return
getImageDataURL(imageFile).then(dataURL => updateBackground({ image: dataURL })) getImageDataURL(imageFile).then(dataURL => updateImageBackground({ src: dataURL }))
} }
// //