1use serde::{Deserialize, Serialize};
7
8use crate::ShapeId;
9
10#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
11#[serde(default, rename_all = "camelCase")]
12pub struct Transition {
13 pub kind: String,
17 pub option: String,
19 pub duration_ms: u32,
20 pub advance_on_click: bool,
21 pub advance_after_ms: Option<u32>,
22 pub sound: Option<crate::MediaId>,
24 #[serde(skip_serializing_if = "Option::is_none")]
26 pub raw: Option<String>,
27}
28
29impl Default for Transition {
30 fn default() -> Self {
31 Transition {
32 kind: "none".into(),
33 option: String::new(),
34 duration_ms: 1000,
35 advance_on_click: true,
36 advance_after_ms: None,
37 sound: None,
38 raw: None,
39 }
40 }
41}
42
43pub static TRANSITIONS: &[(&str, &str, &str, u32, &[&str])] = &[
45 ("none", "None", "Subtle", 0, &[]),
46 (
47 "morph",
48 "Morph",
49 "Subtle",
50 2000,
51 &["objects", "words", "characters"],
52 ),
53 ("fade", "Fade", "Subtle", 700, &["smoothly", "throughBlack"]),
54 ("push", "Push", "Subtle", 1000, &["u", "d", "l", "r"]),
55 (
56 "wipe",
57 "Wipe",
58 "Subtle",
59 1000,
60 &["r", "l", "u", "d", "ru", "lu", "rd", "ld"],
61 ),
62 (
63 "split",
64 "Split",
65 "Subtle",
66 1500,
67 &["vertOut", "vertIn", "horzOut", "horzIn"],
68 ),
69 (
70 "reveal",
71 "Reveal",
72 "Subtle",
73 2000,
74 &["smoothlyLeft", "smoothlyRight", "blackLeft", "blackRight"],
75 ),
76 ("cut", "Cut", "Subtle", 0, &["", "throughBlack"]),
77 (
78 "randomBar",
79 "Random Bars",
80 "Subtle",
81 1000,
82 &["vert", "horz"],
83 ),
84 (
85 "shape",
86 "Shape",
87 "Subtle",
88 2000,
89 &["circle", "diamond", "plus", "in", "out"],
90 ),
91 (
92 "uncover",
93 "Uncover",
94 "Subtle",
95 1000,
96 &["l", "r", "u", "d", "lu", "ru", "ld", "rd"],
97 ),
98 (
99 "cover",
100 "Cover",
101 "Subtle",
102 1000,
103 &["l", "r", "u", "d", "lu", "ru", "ld", "rd"],
104 ),
105 ("flash", "Flash", "Subtle", 1000, &[]),
106 ("fallOver", "Fall Over", "Exciting", 2000, &["l", "r"]),
107 ("drape", "Drape", "Exciting", 2000, &["l", "r"]),
108 ("curtains", "Curtains", "Exciting", 2000, &[]),
109 ("wind", "Wind", "Exciting", 2000, &["l", "r"]),
110 ("prestige", "Prestige", "Exciting", 2000, &[]),
111 ("fracture", "Fracture", "Exciting", 2000, &[]),
112 ("crush", "Crush", "Exciting", 2000, &[]),
113 ("peelOff", "Peel Off", "Exciting", 1500, &["l", "r"]),
114 ("pageCurlDouble", "Page Curl", "Exciting", 1500, &["l", "r"]),
115 ("airplane", "Airplane", "Exciting", 2000, &["l", "r"]),
116 ("origami", "Origami", "Exciting", 2000, &["l", "r"]),
117 ("dissolve", "Dissolve", "Exciting", 1200, &[]),
118 (
119 "checker",
120 "Checkerboard",
121 "Exciting",
122 1500,
123 &["horz", "vert"],
124 ),
125 ("blinds", "Blinds", "Exciting", 1600, &["vert", "horz"]),
126 (
127 "clock",
128 "Clock",
129 "Exciting",
130 2000,
131 &["clockwise", "counterClockwise", "wedge"],
132 ),
133 (
134 "ripple",
135 "Ripple",
136 "Exciting",
137 1400,
138 &["center", "lu", "ru", "ld", "rd"],
139 ),
140 ("honeycomb", "Honeycomb", "Exciting", 3000, &[]),
141 (
142 "glitter",
143 "Glitter",
144 "Exciting",
145 2500,
146 &["l", "r", "u", "d"],
147 ),
148 ("vortex", "Vortex", "Exciting", 3000, &["l", "r", "u", "d"]),
149 ("shred", "Shred", "Exciting", 2000, &["strips", "particles"]),
150 ("switch", "Switch", "Exciting", 1250, &["l", "r"]),
151 ("flip", "Flip", "Exciting", 1250, &["l", "r"]),
152 ("gallery", "Gallery", "Exciting", 1500, &["l", "r"]),
153 ("cube", "Cube", "Exciting", 1250, &["l", "r", "u", "d"]),
154 ("doors", "Doors", "Exciting", 1400, &["vert", "horz"]),
155 ("box", "Box", "Exciting", 1250, &["l", "r", "u", "d"]),
156 ("comb", "Comb", "Exciting", 1000, &["horz", "vert"]),
157 ("zoom", "Zoom", "Exciting", 1000, &["in", "out"]),
158 ("random", "Random", "Exciting", 2000, &[]),
159 ("pan", "Pan", "Dynamic Content", 1000, &["u", "d", "l", "r"]),
160 (
161 "ferris",
162 "Ferris Wheel",
163 "Dynamic Content",
164 2000,
165 &["l", "r"],
166 ),
167 ("conveyor", "Conveyor", "Dynamic Content", 2000, &["l", "r"]),
168 (
169 "rotate",
170 "Rotate",
171 "Dynamic Content",
172 2000,
173 &["l", "r", "u", "d"],
174 ),
175 (
176 "window",
177 "Window",
178 "Dynamic Content",
179 1250,
180 &["vert", "horz"],
181 ),
182 (
183 "orbit",
184 "Orbit",
185 "Dynamic Content",
186 2000,
187 &["l", "r", "u", "d"],
188 ),
189 (
190 "flythrough",
191 "Fly Through",
192 "Dynamic Content",
193 1000,
194 &["in", "out", "inBounce", "outBounce"],
195 ),
196];
197
198#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
199#[serde(rename_all = "camelCase")]
200pub enum AnimClass {
201 #[default]
202 Entrance,
203 Emphasis,
204 Exit,
205 Path,
206 Media,
207}
208
209impl AnimClass {
210 pub fn xml(self) -> &'static str {
211 match self {
212 AnimClass::Entrance => "entr",
213 AnimClass::Emphasis => "emph",
214 AnimClass::Exit => "exit",
215 AnimClass::Path => "path",
216 AnimClass::Media => "mediacall",
217 }
218 }
219 pub fn from_xml(s: &str) -> Self {
220 match s {
221 "emph" => AnimClass::Emphasis,
222 "exit" => AnimClass::Exit,
223 "path" => AnimClass::Path,
224 "mediacall" => AnimClass::Media,
225 _ => AnimClass::Entrance,
226 }
227 }
228}
229
230#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
231#[serde(rename_all = "camelCase")]
232pub enum AnimStart {
233 #[default]
234 OnClick,
235 WithPrevious,
236 AfterPrevious,
237}
238
239#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
241#[serde(rename_all = "camelCase")]
242pub enum TextBuild {
243 #[default]
244 AsOne,
245 ByParagraph,
246 ByWord,
247 ByLetter,
248}
249
250#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
251#[serde(default, rename_all = "camelCase")]
252pub struct Animation {
253 pub shape: ShapeId,
254 pub class: AnimClass,
255 pub effect: String,
257 pub option: String,
259 pub start: AnimStart,
260 pub duration_ms: u32,
261 pub delay_ms: u32,
262 pub repeat: u32,
264 pub rewind: bool,
265 pub text_build: TextBuild,
266 pub paragraph: Option<u32>,
268 pub path: Option<String>,
270 pub trigger: Option<ShapeId>,
272 pub amount: Option<f64>,
274 pub color: Option<crate::style::ColorRef>,
276 pub preset_id: Option<u32>,
278 pub preset_subtype: Option<u32>,
279 pub after: Option<String>,
281 pub sound: Option<crate::MediaId>,
282 pub smooth_start: f64,
283 pub smooth_end: f64,
284 pub bounce_end: f64,
285 pub auto_reverse: bool,
286}
287
288impl Default for Animation {
289 fn default() -> Self {
290 Animation {
291 shape: ShapeId(0),
292 class: AnimClass::Entrance,
293 effect: "fade".into(),
294 option: String::new(),
295 start: AnimStart::OnClick,
296 duration_ms: 500,
297 delay_ms: 0,
298 repeat: 1,
299 rewind: false,
300 text_build: TextBuild::AsOne,
301 paragraph: None,
302 path: None,
303 trigger: None,
304 amount: None,
305 color: None,
306 preset_id: None,
307 preset_subtype: None,
308 after: None,
309 sound: None,
310 smooth_start: 0.0,
311 smooth_end: 0.0,
312 bounce_end: 0.0,
313 auto_reverse: false,
314 }
315 }
316}
317
318pub static ANIMATIONS: &[(&str, &str, AnimClass, u32, u32, &[&str])] = &[
320 ("appear", "Appear", AnimClass::Entrance, 1, 0, &[]),
321 ("fade", "Fade", AnimClass::Entrance, 10, 500, &[]),
322 (
323 "fly",
324 "Fly In",
325 AnimClass::Entrance,
326 2,
327 500,
328 &["b", "lb", "l", "lt", "t", "rt", "r", "rb"],
329 ),
330 (
331 "float",
332 "Float In",
333 AnimClass::Entrance,
334 42,
335 1000,
336 &["u", "d"],
337 ),
338 (
339 "split",
340 "Split",
341 AnimClass::Entrance,
342 16,
343 500,
344 &["horzIn", "horzOut", "vertIn", "vertOut"],
345 ),
346 (
347 "wipe",
348 "Wipe",
349 AnimClass::Entrance,
350 22,
351 500,
352 &["b", "l", "t", "r"],
353 ),
354 (
355 "shape",
356 "Shape",
357 AnimClass::Entrance,
358 6,
359 2000,
360 &[
361 "circleIn",
362 "circleOut",
363 "boxIn",
364 "boxOut",
365 "diamondIn",
366 "diamondOut",
367 "plusIn",
368 "plusOut",
369 ],
370 ),
371 (
372 "wheel",
373 "Wheel",
374 AnimClass::Entrance,
375 21,
376 2000,
377 &["1", "2", "3", "4", "8"],
378 ),
379 (
380 "randomBars",
381 "Random Bars",
382 AnimClass::Entrance,
383 14,
384 500,
385 &["horz", "vert"],
386 ),
387 ("grow", "Grow & Turn", AnimClass::Entrance, 31, 500, &[]),
388 ("zoom", "Zoom", AnimClass::Entrance, 53, 500, &["in", "out"]),
389 (
390 "swivel",
391 "Swivel",
392 AnimClass::Entrance,
393 45,
394 2000,
395 &["horz", "vert"],
396 ),
397 ("bounce", "Bounce", AnimClass::Entrance, 26, 2000, &[]),
398 (
399 "blinds",
400 "Blinds",
401 AnimClass::Entrance,
402 3,
403 500,
404 &["horz", "vert"],
405 ),
406 ("box", "Box", AnimClass::Entrance, 4, 500, &["in", "out"]),
407 (
408 "checkerboard",
409 "Checkerboard",
410 AnimClass::Entrance,
411 5,
412 500,
413 &["across", "down"],
414 ),
415 (
416 "circle",
417 "Circle",
418 AnimClass::Entrance,
419 6,
420 500,
421 &["in", "out"],
422 ),
423 (
424 "diamond",
425 "Diamond",
426 AnimClass::Entrance,
427 8,
428 500,
429 &["in", "out"],
430 ),
431 ("dissolve", "Dissolve In", AnimClass::Entrance, 9, 500, &[]),
432 (
433 "peek",
434 "Peek In",
435 AnimClass::Entrance,
436 12,
437 500,
438 &["b", "l", "t", "r"],
439 ),
440 (
441 "strips",
442 "Strips",
443 AnimClass::Entrance,
444 18,
445 500,
446 &["lu", "ru", "ld", "rd"],
447 ),
448 ("expand", "Expand", AnimClass::Entrance, 55, 500, &[]),
449 ("rise", "Rise Up", AnimClass::Entrance, 37, 1000, &[]),
450 ("spinner", "Spinner", AnimClass::Entrance, 49, 1000, &[]),
451 ("pulse", "Pulse", AnimClass::Emphasis, 26, 500, &[]),
452 (
453 "colorPulse",
454 "Color Pulse",
455 AnimClass::Emphasis,
456 27,
457 500,
458 &[],
459 ),
460 ("teeter", "Teeter", AnimClass::Emphasis, 32, 1000, &[]),
461 (
462 "spin",
463 "Spin",
464 AnimClass::Emphasis,
465 8,
466 2000,
467 &["clockwise", "counterClockwise"],
468 ),
469 (
470 "growShrink",
471 "Grow/Shrink",
472 AnimClass::Emphasis,
473 6,
474 2000,
475 &["both", "horz", "vert"],
476 ),
477 (
478 "desaturate",
479 "Desaturate",
480 AnimClass::Emphasis,
481 35,
482 500,
483 &[],
484 ),
485 ("darken", "Darken", AnimClass::Emphasis, 25, 500, &[]),
486 ("lighten", "Lighten", AnimClass::Emphasis, 30, 500, &[]),
487 (
488 "transparency",
489 "Transparency",
490 AnimClass::Emphasis,
491 9,
492 500,
493 &[],
494 ),
495 (
496 "objectColor",
497 "Object Color",
498 AnimClass::Emphasis,
499 19,
500 2000,
501 &[],
502 ),
503 (
504 "complementaryColor",
505 "Complementary Color",
506 AnimClass::Emphasis,
507 21,
508 500,
509 &[],
510 ),
511 ("lineColor", "Line Color", AnimClass::Emphasis, 7, 2000, &[]),
512 ("fillColor", "Fill Color", AnimClass::Emphasis, 1, 2000, &[]),
513 ("fontColor", "Font Color", AnimClass::Emphasis, 3, 2000, &[]),
514 ("underline", "Underline", AnimClass::Emphasis, 18, 500, &[]),
515 ("boldFlash", "Bold Flash", AnimClass::Emphasis, 10, 500, &[]),
516 ("wave", "Wave", AnimClass::Emphasis, 34, 500, &[]),
517 ("disappear", "Disappear", AnimClass::Exit, 1, 0, &[]),
518 ("fadeOut", "Fade", AnimClass::Exit, 10, 500, &[]),
519 (
520 "flyOut",
521 "Fly Out",
522 AnimClass::Exit,
523 2,
524 500,
525 &["b", "lb", "l", "lt", "t", "rt", "r", "rb"],
526 ),
527 (
528 "floatOut",
529 "Float Out",
530 AnimClass::Exit,
531 42,
532 1000,
533 &["u", "d"],
534 ),
535 (
536 "splitOut",
537 "Split",
538 AnimClass::Exit,
539 16,
540 500,
541 &["horzIn", "horzOut", "vertIn", "vertOut"],
542 ),
543 (
544 "wipeOut",
545 "Wipe",
546 AnimClass::Exit,
547 22,
548 500,
549 &["b", "l", "t", "r"],
550 ),
551 (
552 "shapeOut",
553 "Shape",
554 AnimClass::Exit,
555 6,
556 2000,
557 &["circleIn", "circleOut"],
558 ),
559 (
560 "wheelOut",
561 "Wheel",
562 AnimClass::Exit,
563 21,
564 2000,
565 &["1", "2", "3", "4", "8"],
566 ),
567 (
568 "randomBarsOut",
569 "Random Bars",
570 AnimClass::Exit,
571 14,
572 500,
573 &["horz", "vert"],
574 ),
575 ("shrinkTurn", "Shrink & Turn", AnimClass::Exit, 31, 500, &[]),
576 ("zoomOut", "Zoom", AnimClass::Exit, 53, 500, &["in", "out"]),
577 (
578 "swivelOut",
579 "Swivel",
580 AnimClass::Exit,
581 45,
582 2000,
583 &["horz", "vert"],
584 ),
585 ("bounceOut", "Bounce", AnimClass::Exit, 26, 2000, &[]),
586 ("dissolveOut", "Dissolve Out", AnimClass::Exit, 9, 500, &[]),
587 (
588 "lines",
589 "Lines",
590 AnimClass::Path,
591 64,
592 2000,
593 &["down", "up", "right", "left"],
594 ),
595 (
596 "arcs",
597 "Arcs",
598 AnimClass::Path,
599 37,
600 2000,
601 &["down", "up", "right", "left"],
602 ),
603 (
604 "turns",
605 "Turns",
606 AnimClass::Path,
607 43,
608 2000,
609 &["down", "up", "right", "left"],
610 ),
611 (
612 "shapes",
613 "Shapes",
614 AnimClass::Path,
615 1,
616 2000,
617 &[
618 "circle",
619 "diamond",
620 "hexagon",
621 "triangle",
622 "square",
623 "trapezoid",
624 "octagon",
625 "parallelogram",
626 "pentagon",
627 ],
628 ),
629 ("loops", "Loops", AnimClass::Path, 61, 2000, &[]),
630 ("customPath", "Custom Path", AnimClass::Path, 0, 2000, &[]),
631 ("play", "Play", AnimClass::Media, 1, 0, &[]),
632 ("pause", "Pause", AnimClass::Media, 2, 0, &[]),
633 ("stop", "Stop", AnimClass::Media, 3, 0, &[]),
634];
635
636pub fn animation_info(
637 effect: &str,
638 class: AnimClass,
639) -> Option<&'static (
640 &'static str,
641 &'static str,
642 AnimClass,
643 u32,
644 u32,
645 &'static [&'static str],
646)> {
647 ANIMATIONS
648 .iter()
649 .find(|a| a.0 == effect && a.2 == class)
650 .or_else(|| ANIMATIONS.iter().find(|a| a.0 == effect))
651}