jvs-ppt-ui 0.0.15 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/jvs-ppt-ui.es.js +24062 -23229
- package/dist/lib/jvs-ppt-ui.umd.js +101 -101
- package/dist/lib/style.css +1 -1
- package/package.json +1 -1
- package/src/components/CanvasArea.vue +9707 -9667
- package/src/components/ChartTypeSelector.vue +34 -30
- package/src/components/Header.vue +40 -5
- package/src/components/PresentationGroupChild.vue +44 -13
- package/src/components/PresentationMode.vue +84 -33
- package/src/components/SidebarLeft.vue +96 -18
- package/src/components/SidebarRight.vue +16 -9
- package/src/components/TemplateGallery.vue +36 -3
- package/src/components/Toolbar.vue +1 -1
- package/src/components/canvas/elements/CanvasGroupElement.vue +214 -213
- package/src/components/canvas/elements/CanvasShapeElement.vue +894 -825
- package/src/components/sidebar/common/SidebarBorderAccordion.vue +2 -2
- package/src/components/sidebar/common/SidebarReflectionAccordion.vue +2 -2
- package/src/components/sidebar/common/SidebarShadowAccordion.vue +2 -2
- package/src/components/sidebar/panels/SidebarChartFormatPanel.vue +3 -3
- package/src/components/sidebar/panels/SidebarDesignPanel.vue +170 -9
- package/src/components/sidebar/panels/SidebarShapeFormatPanel.vue +176 -16
- package/src/components/sidebar/panels/SidebarTableFormatPanel.vue +2 -2
- package/src/components/sidebar/panels/SidebarTextFormatPanel.vue +3 -3
- package/src/components/sidebar/panels/SidebarTransitionPanel.vue +30 -19
- package/src/composables/canvas/useCanvasText.ts +44 -18
- package/src/composables/canvas/useCanvasTransform.ts +24 -0
- package/src/composables/sidebar/useSidebarShapeFormat.ts +248 -17
- package/src/composables/sidebar/useSidebarTextFormat.ts +72 -1
- package/src/composables/useSlides.ts +9804 -9615
- package/src/style.css +4 -2
- package/src/utils/canvas/elementStyles.ts +278 -0
|
@@ -20,7 +20,9 @@ import {
|
|
|
20
20
|
getElementBorderGradientCss,
|
|
21
21
|
getGradientAngleDeg,
|
|
22
22
|
getSvgGradientCoords,
|
|
23
|
-
isImagePlaceholder
|
|
23
|
+
isImagePlaceholder,
|
|
24
|
+
isElementPatternTile,
|
|
25
|
+
getElementPatternTileSize
|
|
24
26
|
} from '../utils/canvas/elementStyles'
|
|
25
27
|
import CanvasImageElement from './canvas/elements/CanvasImageElement.vue'
|
|
26
28
|
|
|
@@ -75,29 +77,59 @@ function observeThumbItem(el: HTMLElement | null, index: number) {
|
|
|
75
77
|
if (!el || typeof IntersectionObserver === 'undefined') return
|
|
76
78
|
if (!thumbObserver) {
|
|
77
79
|
thumbObserver = new IntersectionObserver((entries) => {
|
|
80
|
+
let mutated = false
|
|
78
81
|
entries.forEach(entry => {
|
|
79
82
|
if (entry.isIntersecting) {
|
|
80
83
|
const idx = Number((entry.target as HTMLElement).dataset.slideIndex)
|
|
81
84
|
if (!isNaN(idx) && !renderedThumbIndexes.value.has(idx)) {
|
|
82
85
|
renderedThumbIndexes.value.add(idx)
|
|
86
|
+
mutated = true
|
|
83
87
|
}
|
|
84
88
|
}
|
|
85
89
|
})
|
|
90
|
+
if (mutated) {
|
|
91
|
+
renderedThumbIndexes.value = new Set(renderedThumbIndexes.value)
|
|
92
|
+
}
|
|
86
93
|
}, {
|
|
87
94
|
rootMargin: '300px 0px'
|
|
88
95
|
})
|
|
89
96
|
}
|
|
90
|
-
|
|
97
|
+
if (!renderedThumbIndexes.value.has(index)) {
|
|
98
|
+
thumbObserver.observe(el)
|
|
99
|
+
}
|
|
91
100
|
}
|
|
92
101
|
|
|
93
102
|
watch(activeIndex, (newIdx) => {
|
|
94
103
|
if (!renderedThumbIndexes.value.has(newIdx)) {
|
|
95
|
-
renderedThumbIndexes.value
|
|
104
|
+
const next = new Set(renderedThumbIndexes.value)
|
|
105
|
+
next.add(newIdx)
|
|
106
|
+
renderedThumbIndexes.value = next
|
|
96
107
|
}
|
|
97
108
|
})
|
|
98
109
|
|
|
99
|
-
watch(() => slides.value.length, () => {
|
|
100
|
-
|
|
110
|
+
watch(() => slides.value.length, (newLen, oldLen) => {
|
|
111
|
+
const delta = typeof oldLen === 'number' ? newLen - oldLen : 0
|
|
112
|
+
const isBulkImport = typeof oldLen === 'number' && delta > 5 && activeIndex.value === 0
|
|
113
|
+
if (isBulkImport) {
|
|
114
|
+
if (thumbObserver) {
|
|
115
|
+
thumbObserver.disconnect()
|
|
116
|
+
thumbObserver = null
|
|
117
|
+
}
|
|
118
|
+
renderedThumbIndexes.value = new Set<number>([0, 1, 2, 3, 4, 5, activeIndex.value])
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
const next = new Set<number>([0, 1, 2, 3, 4, 5, activeIndex.value])
|
|
122
|
+
renderedThumbIndexes.value.forEach(idx => {
|
|
123
|
+
if (idx >= 0 && idx < newLen) {
|
|
124
|
+
next.add(idx)
|
|
125
|
+
}
|
|
126
|
+
if (delta > 0 && delta <= 5 && idx + delta >= 0 && idx + delta < newLen) {
|
|
127
|
+
next.add(idx + delta)
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
if (activeIndex.value - 1 >= 0) next.add(activeIndex.value - 1)
|
|
131
|
+
if (activeIndex.value + 1 < newLen) next.add(activeIndex.value + 1)
|
|
132
|
+
renderedThumbIndexes.value = next
|
|
101
133
|
})
|
|
102
134
|
|
|
103
135
|
onUnmounted(() => {
|
|
@@ -744,6 +776,7 @@ const addSlideWithLayout = (layoutId: string) => {
|
|
|
744
776
|
newSlide.subtitle = ''
|
|
745
777
|
}
|
|
746
778
|
|
|
779
|
+
activeSlideVersion.value++
|
|
747
780
|
presetPopoverVisible.value = false
|
|
748
781
|
}
|
|
749
782
|
|
|
@@ -1035,6 +1068,22 @@ function getElementWidthHeight(el: any, parentGroup?: any, anchorGroup?: any): {
|
|
|
1035
1068
|
return { width, height }
|
|
1036
1069
|
}
|
|
1037
1070
|
|
|
1071
|
+
function getShapePatternTransform(el: any, isTriangle = false): string | undefined {
|
|
1072
|
+
if (!isElementPatternTile(el)) return undefined
|
|
1073
|
+
const dim = getElementWidthHeight(el)
|
|
1074
|
+
const w = Math.max(1, dim.width || 100)
|
|
1075
|
+
const h = Math.max(1, dim.height || 100)
|
|
1076
|
+
if (isTriangle) {
|
|
1077
|
+
return `scale(${+(100 / w).toFixed(4)}, ${+(100 / h).toFixed(4)})`
|
|
1078
|
+
}
|
|
1079
|
+
const vbW = el.viewBox ? el.viewBox[0] : 200
|
|
1080
|
+
const vbH = el.viewBox ? el.viewBox[1] : 200
|
|
1081
|
+
const bw = el.shapType === 'arc' ? 0 : (el.style?.borderWidth ? parseFloat(el.style.borderWidth) : 2)
|
|
1082
|
+
const effW = Math.max(1, w - bw)
|
|
1083
|
+
const effH = Math.max(1, h - bw)
|
|
1084
|
+
return `scale(${+(vbW / effW).toFixed(4)}, ${+(vbH / effH).toFixed(4)})`
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1038
1087
|
function getTextStrokeStyle(el: any) {
|
|
1039
1088
|
if (!el.style || !el.style.enableTextStroke) return 'none'
|
|
1040
1089
|
const width = el.style.textStrokeWidth || '1px'
|
|
@@ -2290,8 +2339,9 @@ const masterGroupedLayouts = computed(() => {
|
|
|
2290
2339
|
height: '100%',
|
|
2291
2340
|
backgroundColor: getElementPattern(el) ? 'transparent' : ((getElementGradientCss(el) || (getElementFill(el) !== undefined && getElementFill(el) !== 'none')) ? (getElementGradientCss(el) ? 'transparent' : getElementFill(el)) : (getElementFill(el) === 'none' ? 'transparent' : '#3b82f6')),
|
|
2292
2341
|
backgroundImage: getElementPattern(el) ? `url('${getElementPattern(el)}')` : (getElementGradientCss(el) || 'none'),
|
|
2293
|
-
backgroundSize: getElementPattern(el) ? 'cover' : undefined,
|
|
2294
|
-
backgroundPosition: getElementPattern(el) ? 'center center' : undefined,
|
|
2342
|
+
backgroundSize: getElementPattern(el) ? (isElementPatternTile(el) ? `${getElementPatternTileSize(el).w}px ${getElementPatternTileSize(el).h}px` : 'cover') : undefined,
|
|
2343
|
+
backgroundPosition: getElementPattern(el) ? (isElementPatternTile(el) ? '0 0' : 'center center') : undefined,
|
|
2344
|
+
backgroundRepeat: getElementPattern(el) ? (isElementPatternTile(el) ? 'repeat' : 'no-repeat') : undefined,
|
|
2295
2345
|
borderRadius: '50%',
|
|
2296
2346
|
borderWidth: el.style?.borderWidth || '0px',
|
|
2297
2347
|
borderStyle: el.style?.borderStyle || 'solid',
|
|
@@ -2302,8 +2352,16 @@ const masterGroupedLayouts = computed(() => {
|
|
|
2302
2352
|
:viewBox="`0 0 ${el.viewBox ? el.viewBox[0] : (el.width || 200)} ${el.viewBox ? el.viewBox[1] : (el.height || 200)}`"
|
|
2303
2353
|
preserveAspectRatio="none" style="width: 100%; height: 100%; display: block; overflow: visible;">
|
|
2304
2354
|
<defs>
|
|
2305
|
-
<pattern v-if="getElementPattern(el)" :id="`thumb-master-pat-${slide.id || index}-${el.id}`"
|
|
2306
|
-
|
|
2355
|
+
<pattern v-if="getElementPattern(el)" :id="`thumb-master-pat-${slide.id || index}-${el.id}`"
|
|
2356
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : '100%'"
|
|
2357
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : '100%'"
|
|
2358
|
+
:patternUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
2359
|
+
:patternContentUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
2360
|
+
:patternTransform="getShapePatternTransform(el, false)">
|
|
2361
|
+
<image :href="getElementPattern(el)"
|
|
2362
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : 1"
|
|
2363
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : 1"
|
|
2364
|
+
preserveAspectRatio="none" />
|
|
2307
2365
|
</pattern>
|
|
2308
2366
|
<template v-if="getElementGradientConfig(el)">
|
|
2309
2367
|
<radialGradient v-if="getElementGradientConfig(el)!.path && getElementGradientConfig(el)!.path !== 'line'"
|
|
@@ -2345,7 +2403,9 @@ const masterGroupedLayouts = computed(() => {
|
|
|
2345
2403
|
<div v-else :style="{
|
|
2346
2404
|
backgroundColor: getElementPattern(el) ? 'transparent' : ((getElementGradientCss(el) || (getElementFill(el) !== undefined && getElementFill(el) !== 'none')) ? (getElementGradientCss(el) ? 'transparent' : getElementFill(el)) : (getElementFill(el) === 'none' ? 'transparent' : '#3b82f6')),
|
|
2347
2405
|
backgroundImage: getElementPattern(el) ? `url('${getElementPattern(el)}')` : (getElementGradientCss(el) || 'none'),
|
|
2348
|
-
backgroundSize: getElementPattern(el) ? 'cover' : undefined,
|
|
2406
|
+
backgroundSize: getElementPattern(el) ? (isElementPatternTile(el) ? `${getElementPatternTileSize(el).w}px ${getElementPatternTileSize(el).h}px` : 'cover') : undefined,
|
|
2407
|
+
backgroundPosition: getElementPattern(el) ? (isElementPatternTile(el) ? '0 0' : 'center center') : undefined,
|
|
2408
|
+
backgroundRepeat: getElementPattern(el) ? (isElementPatternTile(el) ? 'repeat' : 'no-repeat') : undefined,
|
|
2349
2409
|
width: '100%',
|
|
2350
2410
|
height: '100%',
|
|
2351
2411
|
borderRadius: el.style?.borderRadius || '0px',
|
|
@@ -2463,8 +2523,9 @@ const masterGroupedLayouts = computed(() => {
|
|
|
2463
2523
|
height: '100%',
|
|
2464
2524
|
backgroundColor: getElementPattern(el) ? 'transparent' : ((getElementGradientCss(el) || (getElementFill(el) !== undefined && getElementFill(el) !== 'none')) ? (getElementGradientCss(el) ? 'transparent' : getElementFill(el)) : (getElementFill(el) === 'none' ? 'transparent' : '#3b82f6')),
|
|
2465
2525
|
backgroundImage: getElementPattern(el) ? `url('${getElementPattern(el)}')` : (getElementGradientCss(el) || 'none'),
|
|
2466
|
-
backgroundSize: getElementPattern(el) ? 'cover' : undefined,
|
|
2467
|
-
backgroundPosition: getElementPattern(el) ? 'center center' : undefined,
|
|
2526
|
+
backgroundSize: getElementPattern(el) ? (isElementPatternTile(el) ? `${getElementPatternTileSize(el).w}px ${getElementPatternTileSize(el).h}px` : 'cover') : undefined,
|
|
2527
|
+
backgroundPosition: getElementPattern(el) ? (isElementPatternTile(el) ? '0 0' : 'center center') : undefined,
|
|
2528
|
+
backgroundRepeat: getElementPattern(el) ? (isElementPatternTile(el) ? 'repeat' : 'no-repeat') : undefined,
|
|
2468
2529
|
borderRadius: '50%',
|
|
2469
2530
|
borderWidth: `${getElementBorderWidth(el)}px`,
|
|
2470
2531
|
borderStyle: el.style?.borderStyle || (el as any).borderType || 'solid',
|
|
@@ -2478,8 +2539,16 @@ const masterGroupedLayouts = computed(() => {
|
|
|
2478
2539
|
style="width: 100%; height: 100%; display: block; overflow: visible;"
|
|
2479
2540
|
:style="{ filter: (el.shadow && el.shadow.type === 'inner') ? `url(#thumb-shape-inner-shadow-${el.id})` : '' }">
|
|
2480
2541
|
<defs>
|
|
2481
|
-
<pattern v-if="getElementPattern(el)" :id="`thumb-shape-pattern-${slide.id || index}-${el.id}`"
|
|
2482
|
-
|
|
2542
|
+
<pattern v-if="getElementPattern(el)" :id="`thumb-shape-pattern-${slide.id || index}-${el.id}`"
|
|
2543
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : '100%'"
|
|
2544
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : '100%'"
|
|
2545
|
+
:patternUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
2546
|
+
:patternContentUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
2547
|
+
:patternTransform="getShapePatternTransform(el, true)">
|
|
2548
|
+
<image :href="getElementPattern(el)"
|
|
2549
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : 1"
|
|
2550
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : 1"
|
|
2551
|
+
preserveAspectRatio="none" />
|
|
2483
2552
|
</pattern>
|
|
2484
2553
|
<template v-if="getElementGradientConfig(el)">
|
|
2485
2554
|
<radialGradient v-if="getElementGradientConfig(el)!.path && getElementGradientConfig(el)!.path !== 'line'"
|
|
@@ -2523,8 +2592,16 @@ const masterGroupedLayouts = computed(() => {
|
|
|
2523
2592
|
<svg overflow="visible" style="width: 100%; height: 100%; display: block; overflow: visible;"
|
|
2524
2593
|
:style="{ filter: (el.shadow && el.shadow.type === 'inner') ? `url(#thumb-shape-inner-shadow-${el.id})` : '' }">
|
|
2525
2594
|
<defs>
|
|
2526
|
-
<pattern v-if="getElementPattern(el)" :id="`thumb-shape-pattern-${slide.id || index}-${el.id}`"
|
|
2527
|
-
|
|
2595
|
+
<pattern v-if="getElementPattern(el)" :id="`thumb-shape-pattern-${slide.id || index}-${el.id}`"
|
|
2596
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : '100%'"
|
|
2597
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : '100%'"
|
|
2598
|
+
:patternUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
2599
|
+
:patternContentUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
2600
|
+
:patternTransform="getShapePatternTransform(el, false)">
|
|
2601
|
+
<image :href="getElementPattern(el)"
|
|
2602
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : 1"
|
|
2603
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : 1"
|
|
2604
|
+
preserveAspectRatio="none" />
|
|
2528
2605
|
</pattern>
|
|
2529
2606
|
<template v-if="getElementGradientConfig(el)">
|
|
2530
2607
|
<radialGradient v-if="getElementGradientConfig(el)!.path && getElementGradientConfig(el)!.path !== 'line'"
|
|
@@ -2572,8 +2649,9 @@ const masterGroupedLayouts = computed(() => {
|
|
|
2572
2649
|
height: '100%',
|
|
2573
2650
|
backgroundColor: getElementPattern(el) ? 'transparent' : ((isImagePlaceholder(el) && !getElementGradientCss(el)) ? ((getElementFill(el) && getElementFill(el) !== '#f1f5f9' && getElementFill(el) !== '#f8fafc') ? getElementFill(el) : '#d9dde3') : ((getElementGradientCss(el) || (getElementFill(el) !== undefined && getElementFill(el) !== 'none')) ? (getElementGradientCss(el) ? 'transparent' : getElementFill(el)) : (getElementFill(el) === 'none' ? 'transparent' : '#10b981'))),
|
|
2574
2651
|
backgroundImage: getElementPattern(el) ? `url('${getElementPattern(el)}')` : (getElementGradientCss(el) || 'none'),
|
|
2575
|
-
backgroundSize: getElementPattern(el) ? 'cover' : undefined,
|
|
2576
|
-
backgroundPosition: getElementPattern(el) ? 'center center' : undefined,
|
|
2652
|
+
backgroundSize: getElementPattern(el) ? (isElementPatternTile(el) ? `${getElementPatternTileSize(el).w}px ${getElementPatternTileSize(el).h}px` : 'cover') : undefined,
|
|
2653
|
+
backgroundPosition: getElementPattern(el) ? (isElementPatternTile(el) ? '0 0' : 'center center') : undefined,
|
|
2654
|
+
backgroundRepeat: getElementPattern(el) ? (isElementPatternTile(el) ? 'repeat' : 'no-repeat') : undefined,
|
|
2577
2655
|
borderRadius: isImagePlaceholder(el) ? ((el.style?.borderRadius && el.style.borderRadius !== '0px' && el.style.borderRadius !== '4px') ? el.style.borderRadius : '12px') : (el.style?.borderRadius !== undefined ? el.style.borderRadius : '0px'),
|
|
2578
2656
|
borderWidth: (isImagePlaceholder(el) && (el.style as any)?.enableBorder !== true) ? '0px' : `${getElementBorderWidth(el)}px`,
|
|
2579
2657
|
borderStyle: el.style?.borderStyle || (el as any).borderType || 'solid',
|
|
@@ -465,12 +465,15 @@ function applyTextStyleToHtml(html: string, styles: any) {
|
|
|
465
465
|
paragraphs.forEach(applyTextStyles)
|
|
466
466
|
}
|
|
467
467
|
|
|
468
|
-
// 综合处理字体与样式覆盖:如果指定了 fontFamily
|
|
469
|
-
if (styles.fontFamily) {
|
|
468
|
+
// 综合处理字体与样式覆盖:如果指定了 fontFamily 或 fontSize,清理/更新所有块级和内联节点的原有硬编码值
|
|
469
|
+
if (styles.fontFamily || styles.fontSize) {
|
|
470
470
|
div.querySelectorAll('p, div, li, h1, h2, h3, h4, h5, h6, span, b, strong, i, em, a').forEach((elem: any) => {
|
|
471
|
-
if (elem.style && elem.style.fontFamily) {
|
|
471
|
+
if (styles.fontFamily && elem.style && elem.style.fontFamily) {
|
|
472
472
|
elem.style.fontFamily = styles.fontFamily
|
|
473
473
|
}
|
|
474
|
+
if (styles.fontSize && elem.style && elem.style.fontSize) {
|
|
475
|
+
elem.style.fontSize = styles.fontSize
|
|
476
|
+
}
|
|
474
477
|
})
|
|
475
478
|
}
|
|
476
479
|
|
|
@@ -571,11 +574,12 @@ function setStyleVal(prop: string, val: any) {
|
|
|
571
574
|
}
|
|
572
575
|
}
|
|
573
576
|
|
|
574
|
-
if (prop === 'fontFamily') {
|
|
577
|
+
if (prop === 'fontFamily' || prop === 'fontSize') {
|
|
575
578
|
const container = document.getElementById(`editable-${el.id}`)
|
|
576
579
|
if (container) {
|
|
577
|
-
container.style.fontFamily = val
|
|
578
|
-
container.
|
|
580
|
+
if (prop === 'fontFamily') container.style.fontFamily = val
|
|
581
|
+
else container.style.fontSize = val
|
|
582
|
+
container.innerHTML = applyTextStyleToHtml(container.innerHTML, { [prop]: val })
|
|
579
583
|
if (el.type === 'shape') {
|
|
580
584
|
el.text = container.innerHTML
|
|
581
585
|
} else {
|
|
@@ -916,6 +920,9 @@ const {
|
|
|
916
920
|
gradientDirection,
|
|
917
921
|
updateElementGradient,
|
|
918
922
|
shapePatternFill,
|
|
923
|
+
shapePatternType,
|
|
924
|
+
shapePatternFg,
|
|
925
|
+
shapePatternBg,
|
|
919
926
|
handleShapePatternUpload,
|
|
920
927
|
clearShapePatternFill,
|
|
921
928
|
styleBorderStyle,
|
|
@@ -1709,9 +1716,9 @@ function handleUndockToPopover() {
|
|
|
1709
1716
|
v-model:gradient-angle="gradientAngle"
|
|
1710
1717
|
@update:element-gradient="updateElementGradient"
|
|
1711
1718
|
v-model:shape-pattern-fill="shapePatternFill"
|
|
1712
|
-
:shape-pattern-type="
|
|
1713
|
-
:shape-pattern-fg="
|
|
1714
|
-
:shape-pattern-bg="
|
|
1719
|
+
v-model:shape-pattern-type="shapePatternType"
|
|
1720
|
+
v-model:shape-pattern-fg="shapePatternFg"
|
|
1721
|
+
v-model:shape-pattern-bg="shapePatternBg"
|
|
1715
1722
|
:fill-opacity="fillAlpha"
|
|
1716
1723
|
:is-border-enabled="enableBorder"
|
|
1717
1724
|
v-model:is-border-expanded="isBorderExpanded"
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
VideoPlay
|
|
12
12
|
} from '@element-plus/icons-vue'
|
|
13
13
|
import { useSlides, DEFAULT_MATERIAL_PAGE_API_URL } from '../composables/useSlides'
|
|
14
|
+
import { isImagePlaceholder } from '../utils/canvas/elementStyles'
|
|
14
15
|
|
|
15
16
|
const {
|
|
16
17
|
addElement,
|
|
@@ -20,7 +21,12 @@ const {
|
|
|
20
21
|
materialPageApiUrl,
|
|
21
22
|
materialHeaders,
|
|
22
23
|
activeTab,
|
|
23
|
-
materialPopoverVisible
|
|
24
|
+
materialPopoverVisible,
|
|
25
|
+
activeSlide,
|
|
26
|
+
selectedElementId,
|
|
27
|
+
placeholderMaterialTargetId,
|
|
28
|
+
resolveActivePlaceholderTargetId,
|
|
29
|
+
replacePlaceholderElement
|
|
24
30
|
} = useSlides()
|
|
25
31
|
|
|
26
32
|
export interface MaterialItem {
|
|
@@ -682,7 +688,7 @@ function formatMaterialTitle(title?: string, fallback = '素材', maxLen = 12):
|
|
|
682
688
|
return text.length > maxLen ? `${text.slice(0, maxLen)}...` : text
|
|
683
689
|
}
|
|
684
690
|
|
|
685
|
-
//
|
|
691
|
+
// 点击素材卡片插入画布(区分视频与图片/矢量/插画,若当前处于图片占位符替换状态则优先替换占位符)
|
|
686
692
|
function handleSelectMaterial(meta: MaterialItem) {
|
|
687
693
|
const isVid = isVideoMaterial(meta)
|
|
688
694
|
const targetUrl = meta.sourceUrl || meta.url || meta.downloadUrl || meta.previewUrl
|
|
@@ -692,9 +698,36 @@ function handleSelectMaterial(meta: MaterialItem) {
|
|
|
692
698
|
return
|
|
693
699
|
}
|
|
694
700
|
|
|
695
|
-
let initialDimensions: { width?: number; height?: number } | undefined = undefined
|
|
696
701
|
const rawW = meta.originalWidth || meta.width
|
|
697
702
|
const rawH = meta.originalHeight || meta.height
|
|
703
|
+
|
|
704
|
+
const currentSelectedEl = selectedElementId?.value
|
|
705
|
+
? activeSlide?.value?.elements?.find((el: any) => el.id === selectedElementId.value)
|
|
706
|
+
: null
|
|
707
|
+
|
|
708
|
+
const explicitTargetId =
|
|
709
|
+
placeholderMaterialTargetId?.value ||
|
|
710
|
+
(typeof window !== 'undefined' ? (window as any).__jvsPlaceholderTargetId : null)
|
|
711
|
+
|
|
712
|
+
const targetPlaceholderId =
|
|
713
|
+
(resolveActivePlaceholderTargetId ? resolveActivePlaceholderTargetId() : null) ||
|
|
714
|
+
(explicitTargetId && (!currentSelectedEl || currentSelectedEl.id === explicitTargetId)
|
|
715
|
+
? explicitTargetId
|
|
716
|
+
: (currentSelectedEl && isImagePlaceholder(currentSelectedEl) ? currentSelectedEl.id : null))
|
|
717
|
+
|
|
718
|
+
if (targetPlaceholderId && replacePlaceholderElement) {
|
|
719
|
+
const replaced = replacePlaceholderElement(targetPlaceholderId, targetUrl, {
|
|
720
|
+
isVideo: isVid,
|
|
721
|
+
width: Number(rawW) || undefined,
|
|
722
|
+
height: Number(rawH) || undefined,
|
|
723
|
+
notifyMessage: isVid
|
|
724
|
+
? `已使用视频 "${formatMaterialTitle(meta.title, '高清视频', 12)}" 替换占位符`
|
|
725
|
+
: `已使用素材 "${formatMaterialTitle(meta.title, '图片', 12)}" 替换占位符图片`
|
|
726
|
+
})
|
|
727
|
+
if (replaced) return
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
let initialDimensions: { width?: number; height?: number } | undefined = undefined
|
|
698
731
|
if (rawW && rawH && rawW > 0 && rawH > 0) {
|
|
699
732
|
const maxWidth = 480
|
|
700
733
|
const maxHeight = 360
|
|
@@ -1359,7 +1359,7 @@ async function handleAudioFileChange(e: Event) {
|
|
|
1359
1359
|
</el-popover>
|
|
1360
1360
|
|
|
1361
1361
|
<!-- Chart Popover -->
|
|
1362
|
-
<el-popover trigger="click" placement="bottom-start" :width="
|
|
1362
|
+
<el-popover trigger="click" placement="bottom-start" :width="568" popper-class="chart-popover-popper"
|
|
1363
1363
|
v-model:visible="chartPopoverVisible" :show-arrow="false" :offset="2">
|
|
1364
1364
|
<template #reference>
|
|
1365
1365
|
<div class="toolbar-btn-stacked" :class="{ 'btn-active': chartPopoverVisible }" title="插入图表"
|