text_pipeline/
text_pipeline.rs1use bevy::{
6 color::palettes::basic::{BLUE, YELLOW},
7 diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
8 prelude::*,
9 text::{LineBreak, TextBounds},
10 window::{PresentMode, WindowResolution},
11 winit::WinitSettings,
12};
13
14fn main() {
15 App::new()
16 .add_plugins((
17 DefaultPlugins.set(WindowPlugin {
18 primary_window: Some(Window {
19 present_mode: PresentMode::AutoNoVsync,
20 resolution: WindowResolution::new(1920, 1080).with_scale_factor_override(1.0),
21 ..default()
22 }),
23 ..default()
24 }),
25 FrameTimeDiagnosticsPlugin::default(),
26 LogDiagnosticsPlugin::default(),
27 ))
28 .insert_resource(WinitSettings::continuous())
29 .add_systems(Startup, spawn)
30 .add_systems(Update, update_text_bounds)
31 .run();
32}
33
34fn spawn(mut commands: Commands, asset_server: Res<AssetServer>) {
35 warn!(include_str!("warning_string.txt"));
36
37 commands.spawn(Camera2d);
38
39 let make_spans = |i| {
40 [
41 (
42 TextSpan("text".repeat(i)),
43 TextFont {
44 font: asset_server.load("fonts/FiraMono-Medium.ttf"),
45 font_size: (4 + i % 10) as f32,
46 ..Default::default()
47 },
48 TextColor(BLUE.into()),
49 ),
50 (
51 TextSpan("pipeline".repeat(i)),
52 TextFont {
53 font: asset_server.load("fonts/FiraSans-Bold.ttf"),
54 font_size: (4 + i % 11) as f32,
55 ..default()
56 },
57 TextColor(YELLOW.into()),
58 ),
59 ]
60 };
61
62 let spans = (1..50).flat_map(|i| make_spans(i).into_iter());
63
64 commands
65 .spawn((
66 Text2d::default(),
67 TextLayout {
68 justify: Justify::Center,
69 linebreak: LineBreak::AnyCharacter,
70 },
71 TextBounds::default(),
72 ))
73 .with_children(|p| {
74 for span in spans {
75 p.spawn(span);
76 }
77 });
78}
79
80fn update_text_bounds(time: Res<Time>, mut text_bounds_query: Query<&mut TextBounds>) {
82 let width = (1. + ops::sin(time.elapsed_secs())) * 600.0;
83 for mut text_bounds in text_bounds_query.iter_mut() {
84 text_bounds.width = Some(width);
85 }
86}