vizia_core/style/
transform.rs
1use skia_safe::Matrix;
2use vizia_style::{Angle, Scale, Transform, Translate};
3
4use crate::layout::BoundingBox;
5
6pub(crate) trait IntoTransform {
8 fn as_transform(&self, bounds: BoundingBox, scale_factor: f32) -> Matrix;
9}
10
11impl IntoTransform for Translate {
12 fn as_transform(&self, bounds: BoundingBox, scale_factor: f32) -> Matrix {
13 let tx = self.x.to_pixels(bounds.w, scale_factor);
14 let ty = self.y.to_pixels(bounds.h, scale_factor);
15
16 Matrix::translate((tx, ty))
17 }
18}
19
20impl IntoTransform for Scale {
21 fn as_transform(&self, _bounds: BoundingBox, _scale_factor: f32) -> Matrix {
22 let sx = self.x.to_factor();
23 let sy = self.y.to_factor();
24
25 Matrix::scale((sx, sy))
26 }
27}
28
29impl IntoTransform for Angle {
30 fn as_transform(&self, _bounds: BoundingBox, _scale_factor: f32) -> Matrix {
31 let r = self.to_radians();
32
33 Matrix::rotate_rad(r)
34 }
35}
36
37impl IntoTransform for Vec<Transform> {
38 fn as_transform(&self, bounds: BoundingBox, scale_factor: f32) -> Matrix {
39 let mut result = Matrix::new_identity();
40 for transform in self.iter() {
41 let t = match transform {
42 Transform::Translate(translate) => {
43 let tx = translate.0.to_pixels(bounds.w, scale_factor);
44 let ty = translate.1.to_pixels(bounds.h, scale_factor);
45
46 Matrix::translate((tx, ty))
47 }
48
49 Transform::TranslateX(x) => {
50 let tx = x.to_pixels(bounds.w, scale_factor);
51
52 Matrix::translate((tx, 0.0))
53 }
54
55 Transform::TranslateY(y) => {
56 let ty = y.to_pixels(bounds.h, scale_factor);
57
58 Matrix::translate((0.0, ty))
59 }
60
61 Transform::Scale(scale) => {
62 let sx = scale.0.to_factor();
63 let sy = scale.1.to_factor();
64
65 Matrix::scale((sx, sy))
66 }
67
68 Transform::ScaleX(x) => {
69 let sx = x.to_factor();
70
71 Matrix::scale((sx, 1.0))
72 }
73
74 Transform::ScaleY(y) => {
75 let sy = y.to_factor();
76
77 Matrix::scale((1.0, sy))
78 }
79
80 Transform::Rotate(angle) => Matrix::rotate_rad(angle.to_radians()),
81
82 Transform::Skew(x, y) => {
83 let cx = x.to_radians().tan();
84 let cy = y.to_radians().tan();
85
86 Matrix::skew((cx, cy))
87 }
88
89 Transform::SkewX(angle) => {
90 let cx = angle.to_radians().tan();
91
92 Matrix::skew((cx, 0.0))
93 }
94
95 Transform::SkewY(angle) => {
96 let cy = angle.to_radians().tan();
97
98 Matrix::skew((0.0, cy))
99 }
100
101 Transform::Matrix(matrix) => Matrix::new_all(
102 matrix.a, matrix.c, matrix.e, matrix.b, matrix.d, matrix.f, 0.0, 0.0, 1.0,
103 ),
104 };
105
106 result = result * t;
107 }
108
109 result
110 }
111}