Preview
App
use log::LevelFilter;
use ranim::{
animation::transform::TransformAnim,
color::palettes::manim,
glam::DVec3,
items::{
Group,
vitem::{VItem, geometry::Square},
},
prelude::*,
timeline::TimeMark,
utils::rate_functions::linear,
};
#[scene]
#[preview]
#[output(dir = "perspective_blend")]
fn perspective_blend(r: &mut RanimScene) {
let r_cam = r.insert_and_show(CameraFrame::default());
r.timeline_mut(&r_cam).update_with(|cam| {
cam.pos = DVec3::Z * 5.0;
});
let side_length = 2.0;
let square_with_color = |color: color::AlphaColor<color::Srgb>| {
VItem::from(Square::new(side_length).with(|square| {
square.set_color(color).set_fill_opacity(0.5);
}))
};
let square_faces = [
manim::TEAL_C,
manim::GREEN_C,
manim::BLUE_C,
manim::PURPLE_C,
manim::RED_C,
manim::YELLOW_C,
]
.map(|color| r.insert(square_with_color(color)));
let transform_fns: [&dyn Fn(&mut VItem); 6] = [
&(|data| {
data.shift(DVec3::NEG_Y * side_length / 2.0)
.rotate(std::f64::consts::PI / 2.0, DVec3::X);
}),
&(|data| {
data.shift(DVec3::X * side_length / 2.0)
.rotate(std::f64::consts::PI / 2.0, DVec3::Y);
}),
&(|data| {
data.shift(DVec3::NEG_Z * side_length / 2.0);
}),
&(|data| {
data.shift(DVec3::Y * side_length / 2.0)
.rotate(-std::f64::consts::PI / 2.0, DVec3::X);
}),
&(|data| {
data.shift(DVec3::Z * side_length / 2.0);
}),
&(|data| {
data.shift(DVec3::NEG_X * side_length / 2.0)
.rotate(-std::f64::consts::PI / 2.0, DVec3::Y);
}),
];
let square_faces = square_faces
.iter()
.zip(transform_fns)
.map(|(r_face, transform_fn)| {
r.timeline_mut(r_face)
.play_with(|face| face.transform(transform_fn).with_rate_func(linear))
.hide()
.state()
.clone()
})
.collect::<Vec<_>>();
let faces = Group(square_faces);
let r_faces = r.insert(faces);
r.timelines_mut().sync(); r.timeline_mut(&r_faces).play_with(|faces| {
faces
.transform(|data| {
data.rotate(std::f64::consts::PI / 6.0, DVec3::Y)
.rotate(std::f64::consts::PI / 6.0, DVec3::X);
})
.with_duration(4.0)
});
r.timeline_mut(&r_cam).forward(2.0).play_with(|cam| {
cam.transform(|data| {
data.perspective_blend = 1.0;
})
.with_duration(2.0)
});
r.insert_time_mark(
r.timelines().max_total_secs(),
TimeMark::Capture("preview.png".to_string()),
);
}
fn main() {
#[cfg(not(target_arch = "wasm32"))]
{
#[cfg(debug_assertions)]
pretty_env_logger::formatted_timed_builder()
.filter(Some("ranim"), LevelFilter::Trace)
.init();
#[cfg(not(debug_assertions))]
pretty_env_logger::formatted_timed_builder()
.filter(Some("ranim"), LevelFilter::Info)
.init();
}
#[cfg(not(feature = "app"))]
render_scene(perspective_blend_scene);
#[cfg(feature = "app")]
preview(perspective_blend_scene);
}