返回 oh-my-ppt
index-transition.ts
根目录 / src / shared / index-transition.ts
1 export const INDEX_TRANSITION_TYPES = [
2 'none',
3 'fade',
4 'slide-left',
5 'slide-up',
6 'push',
7 'wipe',
8 'zoom',
9 'flip',
10 'stack',
11 'rotate',
12 'cube',
13 'cover-flow',
14 'blur',
15 'iris',
16 'swing',
17 'center-reveal'
18 ] as const
19
20 export type IndexTransitionType = (typeof INDEX_TRANSITION_TYPES)[number]
21
22 export interface IndexTransitionConfig {
23 type: IndexTransitionType
24 durationMs: number
25 }
26
27 export const DEFAULT_INDEX_TRANSITION_CONFIG: IndexTransitionConfig = {
28 type: 'fade',
29 durationMs: 600
30 }
31
32 export const INDEX_TRANSITION_PRESETS: ReadonlyArray<
33 IndexTransitionConfig & { labelKey: string }
34 > = [
35 { type: 'none', durationMs: 0, labelKey: 'sessionDetail.indexTransitionNone' },
36 { type: 'fade', durationMs: 600, labelKey: 'sessionDetail.indexTransitionFade' },
37 { type: 'slide-left', durationMs: 560, labelKey: 'sessionDetail.indexTransitionSlideLeft' },
38 { type: 'slide-up', durationMs: 560, labelKey: 'sessionDetail.indexTransitionSlideUp' },
39 { type: 'push', durationMs: 600, labelKey: 'sessionDetail.indexTransitionPush' },
40 { type: 'wipe', durationMs: 600, labelKey: 'sessionDetail.indexTransitionWipe' },
41 { type: 'zoom', durationMs: 580, labelKey: 'sessionDetail.indexTransitionZoom' },
42 { type: 'flip', durationMs: 680, labelKey: 'sessionDetail.indexTransitionFlip' },
43 { type: 'stack', durationMs: 640, labelKey: 'sessionDetail.indexTransitionStack' },
44 { type: 'rotate', durationMs: 660, labelKey: 'sessionDetail.indexTransitionRotate' },
45 { type: 'cube', durationMs: 720, labelKey: 'sessionDetail.indexTransitionCube' },
46 { type: 'cover-flow', durationMs: 720, labelKey: 'sessionDetail.indexTransitionCoverFlow' },
47 { type: 'blur', durationMs: 640, labelKey: 'sessionDetail.indexTransitionBlur' },
48 { type: 'iris', durationMs: 720, labelKey: 'sessionDetail.indexTransitionIris' },
49 { type: 'swing', durationMs: 700, labelKey: 'sessionDetail.indexTransitionSwing' },
50 { type: 'center-reveal', durationMs: 680, labelKey: 'sessionDetail.indexTransitionCenterReveal' }
51 ]
52
53 export function isIndexTransitionType(value: unknown): value is IndexTransitionType {
54 return INDEX_TRANSITION_TYPES.includes(value as IndexTransitionType)
55 }
56
57 export function normalizeIndexTransitionType(value: unknown): IndexTransitionType {
58 return isIndexTransitionType(value) ? value : DEFAULT_INDEX_TRANSITION_CONFIG.type
59 }
60
61 export function defaultDurationForIndexTransition(type: IndexTransitionType): number {
62 return (
63 INDEX_TRANSITION_PRESETS.find((preset) => preset.type === type)?.durationMs ??
64 DEFAULT_INDEX_TRANSITION_CONFIG.durationMs
65 )
66 }
67
68 export function clampIndexTransitionDuration(
69 type: IndexTransitionType,
70 value: unknown
71 ): number {
72 if (type === 'none') return 0
73 const numericValue = Number(value)
74 if (!Number.isFinite(numericValue)) return defaultDurationForIndexTransition(type)
75 return Math.max(120, Math.min(1200, Math.round(numericValue)))
76 }
77
78 export function normalizeIndexTransitionConfig(value: {
79 type?: unknown
80 durationMs?: unknown
81 }): IndexTransitionConfig {
82 const type = normalizeIndexTransitionType(value.type)
83 return {
84 type,
85 durationMs: clampIndexTransitionDuration(type, value.durationMs)
86 }
87 }
88
88 lines TYPESCRIPT