text type animation

main
Elijah Voigt 2 years ago
parent 678c0b8c0c
commit b381f0b7b7

@ -1,6 +1,6 @@
use std::time::Duration; use std::time::Duration;
use bevy::{diagnostic::FrameTimeDiagnosticsPlugin, prelude::*}; use bevy::prelude::*;
const LOREM: [&str; 5] = [ const LOREM: [&str; 5] = [
"Ullam nostrum aut amet adipisci consequuntur quisquam nemo consequatur. Vel eum et ullam ullam aperiam earum voluptas consequuntur. Blanditiis earum voluptatem voluptas animi dolorum fuga aliquam ea.\n", "Ullam nostrum aut amet adipisci consequuntur quisquam nemo consequatur. Vel eum et ullam ullam aperiam earum voluptas consequuntur. Blanditiis earum voluptatem voluptas animi dolorum fuga aliquam ea.\n",
@ -23,7 +23,7 @@ fn main() {
.add_startup_system(load_fonts) .add_startup_system(load_fonts)
.add_startup_system(init_ui) .add_startup_system(init_ui)
.add_system(manage_buttons) .add_system(manage_buttons)
.add_system(update) .add_system(update_font)
.add_system(mouse_cursor) .add_system(mouse_cursor)
.add_system(play) .add_system(play)
.run(); .run();
@ -166,24 +166,16 @@ fn manage_buttons(
} }
} }
fn update( fn update_font(
mut texts: Query<&mut Text, (With<Marker>, With<PreviewText>)>, mut texts: Query<&mut Text, (With<Marker>, With<PreviewText>)>,
interaction: Query<(&Interaction, &FontButton), Changed<Interaction>>, interaction: Query<(&Interaction, &FontButton), Changed<Interaction>>,
) { ) {
for (i, f) in interaction.iter() { for (i, f) in interaction.iter() {
match (i, f) { match (i, f) {
(Interaction::Clicked, FontButton(font)) => { (Interaction::Clicked, FontButton(font)) => {
let mut text = texts.single_mut(); texts.single_mut().sections.iter_mut().for_each(|section| {
*text = Text::from_sections(LOREM.iter().flat_map(|&l| { section.style.font = font.clone();
l.chars().map(|c| TextSection { });
value: c.into(),
style: TextStyle {
font: font.clone(),
font_size: 16.0,
..default()
},
})
}));
} }
_ => (), _ => (),
} }
@ -209,24 +201,79 @@ fn play(
interactions: Query<&Interaction, (Changed<Interaction>, With<FontButton>)>, interactions: Query<&Interaction, (Changed<Interaction>, With<FontButton>)>,
time: Res<Time>, time: Res<Time>,
mut duration: Local<Duration>, mut duration: Local<Duration>,
mut desired: Local<Vec<String>>,
) { ) {
for interaction in interactions.iter() { for interaction in interactions.iter() {
match interaction { match interaction {
Interaction::Clicked => *duration = Duration::from_secs(30), Interaction::Clicked => {
if *duration == Duration::ZERO {
// Get end result desired strings
*desired = texts
.single_mut()
.sections
.iter()
.map(|section| section.value.clone())
.collect();
// Clear current text
texts
.single_mut()
.sections
.iter_mut()
.for_each(|section| section.value = String::new());
}
*duration = Duration::from_secs(30);
}
_ => (), _ => (),
} }
} }
// PERF: Why does this slow down immediatly?
if *duration > Duration::ZERO { if *duration > Duration::ZERO {
*duration = duration.saturating_sub(time.delta());
info!("Delta: {:?}", time.delta());
let percentage = 1.0 - (duration.as_secs_f32() / 30.0);
let mut text = texts.single_mut(); let mut text = texts.single_mut();
let total_sections = text.sections.len();
*duration = duration.saturating_sub(time.delta()); let len_total = desired.iter().fold(0, |acc, curr| acc + curr.len());
let mut len_total = ((len_total as f32 * percentage) as usize).min(len_total as usize);
for (section, desired) in text.sections.iter_mut().zip(desired.iter()) {
// This section is empty, initialize with capacity
if len_total == 0 {
break;
for (idx, section) in text.sections.iter_mut().enumerate() { // Total amount of remaining text is greater than this section
let ratio = ((idx + 1) as f32) / (total_sections as f32); // Set this text block to the full section
let cursor = 1.0 - ((*duration).as_secs_f32() / 30.0); } else if len_total >= desired.len() {
let alpha = if cursor > ratio { 1.0 } else { 0.0 }; info!("len_total >= desired.len()");
section.style.color.set_a(alpha); len_total -= desired.len();
if section.value.len() != desired.len() {
info!("value != desired");
section.value = desired.clone();
}
// Total remaining text is less than this section
// Set to a sub-string of text
} else if len_total < desired.len() {
info!("len total < desired len");
// Difference between current value and desired length
let diff = desired
.split_at(section.value.len())
.1
.split_at(len_total - section.value.len())
.0
.into();
info!("adding value {}", diff);
section.value.push_str(diff);
len_total = 0;
// Undefined behavior
} else {
info!("Unexpected text animation situation");
}
} }
} }
} }

Loading…
Cancel
Save