ferroui_base/animation/animators/
transform_operations_animator.rs1use crate::animation::AnimatorKeyFrame;
2use crate::media::transformation::TransformOperations;
3use crate::media::ITransform;
4use crate::Ref;
5use std::rc::Rc;
6
7#[derive(Default)]
14pub struct TransformOperationsAnimator;
15
16impl TransformOperationsAnimator {
17 pub fn new() -> Self {
18 Self
19 }
20
21 pub fn interpolate(
24 &self,
25 progress: f64,
26 old_value: &Rc<TransformOperations>,
27 new_value: &Rc<TransformOperations>,
28 ) -> Rc<TransformOperations> {
29 TransformOperations::interpolate(old_value, new_value, progress)
30 }
31
32 pub(crate) fn ensure_operations(value: &Option<Rc<dyn ITransform>>) -> Rc<TransformOperations> {
35 let Some(value) = value else { return TransformOperations::identity() };
36 match value.as_any().downcast_ref::<TransformOperations>() {
37 Some(operations) => {
38 let mut builder = TransformOperations::create_builder(operations.operations().len());
39 for operation in operations.operations() {
40 builder.append(operation.clone());
41 }
42 builder.build()
43 }
44 None => TransformOperations::identity(),
45 }
46 }
47
48 pub fn validate(&self, item: &Ref<AnimatorKeyFrame>) {
50 let valid = item.with_value(|value| {
51 value
52 .and_then(|value| value.downcast_ref::<Option<Rc<dyn ITransform>>>())
53 .and_then(|value| value.as_ref())
54 .is_some_and(|value| value.as_any().is::<TransformOperations>())
55 });
56 if !valid {
57 panic!("{} must have a value of type TransformOperations.", **item);
58 }
59 }
60}