Added creative demo and cleane dup text rendering

This commit is contained in:
Joey Hines 2026-05-24 19:58:47 -06:00
parent 35e7832b0b
commit 48b2419a24
Signed by: joeyahines
GPG Key ID: E99D8FB14855100E
10 changed files with 156 additions and 18 deletions

View File

@ -93,3 +93,11 @@ until then force attention to zero.
goodbye amigo sorry for the slime.
"""
[[slides]]
type = "CreativeDemo"
title = "Software as a Bit"
[[slides]]
type = "CreativeDemo"
title = "Software as a Creative Outlet"

Binary file not shown.

View File

@ -39,7 +39,9 @@ async fn main() {
let args = Args::parse();
let heading = load_ttf_font("fonts/BoldPixels.ttf").await.unwrap();
let body = load_ttf_font("fonts/ByteBounce.ttf").await.unwrap();
let body = load_ttf_font("fonts/droid-sans-mono.regular.ttf")
.await
.unwrap();
let slide_show_theme = SlideShowTheme {
title_config: TextConfigBuilder::default()
@ -57,7 +59,7 @@ async fn main() {
body_config: TextConfigBuilder::default()
.justification(Justified::Left)
.font(&body)
.font_size(100)
.font_size(60)
.color(WHITE)
.build(),
};

View File

@ -1,4 +1,5 @@
use crate::slide::Slide;
use crate::slides::creative_demo::{CreativeDemo, CreativeDemoCfg};
use crate::slides::demo::Demo;
use crate::slides::projects::Projects;
use crate::slides::standard_slide::{StandardSlide, StandardSlideConfig};
@ -14,6 +15,7 @@ pub enum SlideType {
Demo,
Projects,
StandardSlide(StandardSlideConfig),
CreativeDemo(CreativeDemoCfg),
}
impl SlideType {
@ -23,6 +25,7 @@ impl SlideType {
SlideType::Demo => Demo::new(),
SlideType::Projects => Projects::new(),
SlideType::StandardSlide(cfg) => StandardSlide::new(cfg, asset_dir).await,
SlideType::CreativeDemo(cfg) => CreativeDemo::new(cfg),
}
}
}

View File

@ -0,0 +1,96 @@
use crate::effects::star_field;
use crate::slide::Slide;
use crate::slide_show_config::Context;
use crate::utils::{draw_text_with_background, screen_center};
use macroquad::color::{BLACK, Color, ORANGE, VIOLET};
use macroquad::math::Vec2;
use macroquad::prelude::{
BLUE, GREEN, RED, YELLOW, clear_background,
};
use macroquad::time::get_time;
use macroquad::window::{screen_height, screen_width};
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct CreativeDemoCfg {
pub title: String,
}
#[derive(Debug)]
pub struct CreativeDemo {
cfg: CreativeDemoCfg,
animation_state: usize,
last_update: f64,
first_display: bool,
}
impl CreativeDemo {
pub fn new(cfg: CreativeDemoCfg) -> Box<Self> {
Box::new(Self {
cfg,
animation_state: 0,
last_update: 0.0,
first_display: false,
})
}
}
impl Slide for CreativeDemo {
fn display(&mut self, ctx: &Context<'_>) {
if self.first_display {
self.first_display = true;
self.last_update = get_time();
}
clear_background(BLACK);
star_field();
let rainbow = [
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
Color::from_hex(0x4B0082),
VIOLET,
];
let mid_point = rainbow.len() / 2;
for ndx in (0..=self.animation_state).rev() {
if ndx == 0 {
let bg_color = rainbow[mid_point].with_alpha(0.8);
draw_text_with_background(
&self.cfg.title,
screen_center(),
&ctx.slide_show_theme.heading_config,
rainbow[mid_point],
bg_color,
);
} else {
let offset = Vec2::new(screen_width(), -screen_height()) * 0.05 * ndx as f32;
let ne_bg_color = rainbow[mid_point + ndx].with_alpha(0.8);
draw_text_with_background(
&self.cfg.title,
screen_center() + offset,
&ctx.slide_show_theme.heading_config,
rainbow[mid_point - ndx],
ne_bg_color,
);
let sw_bg_color = rainbow[mid_point - ndx].with_alpha(0.8);
draw_text_with_background(
&self.cfg.title,
screen_center() - offset,
&ctx.slide_show_theme.heading_config,
rainbow[mid_point + ndx],
sw_bg_color,
);
}
}
if get_time() - self.last_update > 0.5 {
self.animation_state = (self.animation_state + 1) % (mid_point + 1);
self.last_update = get_time();
}
}
}

View File

@ -5,6 +5,7 @@ use macroquad::camera::set_default_camera;
use macroquad::input::{KeyCode, is_key_pressed};
pub mod config;
pub mod creative_demo;
pub mod demo;
pub mod projects;
pub mod standard_slide;

View File

@ -87,12 +87,12 @@ impl Slide for StandardSlide {
let body_pos = Vec2::new(
screen_width() * 0.05,
screen_height() * 0.33 + info.text_dimensions.height,
screen_height() * 0.25 + info.text_dimensions.height,
);
ctx.slide_show_theme.body_config.draw_text_box(
&self.cfg.body,
body_pos,
Vec2::new(screen_width() * 0.5, screen_height() * 0.8),
Vec2::new(screen_width() * 0.55, screen_height() * 0.8),
);
if let Some(image) = &self.image {

View File

@ -2,6 +2,7 @@ use crate::effects::star_field;
use crate::slide::Slide;
use crate::slide_show_config::Context;
use crate::text_drawer::TextConfigBuilder;
use crate::utils::draw_text_with_background;
use macroquad::color::{BLACK, DARKGREEN, LIME};
use macroquad::math::Vec2;
use macroquad::miniquad::window::screen_size;
@ -24,15 +25,15 @@ impl Slide for Title {
fn display(&mut self, ctx: &Context<'_>) {
clear_background(BLACK);
star_field();
let title_builder: TextConfigBuilder = ctx.slide_show_theme.title_config.clone().into();
let shadow_style = title_builder.clone().color(DARKGREEN).build();
let title_style = title_builder.color(LIME).build();
let center = Vec2::from(screen_size()) * 0.5;
let center_offset = center + Vec2::from(screen_size()) * 0.005;
shadow_style.draw_text(&self.title, center_offset);
title_style.draw_text(&self.title, center);
draw_text_with_background(
&self.title,
center,
&ctx.slide_show_theme.title_config,
LIME,
DARKGREEN,
);
let subtitle_builder: TextConfigBuilder =
ctx.slide_show_theme.heading_config.clone().into();

View File

@ -134,6 +134,8 @@ impl<'a> TextConfig<'a> {
let mut lines: Vec<String> = text.split("\n").map(|s| s.to_string()).collect();
let mut line_pos = pos;
let standard_line_height = self.measure_text("A").height;
let mut line_ndx = 0;
loop {
if line_ndx >= lines.len() {
@ -141,26 +143,34 @@ impl<'a> TextConfig<'a> {
}
let line = &lines[line_ndx];
let line_size = self.measure_text(line);
let line: Vec<&str> = line.split(" ").collect();
let mut word_pos = line_pos;
let mut need_line_break = false;
for word_ndx in 0..line.len() {
let word = line[word_ndx];
let word_info = self.draw_text(&format!("{word} "), word_pos);
word_pos.x += word_info.text_dimensions.width;
if word_pos.x > size.x {
let new_line = format!("\t\t\t{}", line[word_ndx + 1..].join(" "));
let measure_text = self.measure_text(&format!("{word} "));
if measure_text.width + word_pos.x > size.x {
let new_line = format!("\t\t\t{}", line[word_ndx..].join(" "));
lines.insert(line_ndx + 1, new_line);
need_line_break = true;
break;
}
let word_info = self.draw_text(&format!("{word} "), word_pos);
word_pos.x += word_info.text_dimensions.width;
}
line_ndx += 1;
line_pos.y += line_size.height * 1.2;
if need_line_break {
line_pos.y += standard_line_height * 1.5;
} else {
line_pos.y += standard_line_height * 2.0;
}
if line_pos.y > size.y {
// Stop drawing text

View File

@ -1,3 +1,4 @@
use crate::text_drawer::{TextConfig, TextConfigBuilder};
use macroquad::color::Color;
use macroquad::math::Vec2;
use macroquad::miniquad::window::screen_size;
@ -26,3 +27,19 @@ pub fn draw_rectangle_with_border(
);
draw_rectangle(rect_pos.x, rect_pos.y, rect_size.x, rect_size.y, fg_color);
}
pub fn draw_text_with_background<'a>(
text: &str,
pos: Vec2,
base_config: &TextConfig<'a>,
fg_color: Color,
bg_color: Color,
) {
let title_builder: TextConfigBuilder = base_config.clone().into();
let shadow_style = title_builder.clone().color(bg_color).build();
let title_style = title_builder.color(fg_color).build();
let offset = pos + (pos * 0.005);
shadow_style.draw_text(text, offset);
title_style.draw_text(text, pos);
}