From 2e4a5b6999794ad59329ece68828747c34d0746f Mon Sep 17 00:00:00 2001 From: zxc <1171051090@qq.com> Date: Sat, 10 Aug 2024 15:51:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=BD=A2=E7=8A=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=A4=8D=E6=9D=82=E6=B8=90=E5=8F=98=E5=A1=AB=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/GradientBar.vue | 12 +++-- src/hooks/useExport.ts | 9 +++- src/types/slides.ts | 27 ++++------ .../ElementStylePanel/ShapeStylePanel.vue | 51 +++++++++++-------- .../element/ShapeElement/BaseShapeElement.vue | 3 +- .../element/ShapeElement/GradientDefs.vue | 11 ++-- .../components/element/ShapeElement/index.vue | 3 +- 7 files changed, 63 insertions(+), 53 deletions(-) diff --git a/src/components/GradientBar.vue b/src/components/GradientBar.vue index 34234b0a..9d81ec58 100644 --- a/src/components/GradientBar.vue +++ b/src/components/GradientBar.vue @@ -30,13 +30,14 @@ const emit = defineEmits<{ const points = ref([]) -watchEffect(() => { - points.value = props.value -}) - const barRef = ref() const activeIndex = ref(0) +watchEffect(() => { + points.value = props.value + if (activeIndex.value > props.value.length - 1) activeIndex.value = 0 +}) + watch(activeIndex, () => { emit('update:index', activeIndex.value) }) @@ -52,6 +53,9 @@ const removePoint = (index: number) => { if (index === activeIndex.value) { activeIndex.value = (index - 1 < 0) ? 0 : index - 1 } + else if (activeIndex.value === props.value.length - 1) { + activeIndex.value = props.value.length - 2 + } const values = props.value.filter((item, _index) => _index !== index) emit('update:value', values) diff --git a/src/hooks/useExport.ts b/src/hooks/useExport.ts index 6fa6628f..44a1c139 100644 --- a/src/hooks/useExport.ts +++ b/src/hooks/useExport.ts @@ -517,7 +517,14 @@ export default () => { } const points = formatPoints(toPoints(el.path), scale) - const fillColor = formatColor(el.fill) + let fillColor = formatColor(el.fill) + if (el.gradient) { + const colors = el.gradient.colors + const color1 = colors[0].color + const color2 = colors[colors.length - 1].color + const color = tinycolor.mix(color1, color2).toHexString() + fillColor = formatColor(color) + } const opacity = el.opacity === undefined ? 1 : el.opacity const options: pptxgen.ShapeProps = { diff --git a/src/types/slides.ts b/src/types/slides.ts index 24049cfa..346c49bf 100644 --- a/src/types/slides.ts +++ b/src/types/slides.ts @@ -34,6 +34,15 @@ export const enum ElementTypes { AUDIO = 'audio', } +/** + * 渐变 + * + * type: 渐变类型(径向、线性) + * + * colors: 渐变颜色列表(pos: 百分比位置;color: 颜色) + * + * rotate: 渐变角度(线性渐变) + */ export type GradientType = 'linear' | 'radial' export type GradientColor = { pos: number @@ -261,22 +270,6 @@ export interface PPTImageElement extends PPTBaseElement { colorMask?: string } - -/** - * 形状渐变 - * - * type: 渐变类型(径向、线性) - * - * color: 渐变颜色 - * - * rotate: 渐变角度(线性渐变) - */ -export interface ShapeGradient { - type: GradientType - color: [string, string] - rotate: number -} - export type ShapeTextAlign = 'top' | 'middle' | 'bottom' /** @@ -338,7 +331,7 @@ export interface PPTShapeElement extends PPTBaseElement { path: string fixedRatio: boolean fill: string - gradient?: ShapeGradient + gradient?: Gradient outline?: PPTElementOutline opacity?: number flipH?: boolean diff --git a/src/views/Editor/Toolbar/ElementStylePanel/ShapeStylePanel.vue b/src/views/Editor/Toolbar/ElementStylePanel/ShapeStylePanel.vue index 82f81efe..406ea2c9 100644 --- a/src/views/Editor/Toolbar/ElementStylePanel/ShapeStylePanel.vue +++ b/src/views/Editor/Toolbar/ElementStylePanel/ShapeStylePanel.vue @@ -52,27 +52,22 @@