Create a cyberpunk-style splash screen with a title and a countdown #39

Merged
savanni merged 11 commits from cyberpunk-display into main 2023-04-13 23:14:29 +00:00
1 changed files with 122 additions and 16 deletions
Showing only changes of commit 5e57767921 - Show all commits

View File

@ -1,4 +1,6 @@
use cairo::{Context, FontFace, Format, ImageSurface, LineCap, Pattern}; use cairo::{
Context, FontSlant, FontWeight, Format, ImageSurface, LineCap, LinearGradient, Pattern,
};
use glib::Object; use glib::Object;
use gtk::{prelude::*, subclass::prelude::*}; use gtk::{prelude::*, subclass::prelude::*};
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
@ -28,24 +30,53 @@ impl SplashPrivate {
context.set_source_rgb(0., 0., 0.); context.set_source_rgb(0., 0., 0.);
let _ = context.paint(); let _ = context.paint();
context.select_font_face("Alegreya Sans SC", FontSlant::Normal, FontWeight::Bold);
context.set_font_size(64.); context.set_font_size(64.);
let title_extents = context.text_extents(&self.text.borrow()).unwrap(); let center_x = WIDTH as f64 / 2.;
let center_y = HEIGHT as f64 / 2.;
context.set_source_rgb(0.7, 0., 1.); let (title_width, title_height) = {
context.set_line_width(5.); let title_extents = context.text_extents(&self.text.borrow()).unwrap();
context.set_line_cap(LineCap::Round);
AsymLineReturn { let title_baseline_x = center_x - title_extents.width() / 2.;
orientation: gtk::Orientation::Horizontal, let title_baseline_y = center_y - 20.;
start_x: 20.,
start_y: 20., let gradient = LinearGradient::new(
start_length: 200., title_baseline_x,
center_length: title_extents.y_advance(), title_baseline_y - title_extents.height(),
end_length: 100., title_baseline_x,
width: title_extents.height(), title_baseline_y,
);
gradient.add_color_stop_rgb(0.2, 0.7, 0.0, 1.0);
gradient.add_color_stop_rgb(0.8, 0.2, 0.0, 1.0);
context.move_to(title_baseline_x, title_baseline_y);
let _ = context.set_source(gradient);
let _ = context.show_text(&self.text.borrow());
(title_extents.width(), title_extents.height())
};
{
context.set_source_rgb(0.7, 0., 1.);
context.set_line_width(5.);
context.set_line_cap(LineCap::Round);
let start_length = center_x - title_width / 2. - title_height - 20.;
AsymLineCutout {
orientation: gtk::Orientation::Horizontal,
start_x: 20.,
start_y: center_y - 20. - title_height / 2.,
start_length,
total_length: WIDTH as f64 - 120.,
cutout_length: title_width,
height: title_height,
invert: false,
}
.draw(&context);
let _ = context.stroke();
} }
.draw(&context);
let _ = context.stroke();
let background = context.pop_group().unwrap(); let background = context.pop_group().unwrap();
@ -106,6 +137,81 @@ impl Splash {
} }
} }
struct AsymLineCutout {
orientation: gtk::Orientation,
start_x: f64,
start_y: f64,
start_length: f64,
total_length: f64,
cutout_length: f64,
height: f64,
invert: bool,
}
impl AsymLineCutout {
fn draw(&self, context: &Context) {
let dodge = if self.invert {
self.height
} else {
-self.height
};
match self.orientation {
gtk::Orientation::Horizontal => {
context.move_to(self.start_x, self.start_y);
context.line_to(self.start_x + self.start_length, self.start_y);
context.line_to(
self.start_x + self.start_length + self.height,
self.start_y + dodge,
);
context.line_to(
self.start_x + self.start_length + self.height + self.cutout_length,
self.start_y + dodge,
);
context.line_to(
self.start_x
+ self.start_length
+ self.height
+ self.cutout_length
+ (self.height / 2.),
self.start_y + dodge / 2.,
);
context.line_to(self.total_length, self.start_y + dodge / 2.);
}
gtk::Orientation::Vertical => {
/*
context.move_to(self.start_x, self.start_y);
context.line_to(self.start_x, self.start_y + self.start_length);
context.line_to(
self.start_x + self.height,
self.start_y + self.start_length + self.height,
);
context.line_to(
self.start_x + self.height,
self.start_y + self.start_length + self.height + self.center_length,
);
context.line_to(
self.start_x + self.height / 2.,
self.start_y
+ self.start_length
+ self.height
+ self.center_length
+ (self.height / 2.),
);
context.line_to(
self.start_x + self.height / 2.,
self.start_y
+ self.start_length
+ self.height
+ self.center_length
+ (self.height / 2.)
+ self.end_length,
);
*/
}
_ => panic!("unknown orientation"),
}
}
}
struct AsymLineReturn { struct AsymLineReturn {
orientation: gtk::Orientation, orientation: gtk::Orientation,
start_x: f64, start_x: f64,
@ -191,7 +297,7 @@ fn main() {
let window = gtk::ApplicationWindow::new(app); let window = gtk::ApplicationWindow::new(app);
window.present(); window.present();
window.set_child(Some(&Splash::new("Kifu".to_owned(), "4:23".to_owned()))); window.set_child(Some(&Splash::new("GTK Kifu".to_owned(), "4:23".to_owned())));
}); });
app.run(); app.run();