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.
|
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 args = Args::parse();
|
||||||
|
|
||||||
let heading = load_ttf_font("fonts/BoldPixels.ttf").await.unwrap();
|
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 {
|
let slide_show_theme = SlideShowTheme {
|
||||||
title_config: TextConfigBuilder::default()
|
title_config: TextConfigBuilder::default()
|
||||||
@ -57,7 +59,7 @@ async fn main() {
|
|||||||
body_config: TextConfigBuilder::default()
|
body_config: TextConfigBuilder::default()
|
||||||
.justification(Justified::Left)
|
.justification(Justified::Left)
|
||||||
.font(&body)
|
.font(&body)
|
||||||
.font_size(100)
|
.font_size(60)
|
||||||
.color(WHITE)
|
.color(WHITE)
|
||||||
.build(),
|
.build(),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use crate::slide::Slide;
|
use crate::slide::Slide;
|
||||||
|
use crate::slides::creative_demo::{CreativeDemo, CreativeDemoCfg};
|
||||||
use crate::slides::demo::Demo;
|
use crate::slides::demo::Demo;
|
||||||
use crate::slides::projects::Projects;
|
use crate::slides::projects::Projects;
|
||||||
use crate::slides::standard_slide::{StandardSlide, StandardSlideConfig};
|
use crate::slides::standard_slide::{StandardSlide, StandardSlideConfig};
|
||||||
@ -14,6 +15,7 @@ pub enum SlideType {
|
|||||||
Demo,
|
Demo,
|
||||||
Projects,
|
Projects,
|
||||||
StandardSlide(StandardSlideConfig),
|
StandardSlide(StandardSlideConfig),
|
||||||
|
CreativeDemo(CreativeDemoCfg),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SlideType {
|
impl SlideType {
|
||||||
@ -23,6 +25,7 @@ impl SlideType {
|
|||||||
SlideType::Demo => Demo::new(),
|
SlideType::Demo => Demo::new(),
|
||||||
SlideType::Projects => Projects::new(),
|
SlideType::Projects => Projects::new(),
|
||||||
SlideType::StandardSlide(cfg) => StandardSlide::new(cfg, asset_dir).await,
|
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};
|
use macroquad::input::{KeyCode, is_key_pressed};
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod creative_demo;
|
||||||
pub mod demo;
|
pub mod demo;
|
||||||
pub mod projects;
|
pub mod projects;
|
||||||
pub mod standard_slide;
|
pub mod standard_slide;
|
||||||
|
|||||||
@ -87,12 +87,12 @@ impl Slide for StandardSlide {
|
|||||||
|
|
||||||
let body_pos = Vec2::new(
|
let body_pos = Vec2::new(
|
||||||
screen_width() * 0.05,
|
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(
|
ctx.slide_show_theme.body_config.draw_text_box(
|
||||||
&self.cfg.body,
|
&self.cfg.body,
|
||||||
body_pos,
|
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 {
|
if let Some(image) = &self.image {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use crate::effects::star_field;
|
|||||||
use crate::slide::Slide;
|
use crate::slide::Slide;
|
||||||
use crate::slide_show_config::Context;
|
use crate::slide_show_config::Context;
|
||||||
use crate::text_drawer::TextConfigBuilder;
|
use crate::text_drawer::TextConfigBuilder;
|
||||||
|
use crate::utils::draw_text_with_background;
|
||||||
use macroquad::color::{BLACK, DARKGREEN, LIME};
|
use macroquad::color::{BLACK, DARKGREEN, LIME};
|
||||||
use macroquad::math::Vec2;
|
use macroquad::math::Vec2;
|
||||||
use macroquad::miniquad::window::screen_size;
|
use macroquad::miniquad::window::screen_size;
|
||||||
@ -24,15 +25,15 @@ impl Slide for Title {
|
|||||||
fn display(&mut self, ctx: &Context<'_>) {
|
fn display(&mut self, ctx: &Context<'_>) {
|
||||||
clear_background(BLACK);
|
clear_background(BLACK);
|
||||||
star_field();
|
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 = Vec2::from(screen_size()) * 0.5;
|
||||||
let center_offset = center + Vec2::from(screen_size()) * 0.005;
|
|
||||||
shadow_style.draw_text(&self.title, center_offset);
|
draw_text_with_background(
|
||||||
title_style.draw_text(&self.title, center);
|
&self.title,
|
||||||
|
center,
|
||||||
|
&ctx.slide_show_theme.title_config,
|
||||||
|
LIME,
|
||||||
|
DARKGREEN,
|
||||||
|
);
|
||||||
|
|
||||||
let subtitle_builder: TextConfigBuilder =
|
let subtitle_builder: TextConfigBuilder =
|
||||||
ctx.slide_show_theme.heading_config.clone().into();
|
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 lines: Vec<String> = text.split("\n").map(|s| s.to_string()).collect();
|
||||||
let mut line_pos = pos;
|
let mut line_pos = pos;
|
||||||
|
|
||||||
|
let standard_line_height = self.measure_text("A").height;
|
||||||
|
|
||||||
let mut line_ndx = 0;
|
let mut line_ndx = 0;
|
||||||
loop {
|
loop {
|
||||||
if line_ndx >= lines.len() {
|
if line_ndx >= lines.len() {
|
||||||
@ -141,26 +143,34 @@ impl<'a> TextConfig<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let line = &lines[line_ndx];
|
let line = &lines[line_ndx];
|
||||||
let line_size = self.measure_text(line);
|
|
||||||
let line: Vec<&str> = line.split(" ").collect();
|
let line: Vec<&str> = line.split(" ").collect();
|
||||||
|
|
||||||
let mut word_pos = line_pos;
|
let mut word_pos = line_pos;
|
||||||
|
|
||||||
|
let mut need_line_break = false;
|
||||||
for word_ndx in 0..line.len() {
|
for word_ndx in 0..line.len() {
|
||||||
let word = line[word_ndx];
|
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 measure_text = self.measure_text(&format!("{word} "));
|
||||||
let new_line = format!("\t\t\t{}", line[word_ndx + 1..].join(" "));
|
|
||||||
|
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);
|
lines.insert(line_ndx + 1, new_line);
|
||||||
|
need_line_break = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let word_info = self.draw_text(&format!("{word} "), word_pos);
|
||||||
|
word_pos.x += word_info.text_dimensions.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
line_ndx += 1;
|
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 {
|
if line_pos.y > size.y {
|
||||||
// Stop drawing text
|
// 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::color::Color;
|
||||||
use macroquad::math::Vec2;
|
use macroquad::math::Vec2;
|
||||||
use macroquad::miniquad::window::screen_size;
|
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);
|
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