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