animot-presenter 0.5.25 → 0.6.0

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.
@@ -7,6 +7,13 @@ export declare function getEasingFn(name?: string): (t: number) => number;
7
7
  export declare function interpolateColor(color1: string, color2: string, progress: number): string;
8
8
  export declare function hashFraction(str: string, salt?: number): number;
9
9
  export declare function getFloatAnimName(direction: string, seed: string): string;
10
+ export declare function entranceRuntimeKeyframe(mode: string | undefined): string | null;
11
+ export declare function exitRuntimeKeyframe(mode: string | undefined): string | null;
12
+ export declare function emphasisKeyframeName(mode: string | undefined): string | null;
13
+ export declare function getIdleAnimName(cfg: {
14
+ preset?: string;
15
+ direction?: string;
16
+ } | undefined | null, seed: string): string;
10
17
  export declare function computeFloatAmp(cfg: {
11
18
  amplitude: number;
12
19
  amplitudeRandomness?: number;
@@ -61,6 +61,70 @@ export function getFloatAnimName(direction, seed) {
61
61
  return `float-both-${h % 4}`;
62
62
  }
63
63
  }
64
+ // ─── Phase 2: entrance/exit/emphasis preset → keyframe name ───
65
+ export function entranceRuntimeKeyframe(mode) {
66
+ switch (mode) {
67
+ case 'fade': return 'runtime-entrance-fade';
68
+ case 'slide-up': return 'runtime-entrance-slide-up';
69
+ case 'slide-down': return 'runtime-entrance-slide-down';
70
+ case 'slide-left': return 'runtime-entrance-slide-left';
71
+ case 'slide-right': return 'runtime-entrance-slide-right';
72
+ case 'pop': return 'runtime-entrance-pop';
73
+ case 'scale-in': return 'runtime-entrance-scale-in';
74
+ case 'rotate-in': return 'runtime-entrance-rotate-in';
75
+ case 'blur-in': return 'runtime-entrance-blur-in';
76
+ case 'rise': return 'runtime-entrance-rise';
77
+ case 'flip-x': return 'runtime-entrance-flip-x';
78
+ case 'flip-y': return 'runtime-entrance-flip-y';
79
+ case 'bounce-in': return 'runtime-entrance-bounce-in';
80
+ default: return null;
81
+ }
82
+ }
83
+ export function exitRuntimeKeyframe(mode) {
84
+ switch (mode) {
85
+ case 'fade': return 'runtime-exit-fade';
86
+ case 'slide-up': return 'runtime-exit-slide-up';
87
+ case 'slide-down': return 'runtime-exit-slide-down';
88
+ case 'slide-left': return 'runtime-exit-slide-left';
89
+ case 'slide-right': return 'runtime-exit-slide-right';
90
+ case 'pop': return 'runtime-exit-pop';
91
+ case 'scale-out': return 'runtime-exit-scale-out';
92
+ case 'rotate-out': return 'runtime-exit-rotate-out';
93
+ case 'blur-out': return 'runtime-exit-blur-out';
94
+ case 'sink': return 'runtime-exit-sink';
95
+ case 'flip-x': return 'runtime-exit-flip-x';
96
+ case 'flip-y': return 'runtime-exit-flip-y';
97
+ default: return null;
98
+ }
99
+ }
100
+ export function emphasisKeyframeName(mode) {
101
+ switch (mode) {
102
+ case 'pulse': return 'emphasis-pulse';
103
+ case 'shake': return 'emphasis-shake';
104
+ case 'flash': return 'emphasis-flash';
105
+ case 'wobble': return 'emphasis-wobble';
106
+ case 'glow-flash': return 'emphasis-glow-flash';
107
+ case 'bob-once': return 'emphasis-bob-once';
108
+ case 'tada': return 'emphasis-tada';
109
+ default: return null;
110
+ }
111
+ }
112
+ // Map an idle preset to a keyframe name. Falls back to direction-based picker
113
+ // when no preset is set, preserving behavior for pre-preset projects.
114
+ export function getIdleAnimName(cfg, seed) {
115
+ switch (cfg?.preset) {
116
+ case 'breathe': return 'idle-breathe';
117
+ case 'pulse': return 'idle-pulse';
118
+ case 'wiggle': return 'idle-wiggle';
119
+ case 'sway': return 'idle-sway';
120
+ case 'tilt': return 'idle-tilt';
121
+ case 'bob': return 'idle-bob';
122
+ case 'drift': return 'idle-drift';
123
+ case 'float':
124
+ default:
125
+ return getFloatAnimName(cfg?.direction ?? 'vertical', seed);
126
+ }
127
+ }
64
128
  export function computeFloatAmp(cfg, seed) {
65
129
  const r = cfg.amplitudeRandomness ?? 0;
66
130
  if (r === 0)
@@ -47,6 +47,176 @@
47
47
  100% { translate: 0 0; }
48
48
  }
49
49
 
50
+ /* ───── Idle-preset motion shapes ───── */
51
+ @keyframes idle-breathe {
52
+ 0%, 100% { scale: 1; }
53
+ 50% { scale: var(--float-amp-scale, 1.05); }
54
+ }
55
+
56
+ @keyframes idle-pulse {
57
+ 0%, 100% { scale: 1; }
58
+ 45% { scale: var(--float-amp-scale, 1.05); }
59
+ 55% { scale: var(--float-amp-scale, 1.05); }
60
+ }
61
+
62
+ @keyframes idle-wiggle {
63
+ 0%, 100% { translate: 0 0; rotate: 0deg; }
64
+ 25% { translate: calc(-0.4 * var(--float-amp, 10px)) 0; rotate: calc(-0.5 * var(--float-amp-rot, 5deg)); }
65
+ 50% { translate: 0 0; rotate: 0deg; }
66
+ 75% { translate: calc(0.4 * var(--float-amp, 10px)) 0; rotate: calc(0.5 * var(--float-amp-rot, 5deg)); }
67
+ }
68
+
69
+ @keyframes idle-sway {
70
+ 0%, 100% { rotate: calc(-1 * var(--float-amp-rot, 5deg)); }
71
+ 50% { rotate: var(--float-amp-rot, 5deg); }
72
+ }
73
+
74
+ @keyframes idle-tilt {
75
+ 0%, 100% { transform: skewX(0deg); }
76
+ 50% { transform: skewX(var(--float-amp-rot, 5deg)); }
77
+ }
78
+
79
+ @keyframes idle-bob {
80
+ 0%, 100% { translate: 0 0; }
81
+ 50% { translate: 0 calc(-1 * var(--float-amp, 10px)); }
82
+ }
83
+
84
+ @keyframes idle-drift {
85
+ 0% { translate: 0 0; }
86
+ 25% { translate: calc(0.5 * var(--float-amp, 10px)) calc(-0.3 * var(--float-amp, 10px)); }
87
+ 50% { translate: calc(0.1 * var(--float-amp, 10px)) calc(0.5 * var(--float-amp, 10px)); }
88
+ 75% { translate: calc(-0.4 * var(--float-amp, 10px)) calc(-0.2 * var(--float-amp, 10px)); }
89
+ 100% { translate: 0 0; }
90
+ }
91
+
92
+ /* ───── Phase 2: emphasis ───── */
93
+ @keyframes emphasis-pulse {
94
+ 0%, 100% { transform: scale(1); }
95
+ 50% { transform: scale(1.06); }
96
+ }
97
+ @keyframes emphasis-shake {
98
+ 0%, 100% { transform: translateX(0); }
99
+ 20% { transform: translateX(-4px); }
100
+ 40% { transform: translateX(4px); }
101
+ 60% { transform: translateX(-3px); }
102
+ 80% { transform: translateX(3px); }
103
+ }
104
+ @keyframes emphasis-flash {
105
+ 0%, 100% { opacity: 1; }
106
+ 50% { opacity: 0.55; }
107
+ }
108
+ @keyframes emphasis-wobble {
109
+ 0%, 100% { transform: rotate(0deg); }
110
+ 25% { transform: rotate(-4deg); }
111
+ 75% { transform: rotate(4deg); }
112
+ }
113
+ @keyframes emphasis-glow-flash {
114
+ 0%, 100% { filter: drop-shadow(0 0 0 rgba(124, 58, 237, 0)); }
115
+ 50% { filter: drop-shadow(0 0 16px rgba(124, 58, 237, 0.85)); }
116
+ }
117
+ @keyframes emphasis-bob-once {
118
+ 0% { transform: translateY(0); }
119
+ 30% { transform: translateY(-12px); }
120
+ 60% { transform: translateY(0); }
121
+ 100% { transform: translateY(0); }
122
+ }
123
+ @keyframes emphasis-tada {
124
+ 0% { transform: scale(1) rotate(0deg); }
125
+ 10%, 20% { transform: scale(0.95) rotate(-3deg); }
126
+ 30%, 50%, 70%, 90% { transform: scale(1.08) rotate(3deg); }
127
+ 40%, 60%, 80% { transform: scale(1.08) rotate(-3deg); }
128
+ 100% { transform: scale(1) rotate(0deg); }
129
+ }
130
+
131
+ /* ───── Phase 2: runtime entrance ───── */
132
+ @keyframes runtime-entrance-fade {
133
+ 0% { opacity: 0; } 100% { opacity: 1; }
134
+ }
135
+ @keyframes runtime-entrance-slide-up {
136
+ 0% { translate: 0 60px; opacity: 0; } 100% { translate: 0 0; opacity: 1; }
137
+ }
138
+ @keyframes runtime-entrance-slide-down {
139
+ 0% { translate: 0 -60px; opacity: 0; } 100% { translate: 0 0; opacity: 1; }
140
+ }
141
+ @keyframes runtime-entrance-slide-left {
142
+ 0% { translate: 60px 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; }
143
+ }
144
+ @keyframes runtime-entrance-slide-right {
145
+ 0% { translate: -60px 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; }
146
+ }
147
+ @keyframes runtime-entrance-pop {
148
+ 0% { scale: 0.4; opacity: 0; }
149
+ 60% { scale: 1.08; opacity: 1; }
150
+ 100% { scale: 1; opacity: 1; }
151
+ }
152
+ @keyframes runtime-entrance-scale-in {
153
+ 0% { scale: 0.7; opacity: 0; } 100% { scale: 1; opacity: 1; }
154
+ }
155
+ @keyframes runtime-entrance-rotate-in {
156
+ 0% { rotate: -15deg; scale: 0.8; opacity: 0; }
157
+ 100% { rotate: 0deg; scale: 1; opacity: 1; }
158
+ }
159
+ @keyframes runtime-entrance-blur-in {
160
+ 0% { filter: blur(20px); opacity: 0; } 100% { filter: blur(0); opacity: 1; }
161
+ }
162
+ @keyframes runtime-entrance-rise {
163
+ 0% { translate: 0 30px; opacity: 0; } 100% { translate: 0 0; opacity: 1; }
164
+ }
165
+ @keyframes runtime-entrance-flip-x {
166
+ 0% { opacity: 0; } 100% { opacity: 1; }
167
+ }
168
+ @keyframes runtime-entrance-flip-y {
169
+ 0% { opacity: 0; } 100% { opacity: 1; }
170
+ }
171
+ @keyframes runtime-entrance-bounce-in {
172
+ 0% { scale: 0.3; opacity: 0; }
173
+ 50% { scale: 1.15; opacity: 1; }
174
+ 75% { scale: 0.92; }
175
+ 90% { scale: 1.04; }
176
+ 100% { scale: 1; opacity: 1; }
177
+ }
178
+
179
+ /* ───── Phase 2: runtime exit ───── */
180
+ @keyframes runtime-exit-fade {
181
+ 0% { opacity: 1; } 100% { opacity: 0; }
182
+ }
183
+ @keyframes runtime-exit-slide-up {
184
+ 0% { translate: 0 0; opacity: 1; } 100% { translate: 0 -60px; opacity: 0; }
185
+ }
186
+ @keyframes runtime-exit-slide-down {
187
+ 0% { translate: 0 0; opacity: 1; } 100% { translate: 0 60px; opacity: 0; }
188
+ }
189
+ @keyframes runtime-exit-slide-left {
190
+ 0% { translate: 0 0; opacity: 1; } 100% { translate: -60px 0; opacity: 0; }
191
+ }
192
+ @keyframes runtime-exit-slide-right {
193
+ 0% { translate: 0 0; opacity: 1; } 100% { translate: 60px 0; opacity: 0; }
194
+ }
195
+ @keyframes runtime-exit-pop {
196
+ 0% { scale: 1; opacity: 1; }
197
+ 50% { scale: 1.25; opacity: 1; }
198
+ 100% { scale: 1.6; opacity: 0; }
199
+ }
200
+ @keyframes runtime-exit-scale-out {
201
+ 0% { scale: 1; opacity: 1; } 100% { scale: 0.5; opacity: 0; }
202
+ }
203
+ @keyframes runtime-exit-rotate-out {
204
+ 0% { rotate: 0deg; scale: 1; opacity: 1; }
205
+ 100% { rotate: 15deg; scale: 0.8; opacity: 0; }
206
+ }
207
+ @keyframes runtime-exit-blur-out {
208
+ 0% { filter: blur(0); opacity: 1; } 100% { filter: blur(20px); opacity: 0; }
209
+ }
210
+ @keyframes runtime-exit-sink {
211
+ 0% { translate: 0 0; opacity: 1; } 100% { translate: 0 30px; opacity: 0; }
212
+ }
213
+ @keyframes runtime-exit-flip-x {
214
+ 0% { opacity: 1; } 100% { opacity: 0; }
215
+ }
216
+ @keyframes runtime-exit-flip-y {
217
+ 0% { opacity: 1; } 100% { opacity: 0; }
218
+ }
219
+
50
220
  /* SVG path-trace animations (Icon + Svg elements) */
51
221
  .animot-svg-element.icon-anim-draw path,
52
222
  .animot-svg-element.icon-anim-draw circle,
package/dist/types.d.ts CHANGED
@@ -46,8 +46,9 @@ export interface PropertySequence {
46
46
  delay: number;
47
47
  duration: number;
48
48
  }
49
- export type EntranceAnimation = 'fade' | 'none';
50
- export type ExitAnimation = 'fade' | 'none';
49
+ export type EntranceAnimation = 'none' | 'fade' | 'slide-up' | 'slide-down' | 'slide-left' | 'slide-right' | 'pop' | 'scale-in' | 'rotate-in' | 'blur-in' | 'rise' | 'flip-x' | 'flip-y' | 'bounce-in';
50
+ export type ExitAnimation = 'none' | 'fade' | 'slide-up' | 'slide-down' | 'slide-left' | 'slide-right' | 'pop' | 'scale-out' | 'rotate-out' | 'blur-out' | 'sink' | 'flip-x' | 'flip-y';
51
+ export type EmphasisAnimation = 'none' | 'pulse' | 'shake' | 'flash' | 'wobble' | 'glow-flash' | 'bob-once' | 'tada';
51
52
  export interface ElementAnimationConfig {
52
53
  order: number;
53
54
  delay: number;
@@ -56,8 +57,14 @@ export interface ElementAnimationConfig {
56
57
  propertySequences?: PropertySequence[];
57
58
  entrance?: EntranceAnimation;
58
59
  exit?: ExitAnimation;
60
+ emphasis?: EmphasisAnimation;
61
+ entranceDuration?: number;
62
+ exitDuration?: number;
63
+ emphasisDuration?: number;
64
+ emphasisDelay?: number;
59
65
  }
60
66
  export type FloatingDirection = 'vertical' | 'horizontal' | 'both';
67
+ export type IdlePreset = 'float' | 'breathe' | 'pulse' | 'wiggle' | 'sway' | 'drift' | 'bob' | 'tilt';
61
68
  export interface FloatingAnimationConfig {
62
69
  enabled: boolean;
63
70
  direction: FloatingDirection;
@@ -65,6 +72,7 @@ export interface FloatingAnimationConfig {
65
72
  speed: number;
66
73
  amplitudeRandomness: number;
67
74
  speedRandomness: number;
75
+ preset?: IdlePreset;
68
76
  }
69
77
  export interface PathPoint {
70
78
  x: number;
@@ -144,7 +152,7 @@ export interface CodeElement extends BaseElement {
144
152
  headerRadius?: number;
145
153
  tabRadius?: number;
146
154
  }
147
- export type TextAnimationMode = 'instant' | 'typewriter' | 'fade-words' | 'fade-letters' | 'handwriting' | 'bounce-in';
155
+ export type TextAnimationMode = 'instant' | 'typewriter' | 'fade-words' | 'fade-letters' | 'handwriting' | 'bounce-in' | 'scramble-in' | 'slot-machine' | 'drop' | 'glitch' | 'marquee' | 'blur-in' | 'stretch' | 'slide-words' | 'wave' | 'typewriter-erase';
148
156
  export interface TextAnimationConfig {
149
157
  mode: TextAnimationMode;
150
158
  typewriterSpeed: number;
@@ -16,7 +16,7 @@
16
16
  * virtual clock at the start of the slide hold (same pattern as FlowMarkers
17
17
  * and arrowClipDraw).
18
18
  */
19
- export type TextAnimateMode = 'instant' | 'typewriter' | 'fade-words' | 'fade-letters' | 'handwriting' | 'bounce-in';
19
+ export type TextAnimateMode = 'instant' | 'typewriter' | 'fade-words' | 'fade-letters' | 'handwriting' | 'bounce-in' | 'scramble-in' | 'slot-machine' | 'drop' | 'glitch' | 'marquee' | 'blur-in' | 'stretch' | 'slide-words' | 'wave' | 'typewriter-erase';
20
20
  export interface TextAnimateParams {
21
21
  enabled: boolean;
22
22
  mode: TextAnimateMode;