Manually Animated Render Loops
Animating Between Render Trees
To animate rendering between two render trees, use the render_animated() method:
#![allow(unused)]
fn main() {
extern crate buoyant;
extern crate embedded_graphics;
use std::time::Duration;
use buoyant::{
environment::DefaultEnvironment,
primitives::{Point, Size},
render::{
AnimatedJoin, AnimationDomain, Render,
},
render_target::EmbeddedGraphicsRenderTarget,
view::prelude::*,
};
use embedded_graphics::{pixelcolor::Rgb888, prelude::RgbColor};
let mut display = embedded_graphics::mock_display::MockDisplay::new();
let mut target = EmbeddedGraphicsRenderTarget::new(&mut display);
let app_time = Duration::from_secs(0);
let mut captures = ();
let environment = DefaultEnvironment::new(app_time);
let source_view = view();
let mut view_state = source_view.build_state(&mut ());
let source_layout = source_view.layout(&Size::new(200, 100).into(), &environment, &mut captures, &mut view_state);
let source_render_tree = source_view.render_tree(&source_layout.sublayouts, Point::zero(), &environment, &mut captures, &mut view_state);
let environment = DefaultEnvironment::new(app_time);
let target_view = view();
let target_layout = target_view.layout(&Size::new(200, 100).into(), &environment, &mut captures, &mut view_state);
let target_render_tree = target_view.render_tree(&target_layout.sublayouts, Point::zero(), &environment, &mut captures, &mut view_state);
Render::render_animated(
&mut target,
&source_render_tree,
&target_render_tree,
&Rgb888::BLACK,
&AnimationDomain::top_level(app_time),
);
/// This is just a tribute to the greatest view in the world.
fn view() -> impl View<Rgb888, ()> {
EmptyView // Couldn't remember
}
}
Joining Trees
Generally, all animations in Buoyant are interruptible. In the same way you can animate rendering between two trees, two trees can be joined at a moment in time to form a new one. This allows continuously merging and generating new trees to drive smooth compound animations.
Render tree types conform to AnimatedJoin, which allows you to create a joined tree
at a specific point in time. With some exceptions, the result of rendering the joined tree
is the same as rendering the two trees with render_animated().
#![allow(unused)]
fn main() {
extern crate buoyant;
extern crate embedded_graphics;
use std::time::Duration;
use buoyant::{
environment::DefaultEnvironment,
primitives::{Point, Size},
render::{
AnimatedJoin, AnimationDomain, Render,
},
render_target::EmbeddedGraphicsRenderTarget,
view::prelude::*,
};
use embedded_graphics::{pixelcolor::Rgb888, prelude::RgbColor};
let mut display = embedded_graphics::mock_display::MockDisplay::new();
let mut target = EmbeddedGraphicsRenderTarget::new(&mut display);
let app_time = Duration::from_secs(0);
let mut captures = ();
let environment = DefaultEnvironment::new(app_time);
let source_view = view();
let mut view_state = source_view.build_state(&mut ());
let source_layout = source_view.layout(&Size::new(200, 100).into(), &environment, &mut captures, &mut view_state);
let source_render_tree = source_view.render_tree(&source_layout.sublayouts, Point::zero(), &environment, &mut captures, &mut view_state);
let environment = DefaultEnvironment::new(app_time);
let target_view = view();
let target_layout = target_view.layout(&Size::new(200, 100).into(), &environment, &mut captures, &mut view_state);
let mut target_render_tree = target_view.render_tree(&target_layout.sublayouts, Point::zero(), &environment, &mut captures, &mut view_state);
// Join two trees into the target
target_render_tree.join_from(
&source_render_tree,
&AnimationDomain::top_level(app_time),
);
// Calling render on the joined tree produces the same result as
// the render_animated call above
target_render_tree.render(&mut target, &Rgb888::BLACK);
fn view() -> impl View<Rgb888, ()> {
EmptyView
}
}
Joining trees encodes information about the partially completed animation, which allows multiple staggered animations to occur in a render loop.