Basic Example

This example demonstrates the basic usage of ranim.

https://github.com/user-attachments/assets/dadab1ab-65e4-4cd3-bda4-b2ef97c61b0b

basic.mp4

Preview App basic 示例输出

scenes.rs(共享场景与项目装配)

use ranim::glam;

use glam::DVec3;
use ranim::{
    anims::{creation::WritingAnim, fading::FadingAnim},
    color::palettes::manim,
    core::animation::eval::StaticAnim,
    items::vitem::{VItem, svg::SvgItem, typst::typst_svg},
    prelude::*,
    utils::rate_functions::smooth,
};

const SVG: &str = include_str!("../../assets/Ghostscript_Tiger.svg");

#[scene]
#[wasm_demo_doc]
#[output(dir = "./output/basic")]
fn basic(r: &mut RanimScene) {
    let mut svg = Vec::<VItem>::from(SvgItem::new(SVG).with(|svg| {
        svg.scale_to_with_stroke(ScaleHint::PorportionalY(3.0))
            .move_to(DVec3::Y * 2.0);
    }));
    let mut text = Vec::<VItem>::from(
        SvgItem::new(typst_svg(
            r#"
            #align(center)[
                #text(18pt)[Ranim]

                #text(6pt)[Hello 你好]
            ]
            "#,
        ))
        .with(|text| {
            text.scale_to_with_stroke(ScaleHint::PorportionalY(2.0))
                .move_to(DVec3::NEG_Y * 2.0)
                .set_color(manim::WHITE)
                .set_fill_opacity(0.8);
        }),
    );

    let mut svg_sequence = AnimSequence::new();
    svg_sequence
        .hold(0.2)
        .push(svg.fade_in().with_duration(3.0).with_rate_func(smooth));

    let mut text_sequence = AnimSequence::new();
    text_sequence.hold(0.2).push(
        text.iter_mut()
            .map(|item| item.write().with_rate_func(smooth))
            .into_lagged(0.2)
            .with_duration(3.0),
    );

    let total_secs = svg_sequence.cursor_sec().max(text_sequence.cursor_sec());
    r.play(CameraFrame::default().show().with_duration(total_secs));
    r.play(stack![svg_sequence, text_sequence]);

    r.insert_time_mark(total_secs, TimeMark::Capture("preview.png".to_string()));
}

/// Register the scenes provided by this example.
pub struct ScenesPlugin;

impl ranim::Plugin for ScenesPlugin {
    fn build(&self, app: &mut bevy_app::App) {
        app.add_scenes([basic::scene()]);
    }
}

main.rs(平台入口)

mod scenes;

#[cfg(not(target_arch = "wasm32"))]
fn main() {
    #[cfg(feature = "cmd-render")]
    {
        use ranim::prelude::*;
        let mut app = App::new();
        app.add_plugins(scenes::ScenesPlugin);
        run_cli(app.build());
    }
    #[cfg(not(feature = "cmd-render"))]
    compile_error!("native examples require the `cmd-render` feature (enabled by default)");
}

// The WASM module is driven by JavaScript through app().
#[cfg(target_arch = "wasm32")]
fn main() {}

#[cfg(target_arch = "wasm32")]
#[wasm_bindgen::prelude::wasm_bindgen]
pub fn app() -> ranim::wasm::WasmApp {
    use ranim::prelude::*;

    let mut app = App::new();
    app.add_plugins(scenes::ScenesPlugin);
    ranim::wasm::WasmApp::new(app.build())
}