rive_rs/animation/
linear_animation.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::any::TypeId;
6
7use crate::animation::{Animation, KeyedObject, Loop};
8use crate::artboard::Artboard;
9use crate::core::{Core, CoreContext, Object, ObjectRef, OnAdded, Property};
10use crate::dyn_vec::DynVec;
11use crate::importers::{ArtboardImporter, ImportStack};
12use crate::status_code::StatusCode;
13
14#[derive(Debug)]
15pub struct LinearAnimation {
16    animation: Animation,
17    fps: Property<u64>,
18    duration: Property<u64>,
19    speed: Property<f32>,
20    r#loop: Property<Loop>,
21    work_start: Property<u64>,
22    work_end: Property<u64>,
23    enable_work_area: Property<bool>,
24    keyed_objects: DynVec<Object<KeyedObject>>,
25}
26
27impl ObjectRef<'_, LinearAnimation> {
28    pub fn fps(&self) -> u64 {
29        self.fps.get()
30    }
31
32    pub fn set_fps(&self, fps: u64) {
33        self.fps.set(fps);
34    }
35
36    pub fn duration(&self) -> u64 {
37        self.duration.get()
38    }
39
40    pub fn set_duration(&self, duration: u64) {
41        self.duration.set(duration);
42    }
43
44    pub fn speed(&self) -> f32 {
45        self.speed.get()
46    }
47
48    pub fn set_speed(&self, speed: f32) {
49        self.speed.set(speed);
50    }
51
52    pub fn r#loop(&self) -> Loop {
53        self.r#loop.get()
54    }
55
56    pub fn set_loop(&self, r#loop: Loop) {
57        self.r#loop.set(r#loop);
58    }
59
60    pub fn work_start(&self) -> u64 {
61        self.work_start.get()
62    }
63
64    pub fn set_work_start(&self, work_start: u64) {
65        self.work_start.set(work_start);
66    }
67
68    pub fn work_end(&self) -> u64 {
69        self.work_end.get()
70    }
71
72    pub fn set_work_end(&self, work_end: u64) {
73        self.work_end.set(work_end);
74    }
75
76    pub fn enable_work_area(&self) -> bool {
77        self.enable_work_area.get()
78    }
79
80    pub fn set_enable_work_area(&self, enable_work_area: bool) {
81        self.enable_work_area.set(enable_work_area);
82    }
83}
84
85impl ObjectRef<'_, LinearAnimation> {
86    pub fn push_keyed_object(&self, keyed_object: Object<KeyedObject>) {
87        self.keyed_objects.push(keyed_object);
88    }
89
90    pub fn apply(&self, artboard: Object<Artboard>, time: f32, mix: f32) {
91        for object in self.keyed_objects.iter() {
92            object.as_ref().apply(artboard.clone(), time, mix);
93        }
94    }
95}
96
97impl Core for LinearAnimation {
98    parent_types![(animation, Animation)];
99
100    properties![
101        (56, fps, set_fps),
102        (57, duration, set_duration),
103        (58, speed, set_speed),
104        (59, r#loop, set_loop),
105        (60, work_start, set_work_start),
106        (61, work_end, set_work_end),
107        (62, enable_work_area, set_enable_work_area),
108        animation,
109    ];
110}
111
112impl OnAdded for ObjectRef<'_, LinearAnimation> {
113    fn on_added_dirty(&self, context: &dyn CoreContext) -> StatusCode {
114        for object in self.keyed_objects.iter() {
115            let code = object.as_ref().on_added_dirty(context);
116            if code != StatusCode::Ok {
117                return code;
118            }
119        }
120
121        StatusCode::Ok
122    }
123
124    fn on_added_clean(&self, context: &dyn CoreContext) -> StatusCode {
125        for object in self.keyed_objects.iter() {
126            let code = object.as_ref().on_added_dirty(context);
127            if code != StatusCode::Ok {
128                return code;
129            }
130        }
131
132        StatusCode::Ok
133    }
134
135    fn import(&self, object: Object, import_stack: &ImportStack) -> StatusCode {
136        if let Some(importer) = import_stack.latest::<ArtboardImporter>(TypeId::of::<Artboard>()) {
137            importer.push_animation(object.as_ref().cast::<LinearAnimation>().as_object());
138            self.cast::<Animation>().import(object, import_stack)
139        } else {
140            StatusCode::MissingObject
141        }
142    }
143}
144
145impl Default for LinearAnimation {
146    fn default() -> Self {
147        Self {
148            animation: Animation::default(),
149            fps: Property::new(60),
150            duration: Property::new(60),
151            speed: Property::new(1.0),
152            r#loop: Property::new(Loop::default()),
153            work_start: Property::new(0),
154            work_end: Property::new(0),
155            enable_work_area: Property::new(false),
156            keyed_objects: DynVec::new(),
157        }
158    }
159}