bevy_tween 0.12.0

Flexible tweening plugin library for Bevy
Documentation
use bevy::{
    color::palettes::css::{DEEP_PINK, WHITE},
    prelude::*,
};
use bevy_tween::{
    bevy_time_runner::TimeRunnerEnded, combinator::*, prelude::*,
    tween::AnimationTarget,
};
mod utils;

fn secs(secs: f32) -> Duration {
    Duration::from_secs_f32(secs)
}

fn main() {
    App::new()
        .add_plugins((DefaultPlugins, DefaultTweenPlugins::default()))
        .add_systems(Startup, setup)
        .add_systems(
            Update,
            (
                utils::main_cursor_world_coord_system,
                click_spawn_circle,
                despawn_finished_circle,
            ),
        )
        .init_resource::<utils::MainCursorWorldCoord>()
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn((Camera2d, utils::MainCamera));
}

fn click_spawn_circle(
    mut commands: Commands,
    coord: Res<utils::MainCursorWorldCoord>,
    key: Res<ButtonInput<MouseButton>>,
    asset_server: Res<AssetServer>,
) {
    use interpolate::sprite_color;
    let circle_filled_image = asset_server.load("circle_filled.png");
    if let Some(coord) = coord.0
        && (key.just_pressed(MouseButton::Left)
            || key.pressed(MouseButton::Right))
    {
        let start = Vec3::new(coord.x, coord.y, 1.);
        let end = Vec3::new(0., 0., 0.);
        let transform = Transform::from_translation(start);
        let circle = AnimationTarget.into_target();
        let mut circle_transform = circle.transform_state(transform);
        commands
            .spawn((
                Sprite {
                    image: circle_filled_image,
                    ..default()
                },
                transform,
                AnimationTarget,
            ))
            .animation()
            .insert(parallel((
                tween(
                    secs(2.),
                    EaseKind::ExponentialOut,
                    circle_transform.translation_to(end),
                ),
                tween(
                    secs(1.),
                    EaseKind::BackIn,
                    circle_transform.scale_to(Vec3::ZERO),
                ),
                tween(
                    secs(1.),
                    EaseKind::Linear,
                    circle.with(sprite_color(
                        into_color(WHITE),
                        into_color(DEEP_PINK),
                    )),
                ),
            )));
    }
}

fn despawn_finished_circle(
    mut commands: Commands,
    mut time_runner_ended_reader: MessageReader<TimeRunnerEnded>,
) {
    for t in time_runner_ended_reader.read() {
        commands.entity(t.entity).despawn();
    }
}

fn into_color<T: Into<bevy::color::Srgba>>(color: T) -> Color {
    Color::Srgba(color.into())
}