Skip to main content

bevy_tween/combinator/
state.rs

1use tween::ComponentTween;
2
3use crate::interpolate::*;
4use crate::tween::{self, TargetComponent, Tween};
5use bevy::prelude::*;
6
7/// Generic target and state
8pub struct TargetState<T, V> {
9    /// The target type
10    pub target: T,
11    /// The target's value or property
12    pub value: V,
13}
14
15impl<T, V> TargetState<T, V> {
16    /// Create new [`TargetState`] from target and initial value
17    /// Recommended to use other methods like:
18    /// - [`TargetComponent::state`]
19    /// - [`TargetAsset::state`](crate::tween::TargetAsset::state)
20    /// - [`TargetResource::state`](crate::tween::TargetAsset::state)
21    pub fn new(target: T, value: V) -> Self {
22        TargetState { target, value }
23    }
24
25    /// Change the value
26    pub fn set_value(&mut self, new_value: V) -> &mut Self {
27        self.value = new_value;
28        self
29    }
30
31    /// Change the target
32    pub fn set_target(&mut self, new_target: T) -> &mut Self {
33        self.target = new_target;
34        self
35    }
36}
37
38impl<T, V> TargetState<T, V>
39where
40    T: Clone,
41{
42    /// Create [`ComponentTween`] of a value from this state and relative interpolator constructor
43    ///
44    /// # Examples
45    ///
46    /// ```
47    /// # use bevy::prelude::*;
48    /// # use bevy_tween::prelude::*;
49    /// use bevy_tween::interpolate::translation_to;
50    ///
51    /// # let sprite = Entity::PLACEHOLDER;
52    /// let my_target = sprite.into_target();
53    /// let mut my_target_translation = my_target.state(Vec3::ZERO);
54    ///
55    /// // Creating a ComponentTween that's tweening from previous value to Vec3::ONE
56    /// let tween = my_target_translation.with(translation_to(Vec3::ONE));
57    /// ```
58    pub fn with<I>(&mut self, f: impl FnOnce(&mut V) -> I) -> Tween<T, I> {
59        let interpolator = f(&mut self.value);
60        Tween {
61            target: self.target.clone(),
62            interpolator,
63        }
64    }
65}
66
67/// Extension trait to create [`TransformTargetState`]
68pub trait TransformTargetStateExt {
69    /// Create [`TransformTargetState`] from [`Self`] and initial value
70    fn transform_state(&self, value: Transform) -> TransformTargetState;
71}
72
73impl TransformTargetStateExt for TargetComponent {
74    /// Create [`TransformTargetState`] from [`TargetComponent`] and initial value
75    ///
76    /// # Examples
77    ///
78    /// ```
79    /// # use bevy_tween::prelude::*;
80    /// # use bevy::prelude::*;
81    /// # let sprite = Entity::PLACEHOLDER;
82    /// let my_target = sprite.into_target();
83    /// let mut my_target_translation = my_target.transform_state(Transform::IDENTITY);
84    ///
85    /// // Creating a ComponentTween that's tweening from previous translation to Vec3::ONE
86    /// let tween = my_target_translation.translation_to(Vec3::ONE);
87    /// ```
88    fn transform_state(&self, value: Transform) -> TransformTargetState {
89        TransformTargetState::new(self.clone(), value)
90    }
91}
92
93/// Transform state for animating entity
94pub struct TransformTargetState {
95    target: TargetComponent,
96    value: Transform,
97}
98
99impl TransformTargetState {
100    /// Create new [`TransformTargetState`]
101    pub fn new(
102        target: TargetComponent,
103        value: Transform,
104    ) -> TransformTargetState {
105        TransformTargetState { target, value }
106    }
107
108    /// Create [`ComponentTween`] of transform from this state and relative interpolator constructor
109    pub fn transform_with<I>(
110        &mut self,
111        f: impl FnOnce(&mut Transform) -> I,
112    ) -> Tween<TargetComponent, I> {
113        let interpolator = f(&mut self.value);
114        Tween {
115            target: self.target.clone(),
116            interpolator,
117        }
118    }
119
120    /// Create [`ComponentTween`] of transform's translation from this state and relative interpolator constructor
121    pub fn translation_with<I>(
122        &mut self,
123        f: impl FnOnce(&mut Vec3) -> I,
124    ) -> Tween<TargetComponent, I> {
125        self.transform_with(|v| f(&mut v.translation))
126    }
127
128    /// Create [`ComponentTween`] of transform's rotation from this state and relative interpolator constructor
129    pub fn rotation_with<I>(
130        &mut self,
131        f: impl FnOnce(&mut Quat) -> I,
132    ) -> Tween<TargetComponent, I> {
133        self.transform_with(|v| f(&mut v.rotation))
134    }
135
136    /// Create [`ComponentTween`] of transform's scale from this state and relative interpolator constructor
137    pub fn scale_with<I>(
138        &mut self,
139        f: impl FnOnce(&mut Vec3) -> I,
140    ) -> Tween<TargetComponent, I> {
141        self.transform_with(|v| f(&mut v.scale))
142    }
143
144    /// Create [`ComponentTween`] of transform's translation tweening to provided input
145    pub fn translation_to(&mut self, to: Vec3) -> ComponentTween<Translation> {
146        self.translation_with(translation_to(to))
147    }
148
149    /// Create [`ComponentTween`] of transform's rotation tweening to provided input
150    pub fn rotation_to(&mut self, to: Quat) -> ComponentTween<Rotation> {
151        self.rotation_with(rotation_to(to))
152    }
153
154    /// Create [`ComponentTween`] of transform's scale tweening to provided input
155    pub fn scale_to(&mut self, to: Vec3) -> ComponentTween<Scale> {
156        self.scale_with(scale_to(to))
157    }
158
159    /// Create [`ComponentTween`] of transform's translation tweening by provided input
160    pub fn translation_by(&mut self, by: Vec3) -> ComponentTween<Translation> {
161        self.translation_with(translation_by(by))
162    }
163
164    /// Create [`ComponentTween`] of transform's rotation tweening by provided input
165    pub fn rotation_by(&mut self, by: Quat) -> ComponentTween<Rotation> {
166        self.rotation_with(rotation_by(by))
167    }
168
169    /// Create [`ComponentTween`] of transform's scale tweening by provided input
170    pub fn scale_by(&mut self, by: Vec3) -> ComponentTween<Scale> {
171        self.scale_with(scale_by(by))
172    }
173
174    /// Create delta [`ComponentTween`] of transform's translation tweening by provided input
175    pub fn translation_delta_by(&mut self, by: Vec3) -> ComponentTween<Translation> {
176        self.translation_with(translation_delta_by(by))
177    }
178
179    /// Create delta [`ComponentTween`] of transform's rotation tweening by provided input
180    pub fn rotation_delta_by(&mut self, by: Quat) -> ComponentTween<Rotation> {
181        self.rotation_with(rotation_delta_by(by))
182    }
183    
184    /// Create delta [`ComponentTween`] of scale's rotation tweening by provided input
185    pub fn scale_delta_by(&mut self, by: Vec3) -> ComponentTween<Scale> {
186        self.scale_with(scale_delta_by(by))
187    }
188}