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) {
const background = slide.background
if (background.type === 'image' && background.image) {
if (isBase64Image(background.image)) pptxSlide.background = { data: background.image }
else pptxSlide.background = { path: background.image }
if (isBase64Image(background.image.src)) pptxSlide.background = { data: background.image.src }
else pptxSlide.background = { path: background.image.src }
}
else if (background.type === 'solid' && background.color) {
const c = formatColor(background.color)

View File

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

View File

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

View File

@ -87,6 +87,8 @@ export interface PPTElementOutline {
color?: string
}
export type ElementLinkType = 'web' | 'slide'
/**
*
*
@ -95,7 +97,7 @@ export interface PPTElementOutline {
* target: 目标地址ID
*/
export interface PPTElementLink {
type: 'web' | 'slide'
type: ElementLinkType
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
fontsize?: string
fontname?: string
align?: 'left' | 'center' | 'right' | 'justify'
align?: TextAlign
}
@ -635,6 +638,13 @@ export interface PPTAnimation {
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?: 背景颜色
*
* image?: 图片地址
* image?: 图片背景
*
* imageSize?: 图片填充方式
*
* gradientType?: 渐变类型线
*
* gradientColor?: 渐变颜色
*
* gradientRotate?: 渐变角度线
* gradientType?: 渐变背景
*/
export interface SlideBackground {
type: 'solid' | 'image' | 'gradient'
type: SlideBackgroundType
color?: string
image?: string
imageSize?: 'cover' | 'contain' | 'repeat'
image?: SlideBackgroundImage
gradient?: Gradient
}

View File

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

View File

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

View File

@ -84,7 +84,7 @@
class="row"
button-style="solid"
: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="center" v-tooltip="'居中'" style="flex: 1;"><IconAlignTextCenter /></RadioButton>
@ -173,7 +173,7 @@ import { computed, onMounted, ref, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { nanoid } from 'nanoid'
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 useHistorySnapshot from '@/hooks/useHistorySnapshot'

View File

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