bevy icon indicating copy to clipboard operation
bevy copied to clipboard

JustifyText::Right behaves badly

Open robtfm opened this issue 2 years ago • 3 comments

Bevy version

main (8a523de)

What you did

rendered some text with JustifyText::Right

What went wrong

the text layout is different to browser:

bevy: image

browser: image

the first bevy row is what i expected but i think i misunderstood something in the layout algo (the flex-grow spacer element doesn't work in the browser). either way, the layout is different from the browser equivalent. also the text in the second bevy row is very blurry, maybe due to a partial pixel offset problem.

Additional information

bevy:

use bevy::prelude::*;

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

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

    commands
        // container
        .spawn(NodeBundle {
            style: Style {
                flex_direction: FlexDirection::Column,
                position_type: PositionType::Absolute,
                left: Val::Px(100.0),
                top: Val::Px(100.0),
                ..Default::default()
            },
            background_color: Color::GRAY.into(),
            ..Default::default()
        })
        .with_children(|commands| {
            // row 1 - works ok
            commands.spawn(NodeBundle{
                style: Style {
                    flex_direction: FlexDirection::Row,
                    width: Val::Px(190.0),
                    // without height works as expected
                    // height: Val::Px(50.0),
                    ..Default::default()
                },
                background_color: Color::PURPLE.into(),
                ..Default::default()
            }).with_children(|commands| {
                // spacer
                commands.spawn(NodeBundle {
                    style: Style {
                        flex_grow: 1.0,
                        min_height: Val::Px(1.0),
                        min_width: Val::Px(1.0),
                        ..Default::default()
                    },
                    background_color: Color::rgba(0.0, 1.0, 0.0, 0.25).into(),
                    ..Default::default()
                });

                // text
                commands.spawn(TextBundle {
                    text: Text::from_section("Some text that runs onto a second line", Default::default()).with_justify(JustifyText::Right),
                    ..Default::default()
                });
            });

            // separate by 100px
            commands.spawn(NodeBundle{
                style: Style {
                    height: Val::Px(100.0),
                    ..Default::default()
                },
                ..Default::default()
            });

            // row 2 - looks odd
            commands.spawn(NodeBundle{
                style: Style {
                    flex_direction: FlexDirection::Row,
                    width: Val::Px(190.0),
                    // with height >= 25 the alignment is wrong
                    height: Val::Px(35.0),
                    ..Default::default()
                },
                background_color: Color::PURPLE.into(),
                ..Default::default()
            }).with_children(|commands| {
                // spacer
                commands.spawn(NodeBundle {
                    style: Style {
                        flex_grow: 1.0,
                        min_height: Val::Px(1.0),
                        min_width: Val::Px(1.0),
                        ..Default::default()
                    },
                    background_color: Color::rgba(0.0, 1.0, 0.0, 0.25).into(),
                    ..Default::default()
                });

                // text
                commands.spawn(TextBundle {
                    text: Text::from_section("Some text that runs onto a second line", Default::default()).with_justify(JustifyText::Right),
                    ..Default::default()
                });
            });

        });
}

browser css:

.screen {
    display: flex;
    flex-direction: column;
    position: absolute;
    left: 100px;
    top: 100px;
    height: 200px;
    background-color: #888888;
}

.row1 {
    display: flex;
    flex-direction: row;
    width: 190px;
    background-color: #7700ff;
}

.row2 {
    display: flex;
    flex-direction: row;
    width: 190px;
    height: 35px;
    background-color: #7700ff;
}
.separate {
    display: flex;
    height: 100px;
}

.spacer {
    display: flex;
    flex-grow: 1;
    min-width: 1px;
    min-height: 1px;
    background-color: #00ff00;
}

.text {
    display: flex;
    font-family: 'Fira';
    font-size: 13px;
    text-align: right;
}

html:

<!DOCTYPE html>
<html>

<head> 
    <link rel="stylesheet" href="textshape.css"> 
</head>
 
<body>
    <div class="screen">
        <div class="row1">
            <div class="spacer"></div>
            <div class="text">Some text that runs onto a second line</div>
        </div>
        <div class="separate"></div>
        <div class="row2">
            <div class="spacer"></div>
            <div class="text">Some text that runs onto a second line</div>
        </div>
    </div>
</body>  
</html>

robtfm avatar Jan 15 '24 14:01 robtfm

/// Describes the horizontal alignment of multiple lines of text relative to each other.
/// This only affects the internal positioning of the lines of text within a text entity and
/// does not affect the text entity's position.

seems like maybe this is expected for only JustifyText, and i should add a AlignSelf::FlexEnd or thereabouts as well. image

robtfm avatar Jan 15 '24 16:01 robtfm

A browser will allow you to have a text-containing element that is wider than the text it contains. I think this bug would be fixed if we also allowed this and implemented the relevant text justification logic.

nicoburns avatar Jan 15 '24 20:01 nicoburns