Skip to main content

anchors/
anchors.rs

1use motion_canvas_rs::prelude::*;
2use std::time::Duration;
3
4fn main() {
5    let mut project = Project::default()
6        .with_title("Anchor Test")
7        .with_dimensions(1200, 800)
8        .close_on_finish();
9
10    // 1. TOP-LEFT ANCHOR (-1, -1)
11    let rect_tl = Rect::default()
12        .with_size(Vec2::new(100.0, 100.0))
13        .with_fill(Color::rgb8(0x32, 0xe1, 0x38)) // Green
14        .with_position(Vec2::new(300.0, 200.0))
15        .with_anchor(Vec2::new(-1.0, -1.0));
16
17    let label_tl = TextNode::default()
18        .with_font("JetBrains Mono")
19        .with_text("Top-Left Anchor")
20        .with_font_size(16.0)
21        .with_position(Vec2::new(300.0, 150.0))
22        .with_fill(Color::WHITE);
23
24    // 2. CENTER ANCHOR (0, 0)
25    let rect_c = Rect::default()
26        .with_size(Vec2::new(100.0, 100.0))
27        .with_fill(Color::rgb8(0xe1, 0x32, 0x38)) // Red
28        .with_position(Vec2::new(600.0, 200.0))
29        .with_anchor(Vec2::new(0.0, 0.0));
30
31    let label_c = TextNode::default()
32        .with_font("JetBrains Mono")
33        .with_text("Center Anchor")
34        .with_font_size(16.0)
35        .with_position(Vec2::new(600.0, 150.0))
36        .with_fill(Color::WHITE);
37
38    // 3. BOTTOM-RIGHT ANCHOR (1, 1)
39    let rect_br = Rect::default()
40        .with_size(Vec2::new(100.0, 100.0))
41        .with_fill(Color::rgb8(0x32, 0x38, 0xe1)) // Blue
42        .with_position(Vec2::new(900.0, 200.0))
43        .with_anchor(Vec2::new(1.0, 1.0));
44
45    let label_br = TextNode::default()
46        .with_font("JetBrains Mono")
47        .with_text("Bottom-Right Anchor")
48        .with_font_size(16.0)
49        .with_position(Vec2::new(900.0, 150.0))
50        .with_fill(Color::WHITE);
51
52    // 4. TEXT ANCHOR TEST
53    let text_anchored = TextNode::default()
54        .with_font("JetBrains Mono")
55        .with_text("ANCHORED")
56        .with_font_size(40.0)
57        .with_fill(Color::YELLOW)
58        .with_position(Vec2::new(600.0, 500.0))
59        .with_anchor(Vec2::new(-1.0, 0.0)); // Left-center
60
61    let text_marker = Circle::default()
62        .with_radius(5.0)
63        .with_fill(Color::WHITE)
64        .with_position(Vec2::new(600.0, 500.0));
65
66    // Show markers for each rect position
67    let marker_tl = Circle::default()
68        .with_radius(3.0)
69        .with_fill(Color::WHITE)
70        .with_position(Vec2::new(300.0, 200.0));
71    let marker_c = Circle::default()
72        .with_radius(3.0)
73        .with_fill(Color::WHITE)
74        .with_position(Vec2::new(600.0, 200.0));
75    let marker_br = Circle::default()
76        .with_radius(3.0)
77        .with_fill(Color::WHITE)
78        .with_position(Vec2::new(900.0, 200.0));
79
80    project.scene.add(Box::new(rect_tl.clone()));
81    project.scene.add(Box::new(label_tl));
82    project.scene.add(Box::new(marker_tl));
83
84    project.scene.add(Box::new(rect_c.clone()));
85    project.scene.add(Box::new(label_c));
86    project.scene.add(Box::new(marker_c));
87
88    project.scene.add(Box::new(rect_br.clone()));
89    project.scene.add(Box::new(label_br));
90    project.scene.add(Box::new(marker_br));
91
92    project.scene.add(Box::new(text_anchored.clone()));
93    project.scene.add(Box::new(text_marker));
94
95    // Animate rotation for all rects
96    project.scene.video_timeline.add(loop_anim(
97        move || {
98            chain![
99                // Test rotation
100                all![
101                    rect_tl
102                        .rotation
103                        .to(std::f32::consts::PI * 2.0, Duration::from_secs(2)),
104                    rect_c
105                        .rotation
106                        .to(std::f32::consts::PI * 2.0, Duration::from_secs(2)),
107                    rect_br
108                        .rotation
109                        .to(std::f32::consts::PI * 2.0, Duration::from_secs(2)),
110                    text_anchored
111                        .rotation
112                        .to(std::f32::consts::PI * 2.0, Duration::from_secs(2)),
113                ],
114                // Test scaling
115                all![
116                    rect_tl.scale.to(Vec2::splat(1.5), Duration::from_secs(2)),
117                    rect_c.scale.to(Vec2::splat(1.5), Duration::from_secs(2)),
118                    rect_br.scale.to(Vec2::splat(1.5), Duration::from_secs(2)),
119                    text_anchored
120                        .scale
121                        .to(Vec2::splat(1.5), Duration::from_secs(2)),
122                ],
123                // Test moving anchor during animation
124                all![
125                    text_anchored
126                        .rotation
127                        .to(std::f32::consts::PI * 3.0, Duration::from_secs(3)),
128                    text_anchored
129                        .anchor
130                        .to(Vec2::new(1.0, 0.0), Duration::from_secs(3))
131                        .ease(linear),
132                ],
133                // Reset
134                all![
135                    rect_tl.scale.to(Vec2::splat(1.0), Duration::from_secs(2)),
136                    rect_c.scale.to(Vec2::splat(1.0), Duration::from_secs(2)),
137                    rect_br.scale.to(Vec2::splat(1.0), Duration::from_secs(2)),
138                    text_anchored
139                        .scale
140                        .to(Vec2::splat(1.0), Duration::from_secs(2)),
141                ],
142                all![
143                    rect_tl.rotation.to(0.0, Duration::from_secs(2)),
144                    rect_c.rotation.to(0.0, Duration::from_secs(2)),
145                    rect_br.rotation.to(0.0, Duration::from_secs(2)),
146                    text_anchored.rotation.to(0.0, Duration::from_secs(2)),
147                    text_anchored
148                        .anchor
149                        .to(Vec2::new(-1.0, 0.0), Duration::from_secs(2)),
150                ],
151            ]
152        },
153        None,
154    ));
155
156    project.show().expect("Failed to render");
157}