返回 oh-my-ppt
elementEditUtils.ts
1 import type {
2 EditableElementSnapshot,
3 EditSelectionPayload
4 } from '@arcsin1/presentation-editor-runtime'
5 import type { ElementEditDraft } from './types'
6
7 export const EMPTY_ELEMENT_DRAFT: ElementEditDraft = {
8 html: '',
9 text: '',
10 color: '#34402c',
11 fontSize: '',
12 fontWeight: '400',
13 textAlign: 'left',
14 layoutX: '',
15 layoutY: '',
16 layoutWidth: '',
17 layoutHeight: '',
18 layoutZIndex: '',
19 opacity: '1',
20 backgroundColor: '#ffffff',
21 objectFit: 'contain',
22 alt: '',
23 poster: '',
24 controls: false,
25 muted: false,
26 loop: false,
27 autoplay: false,
28 playsInline: true,
29 preload: 'metadata',
30 artTextTemplateId: '',
31 formulaLatex: '',
32 formulaHtml: '',
33 formulaDisplayMode: false,
34 chartType: 'bar',
35 chartTitle: '',
36 chartLabels: '',
37 chartValues: '',
38 chartDataJson: '',
39 chartPrimaryColor: '#5d6b4d',
40 chartAccentColor: '#8fbc8f',
41 chartTextColor: '#2f3b28',
42 chartSmooth: true,
43 chartHorizontal: false,
44 chartStacked: false,
45 chartAreaFill: true,
46 chartShowPoints: true,
47 chartShowLegend: false,
48 chartDoughnutCutout: '58',
49 chartRadarFill: true,
50 chartConfigJson: ''
51 }
52
53 export function rgbToHex(value: string | undefined): string {
54 const text = String(value || '').trim()
55 if (/^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(text)) return text
56 const match = text.match(/^rgba?\(\s*(\d{1,3})[\s,]+(\d{1,3})[\s,]+(\d{1,3})/i)
57 if (!match) return '#34402c'
58 const toHex = (part: string): string =>
59 Math.max(0, Math.min(255, Number(part) || 0))
60 .toString(16)
61 .padStart(2, '0')
62 return `#${toHex(match[1])}${toHex(match[2])}${toHex(match[3])}`
63 }
64
65 export function fontSizeToNumber(value: string | undefined): string {
66 const parsed = Number(String(value || '').replace(/px$/i, ''))
67 return Number.isFinite(parsed) && parsed > 0 ? String(Math.round(parsed)) : ''
68 }
69
70 export function normalizeFontWeight(value: string | undefined): string {
71 const parsed = Number(value)
72 if (!Number.isFinite(parsed)) return value === 'bold' ? '700' : '400'
73 return String(Math.max(300, Math.min(800, Math.round(parsed / 100) * 100)))
74 }
75
76 export function normalizeTextAlign(value: string | undefined): string {
77 const text = String(value || '').trim()
78 if (text === 'center' || text === 'right' || text === 'justify') return text
79 return 'left'
80 }
81
82 export function opacityToInput(value: string | undefined): string {
83 const parsed = Number(value)
84 return Number.isFinite(parsed) ? String(Math.max(0, Math.min(1, parsed))) : '1'
85 }
86
87 export function buildSelectedElementFromSnapshot(args: {
88 selector: string
89 blockId?: string
90 snapshot: EditableElementSnapshot
91 }): EditSelectionPayload {
92 const { selector, blockId, snapshot } = args
93 const rawZIndex = snapshot.computed.zIndex || ''
94 const zIndex = rawZIndex && rawZIndex !== 'auto' ? parseInt(rawZIndex, 10) : undefined
95 return {
96 selector,
97 blockId,
98 label: snapshot.label,
99 elementTag: snapshot.elementTag,
100 elementText: snapshot.elementText,
101 kind: snapshot.kind,
102 capabilities: snapshot.capabilities,
103 snapshot: {
104 ...snapshot,
105 selector,
106 blockId
107 },
108 isText: Boolean(snapshot.text?.editable),
109 text: snapshot.text?.value || '',
110 html: snapshot.text?.html || '',
111 style: {
112 color: snapshot.computed.color || '',
113 fontSize: snapshot.computed.fontSize || '',
114 fontWeight: snapshot.computed.fontWeight || '',
115 textAlign: normalizeTextAlign(snapshot.computed.textAlign),
116 lineHeight: snapshot.computed.lineHeight || '',
117 backgroundColor: snapshot.computed.svgPaintColor || snapshot.computed.backgroundColor || ''
118 },
119 bounds: snapshot.metrics.viewport,
120 viewportBounds: snapshot.metrics.viewport,
121 pageBounds: snapshot.metrics.page,
122 translateX: snapshot.metrics.translateX,
123 translateY: snapshot.metrics.translateY,
124 zIndex: Number.isFinite(zIndex) ? zIndex : undefined,
125 editability: { x: true, y: true, width: true, height: true }
126 }
127 }
128
128 lines TYPESCRIPT