jvs-ppt-ui 0.0.15 → 0.0.16
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 +20301 -19823
- package/dist/lib/jvs-ppt-ui.umd.js +99 -99
- package/dist/lib/style.css +1 -1
- package/package.json +1 -1
- package/src/components/CanvasArea.vue +14 -115
- 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 +6 -3
- package/src/components/Toolbar.vue +1 -1
- package/src/components/canvas/elements/CanvasShapeElement.vue +91 -34
- 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 +2 -2
- package/src/components/sidebar/panels/SidebarTransitionPanel.vue +30 -19
- package/src/composables/canvas/useCanvasTransform.ts +24 -0
- package/src/composables/sidebar/useSidebarShapeFormat.ts +248 -17
- package/src/composables/useSlides.ts +12 -0
- package/src/style.css +4 -2
- package/src/utils/canvas/elementStyles.ts +22 -0
|
@@ -16,7 +16,9 @@ import {
|
|
|
16
16
|
hasElementBorderGradient,
|
|
17
17
|
getElementBorderGradientCss,
|
|
18
18
|
getGradientAngleDeg,
|
|
19
|
-
getSvgGradientCoords
|
|
19
|
+
getSvgGradientCoords,
|
|
20
|
+
isElementPatternTile,
|
|
21
|
+
getElementPatternTileSize
|
|
20
22
|
} from '../utils/canvas/elementStyles'
|
|
21
23
|
import {
|
|
22
24
|
getLineElementPath, getLineElementRenderPath, getLineDashArray, getSvgWidth, getSvgHeight, isEllipseShape
|
|
@@ -532,6 +534,22 @@ function getElementWidthHeight(el: any) {
|
|
|
532
534
|
return { width, height }
|
|
533
535
|
}
|
|
534
536
|
|
|
537
|
+
function getShapePatternTransform(el: any, isTriangle = false): string | undefined {
|
|
538
|
+
if (!isElementPatternTile(el)) return undefined
|
|
539
|
+
const dim = getElementWidthHeight(el)
|
|
540
|
+
const w = Math.max(1, dim.width || 100)
|
|
541
|
+
const h = Math.max(1, dim.height || 100)
|
|
542
|
+
if (isTriangle) {
|
|
543
|
+
return `scale(${+(100 / w).toFixed(4)}, ${+(100 / h).toFixed(4)})`
|
|
544
|
+
}
|
|
545
|
+
const vbW = el.viewBox ? el.viewBox[0] : 200
|
|
546
|
+
const vbH = el.viewBox ? el.viewBox[1] : 200
|
|
547
|
+
const bw = el.shapType === 'arc' ? 0 : (el.style?.borderWidth ? parseFloat(el.style.borderWidth) : 2)
|
|
548
|
+
const effW = Math.max(1, w - bw)
|
|
549
|
+
const effH = Math.max(1, h - bw)
|
|
550
|
+
return `scale(${+(vbW / effW).toFixed(4)}, ${+(vbH / effH).toFixed(4)})`
|
|
551
|
+
}
|
|
552
|
+
|
|
535
553
|
function parseColorString(fill: any, fallback = 'none'): string {
|
|
536
554
|
if (!fill) return fallback
|
|
537
555
|
if (typeof fill === 'string') return fill
|
|
@@ -1120,14 +1138,17 @@ function getSafeShapeText(el: any): string {
|
|
|
1120
1138
|
<svg v-if="el.path || (el.content && (el.content.trim().startsWith('M') || el.content.trim().startsWith('m')))"
|
|
1121
1139
|
:viewBox="`0 0 ${el.viewBox ? el.viewBox[0] : (el.width || 200)} ${el.viewBox ? el.viewBox[1] : (el.height || 200)}`"
|
|
1122
1140
|
preserveAspectRatio="none" style="width: 100%; height: 100%; display: block; overflow: visible;">
|
|
1123
|
-
<defs v-if="getElementPattern(el)">
|
|
1124
|
-
<pattern :id="`pres-master-pat-${slide.id || activeIndex}-${el.id}`" width="100%" height="100%" patternContentUnits="objectBoundingBox">
|
|
1125
|
-
<image :href="getElementPattern(el)" width="1" height="1" preserveAspectRatio="none" />
|
|
1126
|
-
</pattern>
|
|
1127
|
-
</defs>
|
|
1128
1141
|
<defs>
|
|
1129
|
-
<pattern v-if="getElementPattern(el)" :id="`pres-master-pat-${slide.id || activeIndex}-${el.id}`"
|
|
1130
|
-
|
|
1142
|
+
<pattern v-if="getElementPattern(el)" :id="`pres-master-pat-${slide.id || activeIndex}-${el.id}`"
|
|
1143
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : '100%'"
|
|
1144
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : '100%'"
|
|
1145
|
+
:patternUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
1146
|
+
:patternContentUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
1147
|
+
:patternTransform="getShapePatternTransform(el, false)">
|
|
1148
|
+
<image :href="getElementPattern(el)"
|
|
1149
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : 1"
|
|
1150
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : 1"
|
|
1151
|
+
preserveAspectRatio="none" />
|
|
1131
1152
|
</pattern>
|
|
1132
1153
|
<template v-if="getElementGradientConfig(el)">
|
|
1133
1154
|
<radialGradient v-if="getElementGradientConfig(el)!.path && getElementGradientConfig(el)!.path !== 'line'"
|
|
@@ -1169,7 +1190,9 @@ function getSafeShapeText(el: any): string {
|
|
|
1169
1190
|
<div v-else :style="{
|
|
1170
1191
|
backgroundColor: getElementPattern(el) ? 'transparent' : ((getElementGradientCss(el) || (getElementFill(el) !== undefined && getElementFill(el) !== 'none')) ? (getElementGradientCss(el) ? 'transparent' : getElementFill(el)) : (getElementFill(el) === 'none' ? 'transparent' : '#3b82f6')),
|
|
1171
1192
|
backgroundImage: getElementPattern(el) ? `url('${getElementPattern(el)}')` : (getElementGradientCss(el) || 'none'),
|
|
1172
|
-
backgroundSize: getElementPattern(el) ? 'cover' : undefined,
|
|
1193
|
+
backgroundSize: getElementPattern(el) ? (isElementPatternTile(el) ? `${getElementPatternTileSize(el).w}px ${getElementPatternTileSize(el).h}px` : 'cover') : undefined,
|
|
1194
|
+
backgroundPosition: getElementPattern(el) ? (isElementPatternTile(el) ? '0 0' : 'center center') : undefined,
|
|
1195
|
+
backgroundRepeat: getElementPattern(el) ? (isElementPatternTile(el) ? 'repeat' : 'no-repeat') : undefined,
|
|
1173
1196
|
width: '100%',
|
|
1174
1197
|
height: '100%',
|
|
1175
1198
|
borderRadius: el.style?.borderRadius || '0px',
|
|
@@ -1321,9 +1344,9 @@ function getSafeShapeText(el: any): string {
|
|
|
1321
1344
|
height: '100%',
|
|
1322
1345
|
backgroundColor: getElementPattern(el) ? 'transparent' : ((getElementGradientCss(el) || (getElementFill(el) !== undefined && getElementFill(el) !== 'none')) ? (getElementGradientCss(el) ? 'transparent' : getElementFill(el)) : (getElementFill(el) === 'none' ? 'transparent' : '#3b82f6')),
|
|
1323
1346
|
backgroundImage: getElementPattern(el) ? `url('${getElementPattern(el)}')` : (getElementGradientCss(el) || 'none'),
|
|
1324
|
-
backgroundSize: getElementPattern(el) ? 'cover' : undefined,
|
|
1325
|
-
backgroundPosition: getElementPattern(el) ? 'center center' : undefined,
|
|
1326
|
-
backgroundRepeat: getElementPattern(el) ? 'no-repeat' : undefined,
|
|
1347
|
+
backgroundSize: getElementPattern(el) ? (isElementPatternTile(el) ? `${getElementPatternTileSize(el).w}px ${getElementPatternTileSize(el).h}px` : 'cover') : undefined,
|
|
1348
|
+
backgroundPosition: getElementPattern(el) ? (isElementPatternTile(el) ? '0 0' : 'center center') : undefined,
|
|
1349
|
+
backgroundRepeat: getElementPattern(el) ? (isElementPatternTile(el) ? 'repeat' : 'no-repeat') : undefined,
|
|
1327
1350
|
borderRadius: '50%',
|
|
1328
1351
|
borderWidth: `${getElementBorderWidth(el)}px`,
|
|
1329
1352
|
borderStyle: el.style?.borderStyle || (el as any).borderType || 'solid',
|
|
@@ -1337,9 +1360,16 @@ function getSafeShapeText(el: any): string {
|
|
|
1337
1360
|
style="width: 100%; height: 100%; display: block; overflow: visible;"
|
|
1338
1361
|
:style="{ filter: (el.shadow && el.shadow.type === 'inner') ? `url(#pres-shape-inner-shadow-${el.id})` : '' }">
|
|
1339
1362
|
<defs>
|
|
1340
|
-
<pattern v-if="getElementPattern(el)" :id="`pres-main-shape-pattern-${el.id}`"
|
|
1341
|
-
|
|
1342
|
-
|
|
1363
|
+
<pattern v-if="getElementPattern(el)" :id="`pres-main-shape-pattern-${el.id}`"
|
|
1364
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : '100%'"
|
|
1365
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : '100%'"
|
|
1366
|
+
:patternUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
1367
|
+
:patternContentUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
1368
|
+
:patternTransform="getShapePatternTransform(el, true)">
|
|
1369
|
+
<image :href="getElementPattern(el)"
|
|
1370
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : 1"
|
|
1371
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : 1"
|
|
1372
|
+
preserveAspectRatio="none" />
|
|
1343
1373
|
</pattern>
|
|
1344
1374
|
<template v-if="getElementGradientConfig(el)">
|
|
1345
1375
|
<radialGradient
|
|
@@ -1394,9 +1424,16 @@ function getSafeShapeText(el: any): string {
|
|
|
1394
1424
|
<svg overflow="visible" style="width: 100%; height: 100%; display: block; overflow: visible;"
|
|
1395
1425
|
:style="{ filter: (el.shadow && el.shadow.type === 'inner') ? `url(#pres-shape-inner-shadow-${el.id})` : '' }">
|
|
1396
1426
|
<defs>
|
|
1397
|
-
<pattern v-if="getElementPattern(el)" :id="`pres-main-shape-pattern-${el.id}`"
|
|
1398
|
-
|
|
1399
|
-
|
|
1427
|
+
<pattern v-if="getElementPattern(el)" :id="`pres-main-shape-pattern-${el.id}`"
|
|
1428
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : '100%'"
|
|
1429
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : '100%'"
|
|
1430
|
+
:patternUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
1431
|
+
:patternContentUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
1432
|
+
:patternTransform="getShapePatternTransform(el, false)">
|
|
1433
|
+
<image :href="getElementPattern(el)"
|
|
1434
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : 1"
|
|
1435
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : 1"
|
|
1436
|
+
preserveAspectRatio="none" />
|
|
1400
1437
|
</pattern>
|
|
1401
1438
|
<template v-if="getElementGradientConfig(el)">
|
|
1402
1439
|
<radialGradient
|
|
@@ -1453,9 +1490,9 @@ function getSafeShapeText(el: any): string {
|
|
|
1453
1490
|
height: '100%',
|
|
1454
1491
|
backgroundColor: getElementPattern(el) ? 'transparent' : ((getElementGradientCss(el) || (getElementFill(el) !== undefined && getElementFill(el) !== 'none')) ? (getElementGradientCss(el) ? 'transparent' : getElementFill(el)) : (getElementFill(el) === 'none' ? 'transparent' : '#10b981')),
|
|
1455
1492
|
backgroundImage: getElementPattern(el) ? `url('${getElementPattern(el)}')` : (getElementGradientCss(el) || 'none'),
|
|
1456
|
-
backgroundSize: getElementPattern(el) ? 'cover' : undefined,
|
|
1457
|
-
backgroundPosition: getElementPattern(el) ? 'center center' : undefined,
|
|
1458
|
-
backgroundRepeat: getElementPattern(el) ? 'no-repeat' : undefined,
|
|
1493
|
+
backgroundSize: getElementPattern(el) ? (isElementPatternTile(el) ? `${getElementPatternTileSize(el).w}px ${getElementPatternTileSize(el).h}px` : 'cover') : undefined,
|
|
1494
|
+
backgroundPosition: getElementPattern(el) ? (isElementPatternTile(el) ? '0 0' : 'center center') : undefined,
|
|
1495
|
+
backgroundRepeat: getElementPattern(el) ? (isElementPatternTile(el) ? 'repeat' : 'no-repeat') : undefined,
|
|
1459
1496
|
borderRadius: el.style?.borderRadius !== undefined ? el.style.borderRadius : '0px',
|
|
1460
1497
|
borderWidth: `${getElementBorderWidth(el)}px`,
|
|
1461
1498
|
borderStyle: el.style?.borderStyle || (el as any).borderType || 'solid',
|
|
@@ -1765,9 +1802,9 @@ function getSafeShapeText(el: any): string {
|
|
|
1765
1802
|
height: '100%',
|
|
1766
1803
|
backgroundColor: getElementPattern(el) ? 'transparent' : ((getElementGradientCss(el) || (getElementFill(el) !== undefined && getElementFill(el) !== 'none')) ? (getElementGradientCss(el) ? 'transparent' : getElementFill(el)) : (getElementFill(el) === 'none' ? 'transparent' : '#3b82f6')),
|
|
1767
1804
|
backgroundImage: getElementPattern(el) ? `url('${getElementPattern(el)}')` : (getElementGradientCss(el) || 'none'),
|
|
1768
|
-
backgroundSize: getElementPattern(el) ? 'cover' : undefined,
|
|
1769
|
-
backgroundPosition: getElementPattern(el) ? 'center center' : undefined,
|
|
1770
|
-
backgroundRepeat: getElementPattern(el) ? 'no-repeat' : undefined,
|
|
1805
|
+
backgroundSize: getElementPattern(el) ? (isElementPatternTile(el) ? `${getElementPatternTileSize(el).w}px ${getElementPatternTileSize(el).h}px` : 'cover') : undefined,
|
|
1806
|
+
backgroundPosition: getElementPattern(el) ? (isElementPatternTile(el) ? '0 0' : 'center center') : undefined,
|
|
1807
|
+
backgroundRepeat: getElementPattern(el) ? (isElementPatternTile(el) ? 'repeat' : 'no-repeat') : undefined,
|
|
1771
1808
|
borderRadius: '50%',
|
|
1772
1809
|
borderWidth: `${getElementBorderWidth(el)}px`,
|
|
1773
1810
|
borderStyle: el.style?.borderStyle || (el as any).borderType || 'solid',
|
|
@@ -1781,9 +1818,16 @@ function getSafeShapeText(el: any): string {
|
|
|
1781
1818
|
style="width: 100%; height: 100%; display: block; overflow: visible;"
|
|
1782
1819
|
:style="{ filter: (el.shadow && el.shadow.type === 'inner') ? `url(#pres-shape-inner-shadow-${el.id})` : '' }">
|
|
1783
1820
|
<defs>
|
|
1784
|
-
<pattern v-if="getElementPattern(el)" :id="`pres-shape-pattern-${el.id}`"
|
|
1785
|
-
|
|
1786
|
-
|
|
1821
|
+
<pattern v-if="getElementPattern(el)" :id="`pres-shape-pattern-${el.id}`"
|
|
1822
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : '100%'"
|
|
1823
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : '100%'"
|
|
1824
|
+
:patternUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
1825
|
+
:patternContentUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
1826
|
+
:patternTransform="getShapePatternTransform(el, true)">
|
|
1827
|
+
<image :href="getElementPattern(el)"
|
|
1828
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : 1"
|
|
1829
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : 1"
|
|
1830
|
+
preserveAspectRatio="none" />
|
|
1787
1831
|
</pattern>
|
|
1788
1832
|
<template v-if="getElementGradientConfig(el)">
|
|
1789
1833
|
<radialGradient
|
|
@@ -1838,9 +1882,16 @@ function getSafeShapeText(el: any): string {
|
|
|
1838
1882
|
<svg overflow="visible" style="width: 100%; height: 100%; display: block; overflow: visible;"
|
|
1839
1883
|
:style="{ filter: (el.shadow && el.shadow.type === 'inner') ? `url(#pres-shape-inner-shadow-${el.id})` : '' }">
|
|
1840
1884
|
<defs>
|
|
1841
|
-
<pattern v-if="getElementPattern(el)" :id="`pres-shape-pattern-${el.id}`"
|
|
1842
|
-
|
|
1843
|
-
|
|
1885
|
+
<pattern v-if="getElementPattern(el)" :id="`pres-shape-pattern-${el.id}`"
|
|
1886
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : '100%'"
|
|
1887
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : '100%'"
|
|
1888
|
+
:patternUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
1889
|
+
:patternContentUnits="isElementPatternTile(el) ? 'userSpaceOnUse' : 'objectBoundingBox'"
|
|
1890
|
+
:patternTransform="getShapePatternTransform(el, false)">
|
|
1891
|
+
<image :href="getElementPattern(el)"
|
|
1892
|
+
:width="isElementPatternTile(el) ? getElementPatternTileSize(el).w : 1"
|
|
1893
|
+
:height="isElementPatternTile(el) ? getElementPatternTileSize(el).h : 1"
|
|
1894
|
+
preserveAspectRatio="none" />
|
|
1844
1895
|
</pattern>
|
|
1845
1896
|
<template v-if="getElementGradientConfig(el)">
|
|
1846
1897
|
<radialGradient
|
|
@@ -1897,9 +1948,9 @@ function getSafeShapeText(el: any): string {
|
|
|
1897
1948
|
height: '100%',
|
|
1898
1949
|
backgroundColor: getElementPattern(el) ? 'transparent' : ((getElementGradientCss(el) || getElementFill(el) !== undefined) ? (getElementGradientCss(el) ? 'transparent' : getElementFill(el)) : (getElementFill(el) === 'none' ? 'transparent' : '#10b981')),
|
|
1899
1950
|
backgroundImage: getElementPattern(el) ? `url('${getElementPattern(el)}')` : (getElementGradientCss(el) || 'none'),
|
|
1900
|
-
backgroundSize: getElementPattern(el) ? 'cover' : undefined,
|
|
1901
|
-
backgroundPosition: getElementPattern(el) ? 'center center' : undefined,
|
|
1902
|
-
backgroundRepeat: getElementPattern(el) ? 'no-repeat' : undefined,
|
|
1951
|
+
backgroundSize: getElementPattern(el) ? (isElementPatternTile(el) ? `${getElementPatternTileSize(el).w}px ${getElementPatternTileSize(el).h}px` : 'cover') : undefined,
|
|
1952
|
+
backgroundPosition: getElementPattern(el) ? (isElementPatternTile(el) ? '0 0' : 'center center') : undefined,
|
|
1953
|
+
backgroundRepeat: getElementPattern(el) ? (isElementPatternTile(el) ? 'repeat' : 'no-repeat') : undefined,
|
|
1903
1954
|
borderRadius: '4px',
|
|
1904
1955
|
borderWidth: `${getElementBorderWidth(el)}px`,
|
|
1905
1956
|
borderStyle: el.style?.borderStyle || (el as any).borderType || 'solid',
|
|
@@ -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',
|
|
@@ -916,6 +916,9 @@ const {
|
|
|
916
916
|
gradientDirection,
|
|
917
917
|
updateElementGradient,
|
|
918
918
|
shapePatternFill,
|
|
919
|
+
shapePatternType,
|
|
920
|
+
shapePatternFg,
|
|
921
|
+
shapePatternBg,
|
|
919
922
|
handleShapePatternUpload,
|
|
920
923
|
clearShapePatternFill,
|
|
921
924
|
styleBorderStyle,
|
|
@@ -1709,9 +1712,9 @@ function handleUndockToPopover() {
|
|
|
1709
1712
|
v-model:gradient-angle="gradientAngle"
|
|
1710
1713
|
@update:element-gradient="updateElementGradient"
|
|
1711
1714
|
v-model:shape-pattern-fill="shapePatternFill"
|
|
1712
|
-
:shape-pattern-type="
|
|
1713
|
-
:shape-pattern-fg="
|
|
1714
|
-
:shape-pattern-bg="
|
|
1715
|
+
v-model:shape-pattern-type="shapePatternType"
|
|
1716
|
+
v-model:shape-pattern-fg="shapePatternFg"
|
|
1717
|
+
v-model:shape-pattern-bg="shapePatternBg"
|
|
1715
1718
|
:fill-opacity="fillAlpha"
|
|
1716
1719
|
:is-border-enabled="enableBorder"
|
|
1717
1720
|
v-model:is-border-expanded="isBorderExpanded"
|
|
@@ -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="插入图表"
|