From 68bd63f130192e56809490499eedab2ccd1dc1a7 Mon Sep 17 00:00:00 2001 From: Silvestr Predko Date: Thu, 9 Jan 2025 15:06:37 +0200 Subject: [PATCH] Add `sprite_scale.rs` example to demonstrate the new functionality Update `Cargo.toml` accordingly. --- Cargo.toml | 11 +++ examples/2d/sprite_scale.rs | 139 ++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 examples/2d/sprite_scale.rs diff --git a/Cargo.toml b/Cargo.toml index 639f90337ba41b..bc8982f3b7c897 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -655,6 +655,17 @@ description = "Animates a sprite in response to an event" category = "2D Rendering" wasm = true +[[example]] +name = "sprite_scale" +path = "examples/2d/sprite_scale.rs" +doc-scrape-examples = true + +[package.metadata.example.sprite_scale] +name = "Sprite Scale" +description = "Shows how a sprite could be scaled into a rectangle while keeping the aspect ratio" +category = "2D Rendering" +wasm = true + [[example]] name = "sprite_flipping" path = "examples/2d/sprite_flipping.rs" diff --git a/examples/2d/sprite_scale.rs b/examples/2d/sprite_scale.rs new file mode 100644 index 00000000000000..8735df6e2d611d --- /dev/null +++ b/examples/2d/sprite_scale.rs @@ -0,0 +1,139 @@ +//! Shows how to use sprite scaling modes to fill and fit textures into the sprite. + +use bevy::prelude::*; + +fn main() { + App::new() + .add_plugins(DefaultPlugins) + .add_systems(Startup, setup) + .run(); +} + +fn setup(mut commands: Commands, asset_server: Res) { + commands.spawn(Camera2d); + let font = asset_server.load("fonts/FiraSans-Bold.ttf"); + let style = TextFont { + font: font.clone(), + ..default() + }; + + let square = asset_server.load("textures/slice_square_2.png"); + let banner = asset_server.load("branding/banner.png"); + + let rects = vec![ + Rect { + size: Vec2::new(100., 300.), + text: "Stretched".to_string(), + transform: Transform::from_translation(Vec3::new(-550.0, 200.0, 0.0)), + texture: square.clone(), + image_mode: SpriteImageMode::Auto, + }, + Rect { + size: Vec2::new(100., 300.), + text: "Fill Center".to_string(), + transform: Transform::from_translation(Vec3::new(-400.0, 200.0, 0.0)), + texture: square.clone(), + image_mode: SpriteImageMode::ScaleMode(TextureScale::FillCenter), + }, + Rect { + size: Vec2::new(100., 300.), + text: "Fill Start".to_string(), + transform: Transform::from_translation(Vec3::new(-250.0, 200.0, 0.0)), + texture: square.clone(), + image_mode: SpriteImageMode::ScaleMode(TextureScale::FillStart), + }, + Rect { + size: Vec2::new(100., 300.), + text: "Fill End".to_string(), + transform: Transform::from_translation(Vec3::new(-100.0, 200.0, 0.0)), + texture: square.clone(), + image_mode: SpriteImageMode::ScaleMode(TextureScale::FillEnd), + }, + Rect { + size: Vec2::new(300., 100.), + text: "Fill Start Horizontal".to_string(), + transform: Transform::from_translation(Vec3::new(150.0, 300.0, 0.0)), + texture: square.clone(), + image_mode: SpriteImageMode::ScaleMode(TextureScale::FillStart), + }, + Rect { + size: Vec2::new(300., 100.), + text: "Fill End Horizontal".to_string(), + transform: Transform::from_translation(Vec3::new(150.0, 100.0, 0.0)), + texture: square.clone(), + image_mode: SpriteImageMode::ScaleMode(TextureScale::FillEnd), + }, + Rect { + size: Vec2::new(200., 200.), + text: "Fill Center".to_string(), + transform: Transform::from_translation(Vec3::new(450.0, 200.0, 0.0)), + texture: banner.clone(), + image_mode: SpriteImageMode::ScaleMode(TextureScale::FillCenter), + }, + Rect { + size: Vec2::new(100., 100.), + text: "Stretched".to_string(), + transform: Transform::from_translation(Vec3::new(-550.0, -200.0, 0.0)), + texture: banner.clone(), + image_mode: SpriteImageMode::Auto, + }, + Rect { + size: Vec2::new(200., 200.), + text: "Fit Center".to_string(), + transform: Transform::from_translation(Vec3::new(-350.0, -200.0, 0.0)), + texture: banner.clone(), + image_mode: SpriteImageMode::ScaleMode(TextureScale::FitCenter), + }, + Rect { + size: Vec2::new(200., 200.), + text: "Fit Start".to_string(), + transform: Transform::from_translation(Vec3::new(-100.0, -200.0, 0.0)), + texture: banner.clone(), + image_mode: SpriteImageMode::ScaleMode(TextureScale::FitStart), + }, + Rect { + size: Vec2::new(200., 200.), + text: "Fit End".to_string(), + transform: Transform::from_translation(Vec3::new(150.0, -200.0, 0.0)), + texture: banner.clone(), + image_mode: SpriteImageMode::ScaleMode(TextureScale::FitEnd), + }, + Rect { + size: Vec2::new(100., 200.), + text: "Fit Center".to_string(), + transform: Transform::from_translation(Vec3::new(350.0, -200.0, 0.0)), + texture: banner.clone(), + image_mode: SpriteImageMode::ScaleMode(TextureScale::FitCenter), + }, + ]; + + for rect in rects { + let mut cmd = commands.spawn(( + Sprite { + image: rect.texture, + custom_size: Some(rect.size), + image_mode: rect.image_mode, + ..default() + }, + rect.transform, + )); + + cmd.with_children(|builder| { + builder.spawn(( + Text2d::new(rect.text), + style.clone(), + TextLayout::new_with_justify(JustifyText::Center), + Transform::from_xyz(0., -0.5 * rect.size.y - 10., 0.0), + bevy::sprite::Anchor::TopCenter, + )); + }); + } +} + +struct Rect { + size: Vec2, + text: String, + transform: Transform, + texture: Handle, + image_mode: SpriteImageMode, +}