bevy/examples/2d
ickshonpe 3f99a3e8cd
Text 2d alignment fix (#17365)
# Objective

`Text2d` ignores `TextBounds` when calculating the offset for text
aligment.
On main a text entity positioned in the center of the window with center
justification and 600px horizontal text bounds isn't centered like it
should be but shifted off to the right:
<img width="305" alt="hellox"
src="https://github.com/user-attachments/assets/8896c6f0-1b9f-4633-9c12-1de6eff5f3e1"
/>
(second example in the testing section below)

Fixes #14266

I already had a PR in review for this (#14270) but it used post layout
adjustment (which we want to avoid) and ignored `TextBounds`.

## Solution

* If `TextBounds` are present for an axis, use them instead of the size
of the computed text layout size to calculate the offset.
* Adjust the vertical offset of text so it's top is aligned with the top
of the texts bounding rect (when present).

## Testing

```
use bevy::prelude::*;
use bevy::color::palettes;
use bevy::sprite::Anchor;
use bevy::text::TextBounds;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .run();
}

fn example(commands: &mut Commands, dest: Vec3, justify: JustifyText) {
    commands.spawn((
        Sprite {
            color: palettes::css::YELLOW.into(),
            custom_size: Some(10. * Vec2::ONE),
            anchor: Anchor::Center,
            ..Default::default()
        },
        Transform::from_translation(dest),
    ));

    for a in [
        Anchor::TopLeft,
        Anchor::TopRight,
        Anchor::BottomRight,
        Anchor::BottomLeft,
    ] {
        commands.spawn((
            Text2d(format!("L R\n{:?}\n{:?}", a, justify)),
            TextFont {
                font_size: 14.0,
                ..default()
            },
            TextLayout {
                justify,
                ..Default::default()
            },
            TextBounds::new(300., 75.),
            Transform::from_translation(dest + Vec3::Z),
            a,
        ));
    }
}

fn setup(mut commands: Commands) {
    commands.spawn(Camera2d::default());

    for (i, j) in [
        JustifyText::Left,
        JustifyText::Right,
        JustifyText::Center,
        JustifyText::Justified,
    ]
    .into_iter()
    .enumerate()
    {
        example(&mut commands, (300. - 150. * i as f32) * Vec3::Y, j);
    }

    commands.spawn(Sprite {
        color: palettes::css::YELLOW.into(),
        custom_size: Some(10. * Vec2::ONE),
        anchor: Anchor::Center,
        ..Default::default()
    });
}
```

<img width="566" alt="cap"
src="https://github.com/user-attachments/assets/e6a98fa5-80b2-4380-a9b7-155bb49635b8"
/>

This probably looks really confusing but it should make sense if you
imagine each block of text surrounded by a 300x75 rectangle that is
anchored to the center of the yellow square.

# 

```
use bevy::prelude::*;
use bevy::sprite::Anchor;
use bevy::text::TextBounds;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn(Camera2d::default());

    commands.spawn((
        Text2d::new("hello"),
        TextFont {
            font_size: 60.0,
            ..default()
        },
        TextLayout::new_with_justify(JustifyText::Center),
        TextBounds::new(600., 200.),
        Anchor::Center,
    ));
}
```

<img width="338" alt="hello"
src="https://github.com/user-attachments/assets/e5e89364-afda-4baa-aca8-df4cdacbb4ed"
/>

The text being above the center is intended. When `TextBounds` are
present, the text block's offset is calculated using its `TextBounds`
not the layout size returned by cosmic-text.

# 

Probably we should add a vertical alignment setting for Text2d. Didn't
do it here as this is intended for a 0.15.2 release.
2025-01-20 20:54:32 +00:00
..
2d_shapes.rs Merge Style properties into Node. Use ComputedNode for computed properties. (#15975) 2024-10-18 22:25:33 +00:00
2d_viewport_to_world.rs simplify example, replace get_single to Single Query (#16187) 2024-11-01 18:25:42 +00:00
bloom_2d.rs Anamorphic Bloom (#17096) 2025-01-06 18:43:21 +00:00
bounding_2d.rs Reworked Segment types into their cartesian forms (#17404) 2025-01-19 03:54:45 +00:00
cpu_draw.rs Make some examples deterministic (#16488) 2024-11-23 18:28:47 +00:00
custom_gltf_vertex_attribute.rs Introduce support for mixed lighting by allowing lights to opt out of contributing diffuse light to lightmapped objects. (#16761) 2024-12-16 23:48:33 +00:00
mesh2d_alpha_mode.rs Migrate cameras to required components (#15641) 2024-10-05 01:59:52 +00:00
mesh2d_arcs.rs Implement From translation and rotation for isometries (#15733) 2024-10-08 16:09:28 +00:00
mesh2d_manual.rs Use multi_draw_indirect_count where available, in preparation for two-phase occlusion culling. (#17211) 2025-01-14 21:19:20 +00:00
mesh2d_vertex_color_texture.rs Migrate cameras to required components (#15641) 2024-10-05 01:59:52 +00:00
mesh2d.rs Migrate cameras to required components (#15641) 2024-10-05 01:59:52 +00:00
move_sprite.rs aligning public apis of Time,Timer and Stopwatch (#15962) 2024-10-16 21:09:32 +00:00
pixel_grid_snap.rs Refactor and simplify custom projections (#17063) 2025-01-01 20:44:24 +00:00
rotation.rs aligning public apis of Time,Timer and Stopwatch (#15962) 2024-10-16 21:09:32 +00:00
sprite_animation.rs Merge Style properties into Node. Use ComputedNode for computed properties. (#15975) 2024-10-18 22:25:33 +00:00
sprite_flipping.rs Migrate bevy_sprite to required components (#15489) 2024-10-09 16:17:26 +00:00
sprite_sheet.rs Migrate bevy_sprite to required components (#15489) 2024-10-09 16:17:26 +00:00
sprite_slice.rs BorderRect maintenance (#16727) 2024-12-12 04:33:44 +00:00
sprite_tile.rs Improved UiImage and Sprite scaling and slicing APIs (#16088) 2024-11-04 15:14:03 +00:00
sprite.rs Migrate bevy_sprite to required components (#15489) 2024-10-09 16:17:26 +00:00
text2d.rs Text 2d alignment fix (#17365) 2025-01-20 20:54:32 +00:00
texture_atlas.rs Prefer Display over Debug (#16112) 2024-12-27 00:40:06 +00:00
transparency_2d.rs Make some examples deterministic (#16488) 2024-11-23 18:28:47 +00:00
wireframe_2d.rs Merge Style properties into Node. Use ComputedNode for computed properties. (#15975) 2024-10-18 22:25:33 +00:00