Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support running an animation N times #19

Merged
merged 17 commits into from
Aug 3, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions examples/colormaterial_color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,14 @@ fn setup(

let tween = Tween::new(
*ease_function,
TweeningType::PingPong,
Duration::from_secs(1),
ColorMaterialColorLens {
start: Color::RED,
end: Color::BLUE,
},
);
)
.with_repeat_count(RepeatCount::Infinite)
.with_repeat_strategy(RepeatStrategy::Bounce);

commands
.spawn_bundle(MaterialMesh2dBundle {
Expand Down
1 change: 0 additions & 1 deletion examples/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
start_time_ms += 500;
let tween_scale = Tween::new(
EaseFunction::BounceOut,
TweeningType::Once,
Duration::from_secs(2),
TransformScaleLens {
start: Vec3::splat(0.01),
Expand Down
34 changes: 21 additions & 13 deletions examples/sequence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,27 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
];
// Build a sequence from an iterator over a Tweenable (here, a Tween<Transform>)
let seq = Sequence::new(dests.windows(2).enumerate().map(|(index, pair)| {
Tween::new(
EaseFunction::QuadraticInOut,
TweeningType::Once,
Duration::from_secs(1),
TransformPositionLens {
start: pair[0] - center,
end: pair[1] - center,
},
)
.with_completed_event(true, index as u64) // Get an event after each segment
Tracks::new([
Tween::new(
EaseFunction::QuadraticInOut,
Duration::from_millis(250),
TransformRotationLens {
start: Quat::IDENTITY,
end: Quat::from_rotation_z(180_f32.to_radians()),
},
)
.with_repeat_count(RepeatCount::Finite(4))
.with_repeat_strategy(RepeatStrategy::Bounce),
Tween::new(
EaseFunction::QuadraticInOut,
Duration::from_secs(1),
TransformPositionLens {
start: pair[0] - center,
end: pair[1] - center,
},
)
.with_completed_event(true, index as u64), // Get an event after each segment
])
}));

commands
Expand All @@ -139,7 +150,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// size at the same time.
let tween_move = Tween::new(
EaseFunction::QuadraticInOut,
TweeningType::Once,
Duration::from_secs(1),
TransformPositionLens {
start: Vec3::new(-200., 100., 0.),
Expand All @@ -149,7 +159,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
.with_completed_event(true, 99); // Get an event once move completed
let tween_rotate = Tween::new(
EaseFunction::QuadraticInOut,
TweeningType::Once,
Duration::from_secs(1),
TransformRotationLens {
start: Quat::IDENTITY,
Expand All @@ -158,7 +167,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
);
let tween_scale = Tween::new(
EaseFunction::QuadraticInOut,
TweeningType::Once,
Duration::from_secs(1),
TransformScaleLens {
start: Vec3::ONE,
Expand Down
5 changes: 3 additions & 2 deletions examples/sprite_color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,14 @@ fn setup(mut commands: Commands) {
] {
let tween = Tween::new(
*ease_function,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
SpriteColorLens {
start: Color::RED,
end: Color::BLUE,
},
);
)
.with_repeat_count(RepeatCount::Infinite)
.with_repeat_strategy(RepeatStrategy::Bounce);

commands
.spawn_bundle(SpriteBundle {
Expand Down
5 changes: 3 additions & 2 deletions examples/text_color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,15 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
] {
let tween = Tween::new(
*ease_function,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
TextColorLens {
start: Color::RED,
end: Color::BLUE,
section: 0,
},
);
)
.with_repeat_count(RepeatCount::Infinite)
.with_repeat_strategy(RepeatStrategy::Bounce);

commands
.spawn_bundle(TextBundle {
Expand Down
5 changes: 3 additions & 2 deletions examples/transform_rotation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,14 @@ fn setup(mut commands: Commands) {
] {
let tween = Tween::new(
*ease_function,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
TransformRotationLens {
start: Quat::IDENTITY,
end: Quat::from_axis_angle(Vec3::Z, std::f32::consts::PI / 2.),
},
);
)
.with_repeat_count(RepeatCount::Infinite)
.with_repeat_strategy(RepeatStrategy::Bounce);

commands
.spawn_bundle((
Expand Down
5 changes: 3 additions & 2 deletions examples/transform_translation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,14 @@ fn setup(mut commands: Commands) {
] {
let tween = Tween::new(
*ease_function,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
TransformPositionLens {
start: Vec3::new(x, screen_y, 0.),
end: Vec3::new(x, -screen_y, 0.),
},
);
)
.with_repeat_count(RepeatCount::Infinite)
.with_repeat_strategy(RepeatStrategy::Bounce);

commands
.spawn_bundle(SpriteBundle {
Expand Down
5 changes: 3 additions & 2 deletions examples/ui_position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ fn setup(mut commands: Commands) {
] {
let tween = Tween::new(
*ease_function,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
UiPositionLens {
start: Rect {
Expand All @@ -92,7 +91,9 @@ fn setup(mut commands: Commands) {
bottom: Val::Auto,
},
},
);
)
.with_repeat_count(RepeatCount::Infinite)
.with_repeat_strategy(RepeatStrategy::Bounce);

commands
.spawn_bundle(NodeBundle {
Expand Down
61 changes: 33 additions & 28 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,7 @@
//! let tween = Tween::new(
//! // Use a quadratic easing on both endpoints.
//! EaseFunction::QuadraticInOut,
//! // Loop animation back and forth.
//! TweeningType::PingPong,
//! // Animation time (one way only; for ping-pong it takes 2 seconds
//! // to come back to start).
//! // Animation time.
//! Duration::from_secs(1),
//! // The lens gives access to the Transform component of the Entity,
//! // for the Animator to animate it. It also contains the start and
Expand Down Expand Up @@ -85,7 +82,6 @@
//! let tween1 = Tween::new(
//! // [...]
//! # EaseFunction::BounceOut,
//! # TweeningType::Once,
//! # Duration::from_secs(2),
//! # TransformScaleLens {
//! # start: Vec3::ZERO,
Expand All @@ -95,7 +91,6 @@
//! let tween2 = Tween::new(
//! // [...]
//! # EaseFunction::QuadraticInOut,
//! # TweeningType::Once,
//! # Duration::from_secs(1),
//! # TransformPositionLens {
//! # start: Vec3::ZERO,
Expand Down Expand Up @@ -163,22 +158,34 @@ pub use plugin::{
};
pub use tweenable::{Delay, Sequence, Tracks, Tween, TweenCompleted, TweenState, Tweenable};

/// Type of looping for a tween animation.
/// How many times to repeat a tween animation. See also: [`RepeatMode`].
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TweeningType {
/// Run the animation once from start to end only.
Once,
/// Loop the animation indefinitely, restarting from the start each time the end is reached.
Loop,
/// Loop the animation back and forth, changing direction each time an endpoint is reached.
pub enum RepeatCount {
/// Run the animation N times.
Finite(u32),
/// Loop the animation indefinitely.
Infinite,
}

/// What to do when a tween animation needs to be repeated.
///
/// Only applicable when [`RepeatCount`] is greater than 1.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum RepeatStrategy {
/// Reset the animation back to its starting position.
#[default]
Teleport,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if "teleport" really convey the meaning here (teleport to where?). What about using the terminology of texture mapping and call that"repeat", and the bounce one "mirrored repeat"? Although they're not great terms, they do have the advantage of being familiar.

Alternatively, what about "wrap"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repeat and mirrored repeat works for me.

/// Follow a ping-pong pattern, changing the direction each time an endpoint is reached.
///
/// A complete cycle start -> end -> start always counts as 2 loop iterations for the various
/// operations where looping matters.
PingPong,
/// operations where looping matters. That is, a 1 second animation will take 2 seconds to end
/// up back where it started.
Bounce,
}

impl Default for TweeningType {
impl Default for RepeatCount {
fn default() -> Self {
TweeningType::Once
Self::Finite(1)
}
}

Expand Down Expand Up @@ -634,9 +641,15 @@ mod tests {
}

#[test]
fn tweening_type() {
let tweening_type = TweeningType::default();
assert_eq!(tweening_type, TweeningType::Once);
fn repeat_count() {
let tweening_type = RepeatCount::default();
assert_eq!(tweening_type, RepeatCount::Finite(1));
}

#[test]
fn repeat_strategy() {
let tweening_type = RepeatStrategy::default();
assert_eq!(tweening_type, RepeatStrategy::Teleport);
}

#[test]
Expand Down Expand Up @@ -686,7 +699,6 @@ mod tests {
fn animator_new() {
let tween = Tween::new(
EaseFunction::QuadraticInOut,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
DummyLens { start: 0., end: 1. },
);
Expand All @@ -702,7 +714,6 @@ mod tests {
for state in [AnimatorState::Playing, AnimatorState::Paused] {
let tween = Tween::<DummyComponent>::new(
EaseFunction::QuadraticInOut,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
DummyLens { start: 0., end: 1. },
);
Expand All @@ -720,7 +731,6 @@ mod tests {

let tween = Tween::<DummyComponent>::new(
EaseFunction::QuadraticInOut,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
DummyLens { start: 0., end: 1. },
);
Expand All @@ -734,7 +744,6 @@ mod tests {
fn animator_controls() {
let tween = Tween::<DummyComponent>::new(
EaseFunction::QuadraticInOut,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
DummyLens { start: 0., end: 1. },
);
Expand Down Expand Up @@ -773,7 +782,6 @@ mod tests {
fn asset_animator_new() {
let tween = Tween::<DummyAsset>::new(
EaseFunction::QuadraticInOut,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
DummyLens { start: 0., end: 1. },
);
Expand All @@ -789,7 +797,6 @@ mod tests {
for state in [AnimatorState::Playing, AnimatorState::Paused] {
let tween = Tween::<DummyAsset>::new(
EaseFunction::QuadraticInOut,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
DummyLens { start: 0., end: 1. },
);
Expand All @@ -809,7 +816,6 @@ mod tests {

let tween = Tween::new(
EaseFunction::QuadraticInOut,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
DummyLens { start: 0., end: 1. },
);
Expand All @@ -824,7 +830,6 @@ mod tests {
fn asset_animator_controls() {
let tween = Tween::new(
EaseFunction::QuadraticInOut,
TweeningType::PingPong,
std::time::Duration::from_secs(1),
DummyLens { start: 0., end: 1. },
);
Expand Down
Loading