Added creative demo and cleane dup text rendering
This commit is contained in:
parent
35e7832b0b
commit
48b2419a24
@ -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"
|
||||
|
||||
|
||||
BIN
fonts/droid-sans-mono.regular.ttf
Normal file
BIN
fonts/droid-sans-mono.regular.ttf
Normal file
Binary file not shown.
@ -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(),
|
||||
};
|
||||
|
||||
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
96
src/slides/creative_demo.rs
Normal file
96
src/slides/creative_demo.rs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
17
src/utils.rs
17
src/utils.rs
@ -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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user