chore: pptxtojson update

This commit is contained in:
zxc 2025-04-13 20:09:40 +08:00
parent fd7a87383d
commit c7e5c25ae8
3 changed files with 71 additions and 13 deletions

14
package-lock.json generated
View File

@ -24,7 +24,7 @@
"number-precision": "^1.6.0", "number-precision": "^1.6.0",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"pptxgenjs": "^3.12.0", "pptxgenjs": "^3.12.0",
"pptxtojson": "^1.3.0", "pptxtojson": "^1.3.1",
"prosemirror-commands": "^1.6.0", "prosemirror-commands": "^1.6.0",
"prosemirror-dropcursor": "^1.8.1", "prosemirror-dropcursor": "^1.8.1",
"prosemirror-gapcursor": "^1.3.2", "prosemirror-gapcursor": "^1.3.2",
@ -4177,9 +4177,9 @@
} }
}, },
"node_modules/pptxtojson": { "node_modules/pptxtojson": {
"version": "1.3.0", "version": "1.3.1",
"resolved": "https://registry.npmmirror.com/pptxtojson/-/pptxtojson-1.3.0.tgz", "resolved": "https://registry.npmmirror.com/pptxtojson/-/pptxtojson-1.3.1.tgz",
"integrity": "sha512-bLV7v+feumB08iMCRT2JORKpa95Pl54t5LyfweYHwvRxhT3BUSr1Qw3Kz4cx5l/EDKF0LElphPodxxvYjwgu5w==", "integrity": "sha512-+FcSS70PTkgdlExXCEUoNL2DZcySueonyYpnQANeD6BW1AX8313o6zF71t5wN7tnO1cxh1p0/J90fBV5yMzTCA==",
"dependencies": { "dependencies": {
"jszip": "^3.10.1", "jszip": "^3.10.1",
"tinycolor2": "1.6.0", "tinycolor2": "1.6.0",
@ -8393,9 +8393,9 @@
} }
}, },
"pptxtojson": { "pptxtojson": {
"version": "1.3.0", "version": "1.3.1",
"resolved": "https://registry.npmmirror.com/pptxtojson/-/pptxtojson-1.3.0.tgz", "resolved": "https://registry.npmmirror.com/pptxtojson/-/pptxtojson-1.3.1.tgz",
"integrity": "sha512-bLV7v+feumB08iMCRT2JORKpa95Pl54t5LyfweYHwvRxhT3BUSr1Qw3Kz4cx5l/EDKF0LElphPodxxvYjwgu5w==", "integrity": "sha512-+FcSS70PTkgdlExXCEUoNL2DZcySueonyYpnQANeD6BW1AX8313o6zF71t5wN7tnO1cxh1p0/J90fBV5yMzTCA==",
"requires": { "requires": {
"jszip": "^3.10.1", "jszip": "^3.10.1",
"tinycolor2": "1.6.0", "tinycolor2": "1.6.0",

View File

@ -29,7 +29,7 @@
"number-precision": "^1.6.0", "number-precision": "^1.6.0",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"pptxgenjs": "^3.12.0", "pptxgenjs": "^3.12.0",
"pptxtojson": "^1.3.0", "pptxtojson": "^1.3.1",
"prosemirror-commands": "^1.6.0", "prosemirror-commands": "^1.6.0",
"prosemirror-dropcursor": "^1.8.1", "prosemirror-dropcursor": "^1.8.1",
"prosemirror-gapcursor": "^1.3.2", "prosemirror-gapcursor": "^1.3.2",

View File

@ -1,6 +1,6 @@
import { ref } from 'vue' import { ref } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { parse, type Shape, type Element, type ChartItem } from 'pptxtojson' import { parse, type Shape, type Element, type ChartItem, type BaseElement } from 'pptxtojson'
import { nanoid } from 'nanoid' import { nanoid } from 'nanoid'
import { useSlidesStore } from '@/store' import { useSlidesStore } from '@/store'
import { decrypt } from '@/utils/crypto' import { decrypt } from '@/utils/crypto'
@ -18,11 +18,14 @@ import type {
SlideBackground, SlideBackground,
PPTShapeElement, PPTShapeElement,
PPTLineElement, PPTLineElement,
PPTImageElement,
ShapeTextAlign, ShapeTextAlign,
PPTTextElement, PPTTextElement,
ChartOptions, ChartOptions,
Gradient, Gradient,
PPTElement,
} from '@/types/slides' } from '@/types/slides'
import { getElementListRange } from '@/utils/element'
const convertFontSizePtToPx = (html: string, ratio: number) => { const convertFontSizePtToPx = (html: string, ratio: number) => {
return html.replace(/font-size:\s*([\d.]+)pt/g, (match, p1) => { return html.replace(/font-size:\s*([\d.]+)pt/g, (match, p1) => {
@ -109,6 +112,25 @@ export default () => {
return data return data
} }
const flipGroupElements = (elements: BaseElement[], axis: 'x' | 'y') => {
const minX = Math.min(...elements.map(el => el.left))
const maxX = Math.max(...elements.map(el => el.left + el.width))
const minY = Math.min(...elements.map(el => el.top))
const maxY = Math.max(...elements.map(el => el.top + el.height))
const centerX = (minX + maxX) / 2
const centerY = (minY + maxY) / 2
return elements.map(element => {
const newElement = { ...element }
if (axis === 'y') newElement.left = 2 * centerX - element.left - element.width
if (axis === 'x') newElement.top = 2 * centerY - element.top - element.height
return newElement
})
}
const calculateRotatedPosition = ( const calculateRotatedPosition = (
x: number, x: number,
y: number, y: number,
@ -259,7 +281,7 @@ export default () => {
slide.elements.push(textEl) slide.elements.push(textEl)
} }
else if (el.type === 'image') { else if (el.type === 'image') {
slide.elements.push({ const element: PPTImageElement = {
type: 'image', type: 'image',
id: nanoid(10), id: nanoid(10),
src: el.src, src: el.src,
@ -271,7 +293,37 @@ export default () => {
rotate: el.rotate, rotate: el.rotate,
flipH: el.isFlipH, flipH: el.isFlipH,
flipV: el.isFlipV, flipV: el.isFlipV,
}) }
if (el.borderWidth) {
element.outline = {
color: el.borderColor,
width: +(el.borderWidth * ratio).toFixed(2),
style: el.borderType,
}
}
const clipShapeTypes = ['roundRect', 'ellipse', 'triangle', 'rhombus', 'pentagon', 'hexagon', 'heptagon', 'octagon', 'parallelogram', 'trapezoid']
if (el.rect) {
element.clip = {
shape: (el.geom && clipShapeTypes.includes(el.geom)) ? el.geom : 'rect',
range: [
[
el.rect.l || 0,
el.rect.t || 0,
],
[
100 - (el.rect.r || 0),
100 - (el.rect.b || 0),
],
]
}
}
else if (el.geom && clipShapeTypes.includes(el.geom)) {
element.clip = {
shape: el.geom,
range: [[0, 0], [100, 100]]
}
}
slide.elements.push(element)
} }
else if (el.type === 'math') { else if (el.type === 'math') {
slide.elements.push({ slide.elements.push({
@ -562,7 +614,7 @@ export default () => {
}) })
} }
else if (el.type === 'group') { else if (el.type === 'group') {
const elements = el.elements.map(_el => { let elements: BaseElement[] = el.elements.map(_el => {
let left = _el.left + originLeft let left = _el.left + originLeft
let top = _el.top + originTop let top = _el.top + originTop
@ -572,12 +624,18 @@ export default () => {
top = y top = y
} }
return { const element = {
..._el, ..._el,
left, left,
top, top,
} }
if (el.isFlipH && 'isFlipH' in element) element.isFlipH = true
if (el.isFlipV && 'isFlipV' in element) element.isFlipV = true
return element
}) })
if (el.isFlipH) elements = flipGroupElements(elements, 'y')
if (el.isFlipV) elements = flipGroupElements(elements, 'x')
parseElements(elements) parseElements(elements)
} }
else if (el.type === 'diagram') { else if (el.type === 'diagram') {