1
2use {
3 std::f64::consts::PI,
4 crate::{
5 makepad_live_compiler::{
6 LiveRef,
7 LiveNodeReader,
8 LiveNodeOrigin,
9 LiveValue,
10 LiveTypeInfo,
11 LiveTypeField,
12 LivePropType,
13 LiveFieldKind,
14 LiveModuleId,
15 LiveType,
16 LiveNode,
17 LiveIdAsProp,
18 LiveNodeSliceApi,
19 LiveNodeVecApi
20 },
21 scope::Scope,
22 makepad_live_tokenizer::{LiveErrorOrigin, live_error_origin},
23 makepad_live_id::*,
24 makepad_derive_live::*,
25 makepad_math::*,
26 cursor::MouseCursor,
27 event::{Event, NextFrame},
28 cx::Cx,
29 live_traits::*,
30 },
31};
32
33pub trait AnimatorImpl {
34
35 fn animator_cut(&mut self, cx: &mut Cx, state: &[LiveId; 2]){
36 self.animator_cut_with_scope(cx, state, &mut Scope::empty())
37 }
38 fn animator_play(&mut self, cx: &mut Cx, state: &[LiveId; 2]){
39 self.animator_play_with_scope(cx, state, &mut Scope::empty())
40 }
41 fn animator_cut_with_scope(&mut self, cx: &mut Cx, state: &[LiveId; 2], scope:&mut Scope);
42 fn animator_play_with_scope(&mut self, cx: &mut Cx, state: &[LiveId; 2], scope:&mut Scope);
43 fn animator_toggle_with_scope(&mut self, cx: &mut Cx, is_state_1: bool, animate: Animate, state1: &[LiveId; 2], state2: &[LiveId; 2], scope:&mut Scope) {
44 if is_state_1 {
45 if let Animate::Yes = animate {
46 self.animator_play_with_scope(cx, state1, scope)
47 }
48 else {
49 self.animator_cut_with_scope(cx, state1, scope)
50 }
51 }
52 else {
53 if let Animate::Yes = animate {
54 self.animator_play_with_scope(cx, state2, scope)
55 }
56 else {
57 self.animator_cut_with_scope(cx, state2, scope)
58 }
59 }
60 }
61 fn animator_toggle(&mut self, cx: &mut Cx, is_state_1: bool, animate: Animate, state1: &[LiveId; 2], state2: &[LiveId; 2]) {
62 self.animator_toggle_with_scope(cx, is_state_1, animate, state1, state2, &mut Scope::empty())
63 }
64 fn animator_in_state(&self, cx: &Cx, check_state_pair: &[LiveId; 2]) -> bool;
65 fn animator_apply_state(&mut self, cx: &mut Cx, scope:&mut Scope);
66 fn animator_after_apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]);
67 fn animator_handle_event(&mut self, cx: &mut Cx, event: &Event) -> AnimatorAction{
68 self.animator_handle_event_with_scope(cx, event, &mut Scope::empty())
69 }
70 fn animator_handle_event_with_scope(&mut self, cx: &mut Cx, event: &Event, scope:&mut Scope) -> AnimatorAction;
71}
72
73#[derive(Debug, Clone, Copy)]
74pub enum Animate {
75 Yes,
76 No
77}
78
79#[derive(Debug, Clone, Live, LiveHook)]
81pub struct KeyFrame {
82 #[live(Ease::Linear)]
83 pub ease: Ease,
84
85 #[live(1.0)]
86 pub time: f64,
87
88 #[live(LiveValue::None)]
89 pub value: LiveValue,
90}
91impl LiveRegister for KeyFrame{}
92
93#[derive(Copy, Clone, Debug, PartialEq, Live, LiveHook)]
94pub enum Play {
95 #[pick {duration: 1.0}]
96 Forward {duration: f64},
97
98 Snap,
99
100 #[live {duration: 1.0, end: 1.0}]
101 Reverse {duration: f64, end: f64},
102
103 #[live {duration: 1.0, end: 1.0}]
104 Loop {duration: f64, end: f64},
105
106 #[live {duration: 1.0, end: 1.0}]
107 ReverseLoop {duration: f64, end: f64},
108
109 #[live {duration: 1.0, end: 1.0}]
110 BounceLoop {duration: f64, end: f64},
111}
112impl Play {
115 pub fn get_ended_time(&self, time: f64) -> (bool, f64) {
127 match self {
128 Self::Snap => (true, 1.0),
129 Self::Forward {duration} => {
130 if *duration == 0.0 {return (true, 1.0)}
131 (time > *duration, time.min(*duration) / duration)
132 },
133 Self::Reverse {duration, end} => {
134 if *duration == 0.0 {return (true, 1.0)}
135 (time > *duration, end - (time.min(*duration) / duration))
136 },
137 Self::Loop {duration, end} => {
138 if *duration == 0.0 {return (true, 1.0)}
139 (false, (time / duration) % end)
140 },
141 Self::ReverseLoop {end, duration} => {
142 if *duration == 0.0 {return (true, 1.0)}
143 (false, end - (time / duration) % end)
144 },
145 Self::BounceLoop {end, duration} => {
146 if *duration == 0.0 {return (true, 1.0)}
147 let mut local_time = (time / duration) % (end * 2.0);
148 if local_time > *end {
149 local_time = 2.0 * end - local_time;
150 };
151 (false, local_time)
152 },
153 }
154 }
155}
156
157
158#[derive(Clone, Copy, Debug, PartialEq, Live, LiveHook)]
159pub enum Ease {
160 #[pick] Linear,
161 #[live] None,
162 #[live(1.0)] Constant(f64),
163 #[live] InQuad,
164 #[live] OutQuad,
165 #[live] InOutQuad,
166 #[live] InCubic,
167 #[live] OutCubic,
168 #[live] InOutCubic,
169 #[live] InQuart,
170 #[live] OutQuart,
171 #[live] InOutQuart,
172 #[live] InQuint,
173 #[live] OutQuint,
174 #[live] InOutQuint,
175 #[live] InSine,
176 #[live] OutSine,
177 #[live] InOutSine,
178 #[live] InExp,
179 #[live] OutExp,
180 #[live] InOutExp,
181 #[live] InCirc,
182 #[live] OutCirc,
183 #[live] InOutCirc,
184 #[live] InElastic,
185 #[live] OutElastic,
186 #[live] InOutElastic,
187 #[live] InBack,
188 #[live] OutBack,
189 #[live] InOutBack,
190 #[live] InBounce,
191 #[live] OutBounce,
192 #[live] InOutBounce,
193 #[live {d1: 0.82, d2: 0.97, max: 100}] ExpDecay {d1: f64, d2: f64, max: usize},
194
195 #[live {begin: 0.0, end: 1.0}] Pow {begin: f64, end: f64},
196 #[live {cp0: 0.0, cp1: 0.0, cp2: 1.0, cp3: 1.0}] Bezier {cp0: f64, cp1: f64, cp2: f64, cp3: f64}
197}
198
199impl Ease {
200 pub fn map(&self, t: f64) -> f64 {
201 match self {
202 Self::ExpDecay {d1, d2, max} => { if t > 0.999 {
204 return 1.0;
205 }
206
207 let mut di = *d1;
209 let mut dt = 1.0;
210 let max_steps = (*max).min(1000);
211 let mut steps = 0;
212 while dt > 0.001 && steps < max_steps {
214 steps = steps + 1;
215 dt = dt * di;
216 di *= d2;
217 }
218 let step = t * (steps as f64);
220 let mut di = *d1;
221 let mut dt = 1.0;
222 let max_steps = max_steps as f64;
223 let mut steps = 0.0;
224 while dt > 0.001 && steps < max_steps {
225 steps += 1.0;
226 if steps >= step { let fac = steps - step;
228 return 1.0 - (dt * fac + (dt * di) * (1.0 - fac))
229 }
230 dt = dt * di;
231 di *= d2;
232 }
233 1.0
234 }
235 Self::Linear => {
236 return t.max(0.0).min(1.0);
237 },
238 Self::Constant(t) => {
239 return t.max(0.0).min(1.0);
240 },
241 Self::None => {
242 return 1.0;
243 },
244 Self::Pow {begin, end} => {
245 if t < 0. {
246 return 0.;
247 }
248 if t > 1. {
249 return 1.;
250 }
251 let a = -1. / (begin * begin).max(1.0);
252 let b = 1. + 1. / (end * end).max(1.0);
253 let t2 = (((a - 1.) * -b) / (a * (1. - b))).powf(t);
254 return (-a * b + b * a * t2) / (a * t2 - b);
255 },
256
257 Self::InQuad => {
258 return t * t;
259 },
260 Self::OutQuad => {
261 return t * (2.0 - t);
262 },
263 Self::InOutQuad => {
264 let t = t * 2.0;
265 if t < 1. {
266 return 0.5 * t * t;
267 }
268 else {
269 let t = t - 1.;
270 return -0.5 * (t * (t - 2.) - 1.);
271 }
272 },
273 Self::InCubic => {
274 return t * t * t;
275 },
276 Self::OutCubic => {
277 let t2 = t - 1.0;
278 return t2 * t2 * t2 + 1.0;
279 },
280 Self::InOutCubic => {
281 let t = t * 2.0;
282 if t < 1. {
283 return 0.5 * t * t * t;
284 }
285 else {
286 let t = t - 2.;
287 return 1. / 2. * (t * t * t + 2.);
288 }
289 },
290 Self::InQuart => {
291 return t * t * t * t
292 },
293 Self::OutQuart => {
294 let t = t - 1.;
295 return -(t * t * t * t - 1.);
296 },
297 Self::InOutQuart => {
298 let t = t * 2.0;
299 if t < 1. {
300 return 0.5 * t * t * t * t;
301 }
302 else {
303 let t = t - 2.;
304 return -0.5 * (t * t * t * t - 2.);
305 }
306 },
307 Self::InQuint => {
308 return t * t * t * t * t;
309 },
310 Self::OutQuint => {
311 let t = t - 1.;
312 return t * t * t * t * t + 1.;
313 },
314 Self::InOutQuint => {
315 let t = t * 2.0;
316 if t < 1. {
317 return 0.5 * t * t * t * t * t;
318 }
319 else {
320 let t = t - 2.;
321 return 0.5 * (t * t * t * t * t + 2.);
322 }
323 },
324 Self::InSine => {
325 return -(t * PI * 0.5).cos() + 1.;
326 },
327 Self::OutSine => {
328 return (t * PI * 0.5).sin();
329 },
330 Self::InOutSine => {
331 return -0.5 * ((t * PI).cos() - 1.);
332 },
333 Self::InExp => {
334 if t < 0.001 {
335 return 0.;
336 }
337 else {
338 return 2.0f64.powf(10. * (t - 1.));
339 }
340 },
341 Self::OutExp => {
342 if t > 0.999 {
343 return 1.;
344 }
345 else {
346 return -(2.0f64.powf(-10. * t)) + 1.;
347 }
348 },
349 Self::InOutExp => {
350 if t<0.001 {
351 return 0.;
352 }
353 if t>0.999 {
354 return 1.;
355 }
356 let t = t * 2.0;
357 if t < 1. {
358 return 0.5 * 2.0f64.powf(10. * (t - 1.));
359 }
360 else {
361 let t = t - 1.;
362 return 0.5 * (-(2.0f64.powf(-10. * t)) + 2.);
363 }
364 },
365 Self::InCirc => {
366 return -((1. - t * t).sqrt() - 1.);
367 },
368 Self::OutCirc => {
369 let t = t - 1.;
370 return (1. - t * t).sqrt();
371 },
372 Self::InOutCirc => {
373 let t = t * 2.;
374 if t < 1. {
375 return -0.5 * ((1. - t * t).sqrt() - 1.);
376 }
377 else {
378 let t = t - 2.;
379 return 0.5 * ((1. - t * t).sqrt() + 1.);
380 }
381 },
382 Self::InElastic => {
383 let p = 0.3;
384 let s = p / 4.0; if t < 0.001 {
386 return 0.;
387 }
388 if t > 0.999 {
389 return 1.;
390 }
391 let t = t - 1.0;
392 return -(2.0f64.powf(10.0 * t) * ((t - s) * (2.0 * PI) / p).sin());
393 },
394 Self::OutElastic => {
395 let p = 0.3;
396 let s = p / 4.0; if t < 0.001 {
399 return 0.;
400 }
401 if t > 0.999 {
402 return 1.;
403 }
404 return 2.0f64.powf(-10.0 * t) * ((t - s) * (2.0 * PI) / p).sin() + 1.0;
405 },
406 Self::InOutElastic => {
407 let p = 0.3;
408 let s = p / 4.0; if t < 0.001 {
410 return 0.;
411 }
412 if t > 0.999 {
413 return 1.;
414 }
415 let t = t * 2.0;
416 if t < 1. {
417 let t = t - 1.0;
418 return -0.5 * (2.0f64.powf(10.0 * t) * ((t - s) * (2.0 * PI) / p).sin());
419 }
420 else {
421 let t = t - 1.0;
422 return 0.5 * 2.0f64.powf(-10.0 * t) * ((t - s) * (2.0 * PI) / p).sin() + 1.0;
423 }
424 },
425 Self::InBack => {
426 let s = 1.70158;
427 return t * t * ((s + 1.) * t - s);
428 },
429 Self::OutBack => {
430 let s = 1.70158;
431 let t = t - 1.;
432 return t * t * ((s + 1.) * t + s) + 1.;
433 },
434 Self::InOutBack => {
435 let s = 1.70158;
436 let t = t * 2.0;
437 if t < 1. {
438 let s = s * 1.525;
439 return 0.5 * (t * t * ((s + 1.) * t - s));
440 }
441 else {
442 let t = t - 2.;
443 return 0.5 * (t * t * ((s + 1.) * t + s) + 2.);
444 }
445 },
446 Self::InBounce => {
447 return 1.0 - Self::OutBounce.map(1.0 - t);
448 },
449 Self::OutBounce => {
450 if t < (1. / 2.75) {
451 return 7.5625 * t * t;
452 }
453 if t < (2. / 2.75) {
454 let t = t - (1.5 / 2.75);
455 return 7.5625 * t * t + 0.75;
456 }
457 if t < (2.5 / 2.75) {
458 let t = t - (2.25 / 2.75);
459 return 7.5625 * t * t + 0.9375;
460 }
461 let t = t - (2.625 / 2.75);
462 return 7.5625 * t * t + 0.984375;
463 },
464 Self::InOutBounce => {
465 if t <0.5 {
466 return Self::InBounce.map(t * 2.) * 0.5;
467 }
468 else {
469 return Self::OutBounce.map(t * 2. - 1.) * 0.5 + 0.5;
470 }
471 },
472 Self::Bezier {cp0, cp1, cp2, cp3} => {
473 if t < 0. {
474 return 0.;
475 }
476 if t > 1. {
477 return 1.;
478 }
479
480 if (cp0 - cp1).abs() < 0.001 && (cp2 - cp3).abs() < 0.001 {
481 return t;
482 }
483
484 let epsilon = 1.0 / 200.0 * t;
485 let cx = 3.0 * cp0;
486 let bx = 3.0 * (cp2 - cp0) - cx;
487 let ax = 1.0 - cx - bx;
488 let cy = 3.0 * cp1;
489 let by = 3.0 * (cp3 - cp1) - cy;
490 let ay = 1.0 - cy - by;
491 let mut u = t;
492
493 for _i in 0..6 {
494 let x = ((ax * u + bx) * u + cx) * u - t;
495 if x.abs() < epsilon {
496 return ((ay * u + by) * u + cy) * u;
497 }
498 let d = (3.0 * ax * u + 2.0 * bx) * u + cx;
499 if d.abs() < 1e-6 {
500 break;
501 }
502 u = u - x / d;
503 };
504
505 if t > 1. {
506 return (ay + by) + cy;
507 }
508 if t < 0. {
509 return 0.0;
510 }
511
512 let mut w = 0.0;
513 let mut v = 1.0;
514 u = t;
515 for _i in 0..8 {
516 let x = ((ax * u + bx) * u + cx) * u;
517 if (x - t).abs() < epsilon {
518 return ((ay * u + by) * u + cy) * u;
519 }
520
521 if t > x {
522 w = u;
523 }
524 else {
525 v = u;
526 }
527 u = (v - w) * 0.5 + w;
528 }
529
530 return ((ay * u + by) * u + cy) * u;
531 }
532 }
533 }
534}
535
536#[derive(Default)]
537pub struct Animator {
538 pub ignore_missing: bool,
539 pub live_ptr: LiveRef,
540 pub state: Option<Vec<LiveNode >>,
541 pub next_frame: NextFrame,
542}
543
544#[derive(Copy, Clone)]
545pub enum AnimatorAction {
546 Animating {redraw: bool},
547 None
548}
549
550impl LiveHook for Animator {}
551impl LiveNew for Animator {
552 fn new(_cx: &mut Cx) -> Self {Self::default()}
553
554 fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
555 LiveTypeInfo {
556 module_id: LiveModuleId::from_str(&module_path!()).unwrap(),
557 live_type: LiveType::of::<Self>(),
558 live_ignore: true,
559 fields: Vec::new(),
560 type_name: id_lut!(States)
561 }
562 }
563}
564impl LiveApply for Animator {
565 fn apply(&mut self, cx: &mut Cx, apply: &mut Apply, start_index: usize, nodes: &[LiveNode]) -> usize {
566
567 if let Some(file_id) = apply.from.file_id() {
568 self.live_ptr = Some(cx.live_registry.borrow().file_id_index_to_live_ptr(file_id, start_index));
569 }
570 if !nodes[start_index].value.is_structy_type() {
571 cx.apply_error_wrong_type_for_struct(live_error_origin!(), start_index, nodes, live_id!(States));
572 return nodes.skip_node(start_index);
573 }
574 let mut index = start_index + 1;
576 loop {
577 if nodes[index].value.is_close() {
578 index += 1;
579 break;
580 }
581 if nodes[index].id == live_id!(ignore_missing){
582 self.ignore_missing = nodes[index].value.as_bool().unwrap_or(false);
583 }
584 else if !nodes[index].origin.has_prop_type(LivePropType::Instance) {
585 cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
586 }
587 index = nodes.skip_node(index);
588 }
589 return index;
590 }
591}
592
593impl AnimatorAction {
594 pub fn must_redraw(&self) -> bool {
595 match self {
596 Self::Animating {redraw} => *redraw,
597 _ => false
598 }
599 }
600 pub fn is_animating(&self) -> bool {
601 match self {
602 Self::Animating {..} => true,
603 _ => false
604 }
605 }
606}
607impl Animator {
608
609 pub fn swap_out_state(&mut self) -> Option<Vec<LiveNode>> {
610 self.state.take()
611 }
612
613 pub fn swap_in_state(&mut self, state: Vec<LiveNode>) {
614 self.state = Some(state);
615 }
616
617 pub fn need_init(&self) -> bool {
618 self.state.is_none()
619 }
620
621 pub fn handle_event(&mut self, cx: &mut Cx, event: &Event) -> AnimatorAction {
622
623 if let Event::NextFrame(nf) = event {
624 if !nf.set.contains(&self.next_frame) {
625 return AnimatorAction::None
626 }
627 if self.state.is_none() {
628 return AnimatorAction::None
629 }
630 let state_nodes = self.state.as_mut().unwrap();
631
632 let mut state_index = state_nodes.child_by_name(0, live_id!(state).as_field()).unwrap();
633 let mut stack_depth = 0;
634 let mut ended = true;
635 let mut redraw = false;
636 while state_index < state_nodes.len() {
637 let state_node = &state_nodes[state_index];
638 if state_node.is_array() {
639 let (play_ended, play_redraw) = Self::update_timeline_value(cx, state_index, state_nodes, nf.time);
641 if !play_ended {
642 ended = false;
643 }
644 if play_redraw {
645 redraw = true;
646 }
647 state_index = state_nodes.skip_node(state_index);
648 }
649 else { if state_node.value.is_open() {
651 stack_depth += 1;
652 state_index += 1;
653 }
654 else if state_node.value.is_close() {
655 stack_depth -= 1;
656 state_index += 1;
657 if stack_depth == 0 {
658 break;
659 }
660 }
661 else {
662 state_index = state_nodes.skip_node(state_index);
663 }
664 }
665 }
666 if !ended {
668 self.next_frame = cx.new_next_frame();
669 }
670
671 return AnimatorAction::Animating {redraw}
672 }
673 AnimatorAction::None
674 }
675
676 pub fn update_timeline_value(cx: &mut Cx, index: usize, nodes: &mut [LiveNode], ext_time: f64) -> (bool, bool) {
678 if nodes[index].is_array() {
680 let mut node_iter = nodes.first_child(index);
681
682 let (ended, time, redraw, track_id) = if let Some(id_index) = node_iter {
684 if let LiveValue::Id(track_id) = nodes[id_index].value {
685 let track_index = nodes.child_by_path(0, &[live_id!(tracks).as_field(), track_id.as_field()]).unwrap();
687
688 let time_index = if let Some(time_index) = nodes.child_by_name(track_index, live_id!(time).as_field()) {time_index}
689 else {
690 return (true, false);
691 };
692
693 let start_time = match &nodes[time_index].value {
694 LiveValue::Id(v) => {
695 assert!(*v == live_id!(void));
696 nodes[time_index].value = LiveValue::Float64(ext_time);
697 ext_time
698 }
699 LiveValue::Float64(time) => {
700 *time
701 }
702 _ => panic!()
703 };
704
705 let play = if let Some(play_index) = nodes.child_by_name(track_index, live_id!(play).as_field()) {
706 Play::new_apply(cx, &mut ApplyFrom::New.into(), play_index, nodes)
707 }
708 else {
709 Play::new(cx)
710 };
711 node_iter = nodes.next_child(id_index);
712
713 let (ended, time) = play.get_ended_time(ext_time - start_time);
714
715 if ended { if let Some(index) = nodes.child_by_name(track_index, live_id!(ended).as_field()) {
717 nodes[index].value = LiveValue::Int64(cx.event_id as i64);
718 }
719 }
720
721 let redraw = if let Some(index) = nodes.child_by_name(track_index, live_id!(redraw).as_field()) {
722 if let LiveValue::Bool(redraw) = &nodes[index].value {
723 *redraw
724 }else {false}
725 }else {false};
726
727 (ended, time, redraw, track_id)
728 }
729 else {panic!()}
730 }
731 else {panic!()};
732
733 let default_ease = if let Some(ease_index) = nodes.child_by_path(0, &[live_id!(tracks).as_field(), track_id.as_field(), live_id!(ease).as_field()]) {
734 Ease::new_apply(cx, &mut ApplyFrom::New.into(), ease_index, nodes)
735 }
736 else {
737 Ease::Linear
738 };
739
740 let mut prev_kf: Option<KeyFrame> = None;
741 let mut last_child_index = node_iter.unwrap();
742 while let Some(node_index) = node_iter {
743 if nodes[node_index + 1].is_close() { last_child_index = node_index;
745 break;
746 }
747 let next_kf = if nodes[node_index].is_value_type() { if prev_kf.is_some() {
749 KeyFrame {
750 ease: default_ease.clone(),
751 time: 1.0,
752 value: nodes[node_index].value.clone()
753 }
754 }
755 else {
756 KeyFrame {
757 ease: default_ease.clone(),
758 time: 0.0,
759 value: nodes[node_index].value.clone()
760 }
761 }
762 }
763 else { let mut kf = KeyFrame::new_apply(cx, &mut ApplyFrom::New.into(), node_index, nodes);
765 if nodes.child_by_name(node_index, live_id!(ease).as_field()).is_none() {
766 kf.ease = default_ease.clone();
767 }
768 kf
769 };
770
771 if let Some(prev_kf) = prev_kf {
772 if time >= prev_kf.time && time <= next_kf.time {
773 let normalised_time = (time - prev_kf.time) / (next_kf.time - prev_kf.time);
774 let mix = next_kf.ease.map(normalised_time);
775 while let Some(node_index) = node_iter {
777 last_child_index = node_index;
778 node_iter = nodes.next_child(node_index);
779 }
780
781 let a = &prev_kf.value;
782 let b = &next_kf.value;
783
784 let new_val = match a {
785 LiveValue::Int64(va) => match b {
786 LiveValue::Int64(vb) => {
787 LiveValue::Float64(((vb - va) as f64) * mix + *va as f64)
788 }
789 LiveValue::Float64(vb) => {
790 LiveValue::Float64(((vb - *va as f64) as f64) * mix + *va as f64)
791 }
792 _ => LiveValue::None
793 }
794 LiveValue::Float64(va) => match b {
795 LiveValue::Int64(vb) => {
796 LiveValue::Float64(((*vb as f64 - va) as f64) * mix + *va as f64)
797 }
798 LiveValue::Float64(vb) => {
799 LiveValue::Float64(((vb - va)) * mix + *va)
800 }
801 _ => LiveValue::None
802 }
803 LiveValue::Color(va) => match b {
804 LiveValue::Color(vb) => {
805 LiveValue::Color(Vec4::from_lerp(Vec4::from_u32(*va), Vec4::from_u32(*vb), mix as f32).to_u32())
806 }
807 _ => LiveValue::None
808 }
809 LiveValue::Vec2(va) => match b {
810 LiveValue::Vec2(vb) => {
811 LiveValue::Vec2(Vec2::from_lerp(*va, *vb, mix as f32))
812 }
813 _ => LiveValue::None
814 }
815 LiveValue::Vec3(va) => match b {
816 LiveValue::Vec3(vb) => {
817 LiveValue::Vec3(Vec3::from_lerp(*va, *vb, mix as f32))
818 }
819 _ => LiveValue::None
820 }
821 LiveValue::Id(_) => match b {
822 LiveValue::Id(vb) => {
823 LiveValue::Id(*vb)
824 }
825 _ => LiveValue::None
826 }
827 _ => LiveValue::None
828 };
829 if let LiveValue::None = &new_val {
830 cx.apply_key_frame_cannot_be_interpolated(live_error_origin!(), index, nodes, a, b);
831 return (ended, redraw)
832 }
833 nodes[last_child_index].value = new_val;
834
835 return (ended, redraw)
836 }
837 }
838 prev_kf = Some(next_kf);
839 last_child_index = node_index;
840 node_iter = nodes.next_child(node_index);
841 }
842 if let Some(prev_kf) = prev_kf {
843 nodes[last_child_index].value = prev_kf.value
844 }
845 return (ended, redraw)
846 }
847 (false, false)
848 }
849
850
851 pub fn last_keyframe_value_from_array(index: usize, nodes: &[LiveNode]) -> Option<usize> {
852 if let Some(index) = nodes.last_child(index) {
853 if nodes[index].value.is_object() {
854 return nodes.child_by_name(index, live_id!(value).as_field());
855 }
856 else {
857 return Some(index)
858 }
859 }
860 return None
861 }
862
863 pub fn first_keyframe_time_from_array(reader: &LiveNodeReader) -> f64 {
864 if let Some(reader) = reader.first_child() {
865 if reader.is_object() {
866 if let Some(reader) = reader.child_by_name(live_id!(time).as_field()) {
867 return match &reader.value {
868 LiveValue::Float64(v) => *v,
869 LiveValue::Int64(v) => *v as f64,
870 _ => 1.0
871 }
872 }
873 }
874 }
875 return 1.0
876 }
877
878 pub fn is_track_animating(&self, cx: &mut Cx, track_id: &[LiveId;1]) -> bool {
879 if let Some(state) = self.state.as_ref() {
880 if let Some(LiveValue::Int64(ended)) = state.child_value_by_path(0, &[live_id!(tracks).as_field(), track_id[0].as_field(), live_id!(ended).as_field()]) {
881 if *ended == 0 || *ended == cx.event_id as i64 {
882 return true
883 }
884 }
885 }
886 false
887 }
888
889 pub fn animator_in_state(&self, cx: &Cx, check_state_pair: &[LiveId; 2]) -> bool {
890 if self.need_init() {
892 if let Some(live_ptr) = self.live_ptr {
893 let live_registry_rc = cx.live_registry.clone();
894 let live_registry = live_registry_rc.borrow();
895 if live_registry.generation_valid(live_ptr) {
896 let (nodes, index) = live_registry.ptr_to_nodes_index(live_ptr);
897 if let Some(LiveValue::Id(default_id)) = nodes.child_value_by_path(index, &[check_state_pair[0].as_instance(), live_id!(default).as_field()]) {
898 return *default_id == check_state_pair[1];
899 }
900 }
901 }
902 }
903 else {
904 let state = self.state.as_ref().unwrap();
905 if let Some(LiveValue::Id(id)) = &state.child_value_by_path(0, &[live_id!(tracks).as_field(), check_state_pair[0].as_field(), live_id!(state_id).as_field()]) {
906 return *id == check_state_pair[1];
907 }
908 }
909 false
910 }
911
912 pub fn cut_to_live(&mut self, cx: &mut Cx, state_id: &[LiveId; 2]) {
913 if let Some(live_ptr) = self.live_ptr {
914 let live_registry_rc = cx.live_registry.clone();
915 let live_registry = live_registry_rc.borrow();
916 if live_registry.generation_valid(live_ptr) {
917 let (nodes, index) = live_registry.ptr_to_nodes_index(live_ptr);
919
920 self.init_as_needed(cx, index, nodes);
921
922 if let Some(index) = nodes.child_by_path(index, &[state_id[0].as_instance(), state_id[1].as_instance()]) {
923 self.cut_to(cx, state_id, index, nodes);
924 }
925 else {
926 error!("cut_to_live {}.{} not found", state_id[0], state_id[1]);
927 }
928 }
929 else {
930 error!("cut_to_live generation invalid")
931 }
932 }
933 }
934
935 pub fn cut_to(&mut self, cx: &mut Cx, state_pair: &[LiveId; 2], index: usize, nodes: &[LiveNode]) {
937
938 if let Some(index) = nodes.child_by_name(index, live_id!(cursor).as_field()) {
939 let cursor = MouseCursor::new_apply(cx, &mut ApplyFrom::New.into(), index, nodes);
940 cx.set_cursor(cursor);
941 }
942 let mut state = self.swap_out_state().unwrap_or(Vec::new());
944 let track = state_pair[0];
946
947 if state.len() == 0 {
948 state.push_live(live!{
949 tracks: {},
950 state: {}
951 });
952 }
953
954 state.replace_or_insert_last_node_by_path(0, &[live_id!(tracks).as_field(), track.as_field()], live_object!{
955 [track]: {state_id: (state_pair[1]), ended: 1}
956 });
957
958 let mut path = Vec::new();
959 path.push(live_id!(state).as_field());
960
961 let mut reader = if let Some(reader) = LiveNodeReader::new(index, nodes).child_by_name(live_id!(apply).as_field()) {
962 reader
963 }
964 else {
965 cx.apply_animate_missing_apply_block(live_error_origin!(), index, nodes);
966 self.swap_in_state(state);
967 return
968 };
969
970 reader.walk();
971 while !reader.is_eot() {
972 if reader.is_array() {
973 path.push(reader.prop());
974 if let Some(last_value) = Self::last_keyframe_value_from_array(reader.index(), reader.nodes()) {
975 state.replace_or_insert_first_node_by_path(0, &path, live_array!{
976 [(track), (reader.nodes()[last_value].value.clone())]
977 });
978 }
979 path.pop();
980 reader.skip();
981 }
982 else {
983 if reader.is_expr() {
984 path.push(reader.prop());
985 state.replace_or_insert_last_node_by_path(0, &path, reader.node_slice());
986 path.pop();
987 reader.skip();
988 continue;
989 }
990 else if reader.is_open() {
991 path.push(reader.prop());
992 if reader.is_enum() {
993 state.replace_or_insert_last_node_by_path(0, &path, reader.node_slice());
994 }
995 }
996 else if reader.is_close() {
997 path.pop();
998 }
999 else {
1000 path.push(reader.prop());
1001 state.replace_or_insert_first_node_by_path(0, &path, live_array!{
1002 [(track), (reader.value.clone())]
1003 });
1004 path.pop();
1005 }
1006 reader.walk();
1007 }
1008 }
1009 self.swap_in_state(state);
1010 }
1013
1014 pub fn init_as_needed(&mut self, cx: &mut Cx, index: usize, nodes: &[LiveNode]) {
1015 if self.need_init() {
1016 let mut index = index + 1;
1017 while !nodes[index].is_close() {
1018 let track_id = nodes[index].id;
1019 if let Some(LiveValue::Id(state_id)) = nodes.child_value_by_path(index, &[live_id!(default).as_field()]) {
1020 if let Some(index) = nodes.child_by_name(index, state_id.as_instance()) {
1021 self.cut_to(cx, &[track_id, *state_id], index, nodes);
1022 }
1023 }
1024 index = nodes.skip_node(index);
1025 }
1026 }
1027 }
1028
1029 pub fn animate_to_live(&mut self, cx: &mut Cx, state_pair: &[LiveId; 2]) {
1030 if let Some(live_ptr) = self.live_ptr {
1031 let live_registry_rc = cx.live_registry.clone();
1032 let live_registry = live_registry_rc.borrow();
1033 if live_registry.generation_valid(live_ptr) {
1034 let (nodes, index) = live_registry.ptr_to_nodes_index(live_ptr);
1035
1036 self.init_as_needed(cx, index, nodes);
1037
1038 if let Some(index) = nodes.child_by_path(index, &[state_pair[0].as_instance(), state_pair[1].as_instance()]) {
1039 self.animate_to(cx, state_pair, index, nodes)
1040 }
1041 else if !self.ignore_missing{
1042 error!("animate_to_live {}.{} not found", state_pair[0], state_pair[1])
1043 }
1044 }
1045 else {
1046 error!("animate_to_live generation invalid");
1047 }
1048 }
1049 }
1050
1051 pub fn animate_to(&mut self, cx: &mut Cx, state_pair: &[LiveId; 2], index: usize, nodes: &[LiveNode]) {
1052
1053 if let Some(index) = nodes.child_by_name(index, live_id!(cursor).as_field()) {
1054 let cursor = MouseCursor::new_apply(cx, &mut ApplyFrom::New.into(), index, nodes);
1055 cx.set_cursor(cursor);
1056 }
1057
1058 let mut state = self.swap_out_state().unwrap_or(Vec::new());
1059 if state.len() == 0 { panic!();
1063 }
1064
1065 let track = state_pair[0];
1066
1067 let from_id = if let Some(LiveValue::Id(id)) = state.child_value_by_path(0, &[live_id!(tracks).as_field(), track.as_field(), live_id!(state_id).as_field()]) {
1069 *id
1070 }
1071 else {
1072 cx.apply_error_animate_to_unknown_track(live_error_origin!(), index, nodes, track, state_pair[1]);
1073 return
1074 };
1075
1076 let mut path = Vec::new();
1077
1078 state.replace_or_insert_last_node_by_path(0, &[live_id!(tracks).as_field(), track.as_field()], live_object!{
1079 [track]: {state_id: (state_pair[1]), ended: 0, time: void},
1080 });
1081
1082 if let Some(index) = nodes.child_by_name(index, live_id!(from).as_field()) {
1084 if let Some(index) = nodes.child_by_name(index, from_id.as_field()) {
1085 state.replace_or_insert_last_node_by_path(
1086 0,
1087 &[live_id!(tracks).as_field(), track.as_field(), live_id!(play).as_field()],
1088 nodes.node_slice(index)
1089 );
1090 }
1091 else if let Some(index) = nodes.child_by_name(index, live_id!(all).as_field()) {
1092 state.replace_or_insert_last_node_by_path(
1093 0,
1094 &[live_id!(tracks).as_field(), track.as_field(), live_id!(play).as_field()],
1095 nodes.node_slice(index)
1096 );
1097 }
1098 }
1099
1100 if let Some(index) = nodes.child_by_name(index, live_id!(ease).as_field()) {
1102 state.replace_or_insert_last_node_by_path(0, &[live_id!(tracks).as_field(), track.as_field(), live_id!(ease).as_field()], nodes.node_slice(index));
1103 }
1104
1105 if let Some(index) = nodes.child_by_name(index, live_id!(redraw).as_field()) {
1106 state.replace_or_insert_last_node_by_path(0, &[live_id!(tracks).as_field(), track.as_field(), live_id!(redraw).as_field()], nodes.node_slice(index));
1107 }
1108
1109 path.push(live_id!(state).as_field());
1110
1111 let mut reader = if let Some(reader) = LiveNodeReader::new(index, nodes).child_by_name(live_id!(apply).as_field()) {
1112 reader
1113 }
1114 else {
1115 cx.apply_animate_missing_apply_block(live_error_origin!(), index, nodes);
1116 return
1117 };
1118 reader.walk();
1119 while !reader.is_eot() {
1120
1121 if reader.is_array() {
1122 path.push(reader.prop());
1123 let (first_index, last_index) = if let Some(state_child) = state.child_by_path(0, &path) {
1124 if let Some(last_index) = state.last_child(state_child) {
1125 (state_child + 1, last_index)
1126 }
1127 else {panic!()}
1128 }
1129 else {
1130 cx.apply_error_animation_missing_state(live_error_origin!(), index, nodes, track, state_pair[1], &path);
1131 path.pop();
1132 reader.skip();
1133 continue;
1134 };
1135 if let LiveValue::Id(check_id) = &state[first_index].value {
1137 if *check_id != track {
1138 cx.apply_error_wrong_animation_track_used(live_error_origin!(), index, nodes, path.last().unwrap().0, *check_id, track);
1139 path.pop();
1140 reader.skip();
1141 continue;
1142 }
1143 }
1144 else {
1145 panic!()
1146 }
1147 let first_time = Self::first_keyframe_time_from_array(&reader);
1148
1149 let mut timeline = Vec::new();
1150 timeline.open_array(LiveId(0));
1151 timeline.push_id(LiveId(0), track);
1152 if first_time != 0.0 { timeline.push_live(state.node_slice(last_index));
1154 }
1155 timeline.push_live(reader.children_slice());
1156 timeline.push_live(state.node_slice(last_index));
1157 timeline.close();
1158 state.replace_or_insert_last_node_by_path(0, &path, &timeline);
1159
1160 path.pop();
1161 reader.skip();
1162 }
1163 else {
1164 if reader.is_expr() {
1165 path.push(reader.prop());
1166 state.replace_or_insert_last_node_by_path(0, &path, reader.node_slice());
1167 path.pop();
1168 reader.skip();
1169 continue;
1170 }
1171 if reader.is_open() {
1172 path.push(reader.prop());
1173 }
1174 else if reader.is_close() {
1175 path.pop();
1176 }
1177 else {
1178 path.push(reader.prop());
1179
1180 let (first_index, last_index) = if let Some(state_child) = state.child_by_path(0, &path) {
1181 if let Some(last_index) = state.last_child(state_child) {
1182 (state_child + 1, last_index)
1183 }
1184 else {panic!()}
1185 }
1186 else {
1187 cx.apply_error_animation_missing_state(live_error_origin!(), index, nodes, track, state_pair[1], &path);
1190 path.pop();
1191 reader.skip();
1192 continue;
1193 };
1194 if let LiveValue::Id(check_id) = &state[first_index].value {
1196 if *check_id != track {
1197 cx.apply_error_wrong_animation_track_used(live_error_origin!(), index, nodes, path.last().unwrap().0, *check_id, track);
1198 path.pop();
1199 reader.skip();
1200 continue;
1201 }
1202 }
1203 else {
1204 panic!()
1205 }
1206 let mut timeline = Vec::new();
1207 timeline.open_array(LiveId(0));
1208 timeline.push_live(live_array!{(track)});
1209 timeline.push_live(state.node_slice(last_index));
1210 timeline.push_live(reader.node_slice());
1211 timeline.push_live(state.node_slice(last_index));
1213 timeline.close();
1214 state.replace_or_insert_last_node_by_path(0, &path, &timeline);
1215 path.pop();
1216 }
1217 reader.walk();
1218 }
1219 }
1220
1221 self.swap_in_state(state);
1222
1223 self.next_frame = cx.new_next_frame();
1224 }
1225
1226}