返回 oh-my-ppt
element-animation.ts
根目录 / src / shared / element-animation.ts
1 export const DATA_ANIM_SUPPORTED_TYPES = [
2 'fade',
3 'fade-up',
4 'fade-down',
5 'fade-left',
6 'fade-right',
7 'scale-in',
8 'slide-up',
9 'slide-down',
10 'slide-left',
11 'slide-right',
12 'fly-in',
13 'wipe',
14 'zoom-in',
15 'spin-in',
16 'grow-shrink-soft',
17 'grow-shrink',
18 'grow-shrink-strong',
19 'pulse-soft',
20 'pulse',
21 'pulse-strong',
22 'exit-fade',
23 'exit-scale',
24 'exit-zoom',
25 'exit-wipe',
26 'exit-fly',
27 'path'
28 ] as const
29
30 export type DataAnimType = (typeof DATA_ANIM_SUPPORTED_TYPES)[number]
31
32 export const DATA_ANIM_EDITABLE_TYPES = DATA_ANIM_SUPPORTED_TYPES.filter(
33 (type): type is Exclude<DataAnimType, 'path'> => type !== 'path'
34 )
35
36 export type ElementAnimationEditableType = (typeof DATA_ANIM_EDITABLE_TYPES)[number]
37
38 export const DATA_ANIM_FROM_VALUES = ['left', 'right', 'top', 'bottom', 'center'] as const
39 export type DataAnimFrom = (typeof DATA_ANIM_FROM_VALUES)[number]
40 export type ElementAnimationEditableFrom = Exclude<DataAnimFrom, 'center'>
41
42 export const DATA_ANIM_TRIGGERS = ['load', 'with', 'after', 'click'] as const
43 export type DataAnimTrigger = (typeof DATA_ANIM_TRIGGERS)[number]
44 export type DataAnimPptxTrigger = Extract<DataAnimTrigger, 'load' | 'click'>
45
46 export const DATA_ANIM_SEQUENCES = ['with', 'after'] as const
47 export type DataAnimSequence = (typeof DATA_ANIM_SEQUENCES)[number]
48
49 export interface ElementAnimationConfig {
50 type: DataAnimType
51 trigger: DataAnimTrigger
52 durationMs: number
53 from?: DataAnimFrom
54 delay?: string
55 staggerMs?: number
56 sequence?: DataAnimSequence
57 clickGroup?: string
58 path?: string
59 }
60
61 export interface ElementAnimationPatch {
62 type?: ElementAnimationEditableType | null
63 trigger?: 'load' | 'click'
64 durationMs?: number
65 from?: ElementAnimationEditableFrom | null
66 }
67
68 export function isDataAnimType(value: unknown): value is DataAnimType {
69 return DATA_ANIM_SUPPORTED_TYPES.includes(value as DataAnimType)
70 }
71
72 export function isDataAnimTrigger(value: unknown): value is DataAnimTrigger {
73 return DATA_ANIM_TRIGGERS.includes(value as DataAnimTrigger)
74 }
75
76 export function isDataAnimFrom(value: unknown): value is DataAnimFrom {
77 return DATA_ANIM_FROM_VALUES.includes(value as DataAnimFrom)
78 }
79
80 export function isDataAnimSequence(value: unknown): value is DataAnimSequence {
81 return DATA_ANIM_SEQUENCES.includes(value as DataAnimSequence)
82 }
83
84 /**
85 * Normalize data-anim-trigger to a canonical value.
86 * Tolerates PowerPoint-style legacy aliases (on-click / after-previous / with-previous)
87 * so old/hand-edited pages stay editable. Returns null for truly invalid values.
88 */
89 export function normalizeDataAnimTrigger(
90 value: string | undefined | null
91 ): DataAnimTrigger | null {
92 const normalized = (value || '').trim().toLowerCase()
93 if (normalized === 'on-click' || normalized === 'click') return 'click'
94 if (normalized === 'after-previous' || normalized === 'after') return 'after'
95 if (normalized === 'with-previous' || normalized === 'with') return 'with'
96 if (normalized === 'load') return 'load'
97 return null
98 }
99
100 export function isElementAnimationEditableType(
101 value: unknown
102 ): value is ElementAnimationEditableType {
103 return DATA_ANIM_EDITABLE_TYPES.includes(value as ElementAnimationEditableType)
104 }
105
106 export function isElementAnimationEditableFrom(
107 value: unknown
108 ): value is ElementAnimationEditableFrom {
109 return ['left', 'right', 'top', 'bottom'].includes(value as string)
110 }
111
111 lines TYPESCRIPT