1use crate::easing::parse_easing;
4use crate::error::require_index;
5use crate::types::f32_array;
6use animato_core::Update;
7use animato_tween::Tween as CoreTween;
8use js_sys::Float32Array;
9use wasm_bindgen::prelude::*;
10
11#[wasm_bindgen(js_name = TweenBatch)]
13#[derive(Clone, Debug, Default)]
14pub struct TweenBatch {
15 tweens: Vec<CoreTween<f32>>,
16 values: Vec<f32>,
17}
18
19#[wasm_bindgen(js_class = TweenBatch)]
20impl TweenBatch {
21 #[wasm_bindgen(constructor)]
23 pub fn new() -> Self {
24 Self::default()
25 }
26
27 pub fn push(
29 &mut self,
30 from: f32,
31 to: f32,
32 duration: f32,
33 easing: &str,
34 ) -> Result<u32, JsValue> {
35 let tween = CoreTween::new(from, to)
36 .duration(duration.max(0.0))
37 .easing(parse_easing(easing)?)
38 .build();
39 let index = self.tweens.len();
40 self.values.push(tween.value());
41 self.tweens.push(tween);
42 Ok(index as u32)
43 }
44
45 pub fn tick(&mut self, dt: f32) {
47 for (index, tween) in self.tweens.iter_mut().enumerate() {
48 tween.update(dt);
49 self.values[index] = tween.value();
50 }
51 }
52
53 pub fn value(&self, index: u32) -> Result<f32, JsValue> {
55 Ok(self.values[require_index(index, self.values.len(), "batch")?])
56 }
57
58 pub fn values(&self) -> Float32Array {
60 f32_array(&self.values)
61 }
62
63 pub fn len(&self) -> usize {
65 self.tweens.len()
66 }
67
68 #[wasm_bindgen(js_name = isEmpty)]
70 pub fn is_empty(&self) -> bool {
71 self.tweens.is_empty()
72 }
73
74 pub fn clear(&mut self) {
76 self.tweens.clear();
77 self.values.clear();
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn batch_updates_values() {
87 let mut batch = TweenBatch::new();
88 let id = batch.push(0.0, 10.0, 1.0, "linear").unwrap();
89 batch.tick(0.5);
90 assert_eq!(batch.value(id).unwrap(), 5.0);
91 }
92}