ArcBetweenPoints Example

This example demonstrates ArcBetweenPoints.

https://github.com/user-attachments/assets/9595ce1d-2390-4d4d-958f-9299755460b7

arc_between_points.mp4

Preview App arc_between_points 示例输出

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

use itertools::Itertools;
use ranim::{
    anims::fading::FadingAnim,
    color,
    color::HueDirection,
    glam::{DMat2, dvec2},
    items::vitem::geometry::ArcBetweenPoints,
    prelude::*,
    utils::rate_functions::smooth,
};

#[scene]
#[wasm_demo_doc]
#[output(dir = "./output/arc_between_points")]
fn arc_between_points(r: &mut RanimScene) {
    let center = dvec2(0.0, 0.0);

    let start_color = color::color("#FF8080FF");
    let end_color = color::color("#58C4DDFF");
    let ntan = 16;
    let nrad = 5;

    let mut arcs = (0..nrad)
        .map(|i| {
            let radius = 6.0 * (i + 1) as f64 / nrad as f64;
            let width = 0.12 * ((nrad - i) as f64 / nrad as f64).powi(2);
            let angle = std::f64::consts::PI * 7.0 / 4.0 * (i + 1) as f64 / nrad as f64;
            (radius, width, angle)
        })
        .cartesian_product(0..ntan)
        .map(|((rad, width, angle), j)| {
            let color = start_color.lerp(
                end_color,
                j as f32 / (ntan - 1) as f32,
                HueDirection::Increasing,
            );
            let vec = DMat2::from_angle(std::f64::consts::PI * 2.0 / ntan as f64 * j as f64)
                * dvec2(rad, 0.0);
            ArcBetweenPoints::new(center.extend(0.0), (center + vec).extend(0.0), angle).with(
                |arc| {
                    arc.stroke_width = width as f32;
                    arc.set_stroke_color(color);
                },
            )
        })
        .collect::<Vec<_>>();
    let total_secs = 3.0;
    let content = arcs
        .iter_mut()
        .map(|arc| arc.fade_in().with_rate_func(smooth))
        .into_lagged(0.2)
        .with_duration(total_secs);

    r.play(CameraFrame::default().show().with_duration(total_secs));
    r.play(content);

    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([arc_between_points::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())
}