diff --git a/Cargo.toml b/Cargo.toml index aa38f582c1..e5c0078e22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1299,6 +1299,17 @@ description = "Bezier curve example showing a cube following a cubic curve" category = "Animation" wasm = true +[[example]] +name = "easing_functions" +path = "examples/animation/easing_functions.rs" +doc-scrape-examples = true + +[package.metadata.example.easing_functions] +name = "Easing Functions" +description = "Showcases the built-in easing functions" +category = "Animation" +wasm = true + [[example]] name = "custom_skinned_mesh" path = "examples/animation/custom_skinned_mesh.rs" diff --git a/examples/README.md b/examples/README.md index a195a0cf44..15349d35ef 100644 --- a/examples/README.md +++ b/examples/README.md @@ -200,6 +200,7 @@ Example | Description [Color animation](../examples/animation/color_animation.rs) | Demonstrates how to animate colors using mixing and splines in different color spaces [Cubic Curve](../examples/animation/cubic_curve.rs) | Bezier curve example showing a cube following a cubic curve [Custom Skinned Mesh](../examples/animation/custom_skinned_mesh.rs) | Skinned mesh example with mesh and joints data defined in code +[Easing Functions](../examples/animation/easing_functions.rs) | Showcases the built-in easing functions [Morph Targets](../examples/animation/morph_targets.rs) | Plays an animation from a glTF file with meshes with morph targets [glTF Skinned Mesh](../examples/animation/gltf_skinned_mesh.rs) | Skinned mesh example with mesh and joints data loaded from a glTF file diff --git a/examples/animation/easing_functions.rs b/examples/animation/easing_functions.rs new file mode 100644 index 0000000000..58e66aa65b --- /dev/null +++ b/examples/animation/easing_functions.rs @@ -0,0 +1,178 @@ +//! Demonstrates the behavior of the built-in easing functions. + +use bevy::{prelude::*, sprite::Anchor}; + +#[derive(Component)] +struct SelectedEaseFunction(easing::EaseFunction, Color); + +fn main() { + App::new() + .add_plugins(DefaultPlugins) + .add_systems(Startup, setup) + .add_systems(Update, display_curves) + .run(); +} + +fn setup(mut commands: Commands) { + commands.spawn(Camera2d); + + let text_style = TextStyle { + font_size: 10.0, + ..default() + }; + + for (i, functions) in [ + easing::EaseFunction::QuadraticIn, + easing::EaseFunction::QuadraticOut, + easing::EaseFunction::QuadraticInOut, + easing::EaseFunction::CubicIn, + easing::EaseFunction::CubicOut, + easing::EaseFunction::CubicInOut, + easing::EaseFunction::QuarticIn, + easing::EaseFunction::QuarticOut, + easing::EaseFunction::QuarticInOut, + easing::EaseFunction::QuinticIn, + easing::EaseFunction::QuinticOut, + easing::EaseFunction::QuinticInOut, + easing::EaseFunction::CircularIn, + easing::EaseFunction::CircularOut, + easing::EaseFunction::CircularInOut, + easing::EaseFunction::ExponentialIn, + easing::EaseFunction::ExponentialOut, + easing::EaseFunction::ExponentialInOut, + easing::EaseFunction::SineIn, + easing::EaseFunction::SineOut, + easing::EaseFunction::SineInOut, + easing::EaseFunction::ElasticIn, + easing::EaseFunction::ElasticOut, + easing::EaseFunction::ElasticInOut, + easing::EaseFunction::BackIn, + easing::EaseFunction::BackOut, + easing::EaseFunction::BackInOut, + easing::EaseFunction::BounceIn, + easing::EaseFunction::BounceOut, + easing::EaseFunction::BounceInOut, + ] + .chunks(3) + .enumerate() + { + for (j, function) in functions.iter().enumerate() { + let color = Hsla::hsl(i as f32 / 10.0 * 360.0, 0.8, 0.75).into(); + commands + .spawn(( + Text2dBundle { + text: Text::from_section( + format!("{:?}", function), + TextStyle { + color, + ..text_style.clone() + }, + ), + transform: Transform::from_xyz( + i as f32 * 125.0 - 1280.0 / 2.0 + 25.0, + -100.0 - ((j as f32 * 250.0) - 300.0), + 0.0, + ), + text_anchor: Anchor::TopLeft, + ..default() + }, + SelectedEaseFunction(*function, color), + )) + .with_children(|p| { + p.spawn(SpriteBundle { + sprite: Sprite { + custom_size: Some(Vec2::new(5.0, 5.0)), + color, + ..default() + }, + transform: Transform::from_xyz(110.0, 15.0, 0.0), + ..default() + }); + p.spawn(SpriteBundle { + sprite: Sprite { + custom_size: Some(Vec2::new(4.0, 4.0)), + color, + ..default() + }, + transform: Transform::from_xyz(0.0, 0.0, 0.0), + ..default() + }); + }); + } + } + commands.spawn( + TextBundle::from_section("", TextStyle::default()).with_style(Style { + position_type: PositionType::Absolute, + bottom: Val::Px(12.0), + left: Val::Px(12.0), + ..default() + }), + ); +} + +fn display_curves( + mut gizmos: Gizmos, + ease_functions: Query<(&SelectedEaseFunction, &Transform, &Children)>, + mut transforms: Query<&mut Transform, Without>, + mut ui: Query<&mut Text, With>, + time: Res