1use glam::DVec3;
2use ranim::{
3 animation::transform::{GroupTransformAnimSchedule, TransformAnimSchedule},
4 color::palettes::manim,
5 items::{group::Group, vitem::Square},
6 prelude::*,
7 timeline::TimeMark,
8};
9
10#[scene]
11struct PerspectiveBlendScene;
12
13impl TimelineConstructor for PerspectiveBlendScene {
14 fn construct(self, timeline: &RanimTimeline, camera: &mut Rabject<CameraFrame>) {
15 camera.data.pos = DVec3::Z * 5.0;
16 timeline.update(camera);
17
18 // Create a cube
19 let side_length = 2.0;
20
21 let mut anims = Vec::new();
22
23 // Bottom face
24 let mut bottom = Square(side_length).build();
25 bottom.set_color(manim::TEAL_C).set_fill_opacity(0.5);
26 let mut bottom = timeline.insert(bottom);
27 anims.push(bottom.transform(|data| {
28 data.shift(DVec3::NEG_Y * side_length / 2.0)
29 .rotate(std::f64::consts::PI / 2.0, DVec3::X);
30 }));
31
32 // Right face
33 let mut right = Square(side_length).build();
34 right.set_color(manim::GREEN_C).set_fill_opacity(0.5);
35 let mut right = timeline.insert(right);
36 anims.push(right.transform(|data| {
37 data.shift(DVec3::X * side_length / 2.0)
38 .rotate(std::f64::consts::PI / 2.0, DVec3::Y);
39 }));
40
41 // Back face
42 let mut back = Square(side_length).build();
43 back.set_color(manim::BLUE_C).set_fill_opacity(0.5);
44 let mut back = timeline.insert(back);
45 anims.push(back.transform(|data| {
46 data.shift(DVec3::NEG_Z * side_length / 2.0);
47 }));
48
49 // Top face
50 let mut top = Square(side_length).build();
51 top.set_color(manim::PURPLE_C).set_fill_opacity(0.5);
52 let mut top = timeline.insert(top);
53 anims.push(top.transform(|data| {
54 data.shift(DVec3::Y * side_length / 2.0)
55 .rotate(-std::f64::consts::PI / 2.0, DVec3::X);
56 }));
57
58 // Front face (facing camera)
59 let mut front = Square(side_length).build();
60 front.set_color(manim::RED_C).set_fill_opacity(0.5);
61 let mut front = timeline.insert(front);
62
63 anims.push(front.transform(|data| {
64 data.shift(DVec3::Z * side_length / 2.0);
65 }));
66
67 // Left face
68 let mut left = Square(side_length).build();
69 left.set_color(manim::YELLOW_C).set_fill_opacity(0.5);
70 let mut left = timeline.insert(left);
71 anims.push(left.transform(|data| {
72 data.shift(DVec3::NEG_X * side_length / 2.0)
73 .rotate(-std::f64::consts::PI / 2.0, DVec3::Y);
74 }));
75
76 timeline.play(Group(anims).apply()).sync();
77
78 let mut cube = Group(vec![front, back, right, left, top, bottom]);
79
80 timeline.play(
81 cube.transform(|data| {
82 data.rotate(std::f64::consts::PI / 6.0, DVec3::Y)
83 .rotate(std::f64::consts::PI / 6.0, DVec3::X);
84 })
85 .with_duration(4.0),
86 );
87
88 timeline.play(
89 camera
90 .transform(|data| {
91 data.perspective_blend = 1.0;
92 })
93 .with_duration(2.0)
94 .with_padding(2.0, 0.0),
95 );
96 timeline.sync();
97 timeline.insert_time_mark(
98 timeline.duration_secs(),
99 TimeMark::Capture("preview.png".to_string()),
100 );
101 }
102}
103
104fn main() {
105 let options = AppOptions {
106 pixel_size: (1280, 720),
107 frame_rate: 60,
108 ..Default::default()
109 };
110
111 #[cfg(not(feature = "app"))]
112 render_scene(PerspectiveBlendScene, &options);
113
114 // reuires "app" feature
115 #[cfg(feature = "app")]
116 run_scene_app(PerspectiveBlendScene);
117}
118