 1869e45c49
			
		
	
	
		1869e45c49
		
			
		
	
	
	
	
		
			
			# Objective - Followup to #15675 - Some of the functions are wrong, noticed in #15703: `Sine`, `Elastic` and `Back` ## Solution - Fix them and make them deterministic 
		
			
				
	
	
		
			179 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| //! 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::SineIn,
 | |
|         easing::EaseFunction::SineOut,
 | |
|         easing::EaseFunction::SineInOut,
 | |
|         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::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<SelectedEaseFunction>>,
 | |
|     mut ui: Query<&mut Text, With<Node>>,
 | |
|     time: Res<Time>,
 | |
| ) {
 | |
|     let samples = 100;
 | |
|     let size = 100.0;
 | |
|     let duration = 2.5;
 | |
|     let time_margin = 0.5;
 | |
| 
 | |
|     let now = ((time.elapsed_seconds() % (duration + time_margin * 2.0) - time_margin) / duration)
 | |
|         .clamp(0.0, 1.0);
 | |
| 
 | |
|     ui.single_mut().sections[0].value = format!("Progress: {:.2}", now);
 | |
| 
 | |
|     for (SelectedEaseFunction(function, color), transform, children) in &ease_functions {
 | |
|         // Draw a box around the curve
 | |
|         gizmos.linestrip_2d(
 | |
|             [
 | |
|                 Vec2::new(transform.translation.x, transform.translation.y + 15.0),
 | |
|                 Vec2::new(
 | |
|                     transform.translation.x + size,
 | |
|                     transform.translation.y + 15.0,
 | |
|                 ),
 | |
|                 Vec2::new(
 | |
|                     transform.translation.x + size,
 | |
|                     transform.translation.y + 15.0 + size,
 | |
|                 ),
 | |
|                 Vec2::new(
 | |
|                     transform.translation.x,
 | |
|                     transform.translation.y + 15.0 + size,
 | |
|                 ),
 | |
|                 Vec2::new(transform.translation.x, transform.translation.y + 15.0),
 | |
|             ],
 | |
|             color.darker(0.4),
 | |
|         );
 | |
| 
 | |
|         // Draw the curve
 | |
|         let f = easing::EasingCurve::ease(*function);
 | |
|         gizmos.linestrip_2d(
 | |
|             (0..(samples + 1)).map(|i| {
 | |
|                 let t = i as f32 / samples as f32;
 | |
|                 let sampled = f.sample(t).unwrap();
 | |
|                 Vec2::new(
 | |
|                     t * size + transform.translation.x,
 | |
|                     sampled * size + transform.translation.y + 15.0,
 | |
|                 )
 | |
|             }),
 | |
|             *color,
 | |
|         );
 | |
| 
 | |
|         // Show progress along the curve for the current time
 | |
|         let y = f.sample(now).unwrap() * size + 15.0;
 | |
|         transforms.get_mut(children[0]).unwrap().translation.y = y;
 | |
|         transforms.get_mut(children[1]).unwrap().translation = Vec3::new(now * size, y, 0.0);
 | |
|         gizmos.linestrip_2d(
 | |
|             [
 | |
|                 Vec2::new(transform.translation.x, transform.translation.y + y),
 | |
|                 Vec2::new(transform.translation.x + size, transform.translation.y + y),
 | |
|             ],
 | |
|             color.darker(0.2),
 | |
|         );
 | |
|     }
 | |
| }
 |