Skip to main content

oxframe_2d/
scale.rs

1//! The scale of a node: one number for both axes, or a pair.
2
3use std::ops::Deref;
4
5use oxframe_core::{Seconds, Signal, Tween, Vec2};
6
7/// A scale: `1.5` (both axes), `(2.0, 0.5)`, `[2.0, 0.5]` or a [`Vec2`].
8pub trait IntoScale {
9    /// The horizontal and vertical scale.
10    fn into_scale(self) -> Vec2;
11}
12
13impl IntoScale for f64 {
14    fn into_scale(self) -> Vec2 {
15        Vec2::new(self, self)
16    }
17}
18
19impl IntoScale for i32 {
20    fn into_scale(self) -> Vec2 {
21        f64::from(self).into_scale()
22    }
23}
24
25impl IntoScale for (f64, f64) {
26    fn into_scale(self) -> Vec2 {
27        Vec2::new(self.0, self.1)
28    }
29}
30
31impl IntoScale for [f64; 2] {
32    fn into_scale(self) -> Vec2 {
33        Vec2::new(self[0], self[1])
34    }
35}
36
37impl IntoScale for Vec2 {
38    fn into_scale(self) -> Vec2 {
39        self
40    }
41}
42
43/// The scale of a node, from [`Node::scale`](crate::Node::scale): a
44/// `Signal<Vec2>` whose [`to`](ScaleSignal::to) and [`set`](ScaleSignal::set) also take
45/// one number for both axes, `node.scale().to(1.2, 0.3)`.
46#[derive(Clone)]
47pub struct ScaleSignal(pub(crate) Signal<Vec2>);
48
49impl ScaleSignal {
50    /// Animates to `target` (`1.2`, `(2.0, 0.5)`, a [`Vec2`]).
51    pub fn to(&self, target: impl IntoScale, duration: impl Seconds) -> Tween<Vec2> {
52        self.0.to(target.into_scale(), duration)
53    }
54
55    /// Sets a plain value; removes any binding.
56    pub fn set(&self, value: impl IntoScale) {
57        self.0.set(value.into_scale());
58    }
59
60    /// The underlying signal.
61    pub fn signal(&self) -> Signal<Vec2> {
62        self.0.clone()
63    }
64}
65
66impl Deref for ScaleSignal {
67    type Target = Signal<Vec2>;
68    fn deref(&self) -> &Signal<Vec2> {
69        &self.0
70    }
71}
72
73impl From<ScaleSignal> for Signal<Vec2> {
74    fn from(s: ScaleSignal) -> Self {
75        s.0
76    }
77}