Add a glow effect to the cyberpunk-splash line drawing #48
|
@ -143,6 +143,15 @@ impl SplashPrivate {
|
|||
}
|
||||
|
||||
fn redraw_background(&self) {
|
||||
let pen = GlowPen::new(
|
||||
*self.width.borrow(),
|
||||
*self.height.borrow(),
|
||||
2.,
|
||||
8.,
|
||||
8.,
|
||||
(0.7, 0., 1.),
|
||||
);
|
||||
|
||||
let background =
|
||||
ImageSurface::create(Format::Rgb24, *self.width.borrow(), *self.height.borrow())
|
||||
.unwrap();
|
||||
|
@ -175,11 +184,8 @@ impl SplashPrivate {
|
|||
invert: false,
|
||||
};
|
||||
|
||||
context.set_line_cap(LineCap::Round);
|
||||
context.set_source_rgb(0.7, 0., 1.);
|
||||
context.set_line_width(2.);
|
||||
title_cutout.draw(&context);
|
||||
let _ = context.stroke();
|
||||
title_cutout.draw(&pen);
|
||||
pen.stroke();
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -200,7 +206,6 @@ impl SplashPrivate {
|
|||
}
|
||||
|
||||
{
|
||||
context.set_source_rgb(0.7, 0., 1.);
|
||||
AsymLine {
|
||||
orientation: gtk::Orientation::Horizontal,
|
||||
start_x: 100.,
|
||||
|
@ -210,8 +215,8 @@ impl SplashPrivate {
|
|||
total_length: 650.,
|
||||
invert: true,
|
||||
}
|
||||
.draw(&context);
|
||||
let _ = context.stroke();
|
||||
.draw(&pen);
|
||||
pen.stroke();
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -225,10 +230,14 @@ impl SplashPrivate {
|
|||
total_length: 650.,
|
||||
invert: false,
|
||||
}
|
||||
.draw(&context);
|
||||
let _ = context.stroke();
|
||||
.draw(&pen);
|
||||
pen.stroke();
|
||||
}
|
||||
|
||||
let tracery = pen.finish();
|
||||
let _ = context.set_source(tracery);
|
||||
let _ = context.paint();
|
||||
|
||||
let background = context.pop_group().unwrap();
|
||||
|
||||
*self.background.borrow_mut() = background;
|
||||
|
@ -394,7 +403,7 @@ struct AsymLineCutout {
|
|||
}
|
||||
|
||||
impl AsymLineCutout {
|
||||
fn draw(&self, context: &Context) {
|
||||
fn draw(&self, pen: &impl Pen) {
|
||||
let dodge = if self.invert {
|
||||
self.height
|
||||
} else {
|
||||
|
@ -402,17 +411,17 @@ impl AsymLineCutout {
|
|||
};
|
||||
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(
|
||||
pen.move_to(self.start_x, self.start_y);
|
||||
pen.line_to(self.start_x + self.start_length, self.start_y);
|
||||
pen.line_to(
|
||||
self.start_x + self.start_length + self.height,
|
||||
self.start_y + dodge,
|
||||
);
|
||||
context.line_to(
|
||||
pen.line_to(
|
||||
self.start_x + self.start_length + self.height + self.cutout_length,
|
||||
self.start_y + dodge,
|
||||
);
|
||||
context.line_to(
|
||||
pen.line_to(
|
||||
self.start_x
|
||||
+ self.start_length
|
||||
+ self.height
|
||||
|
@ -420,20 +429,20 @@ impl AsymLineCutout {
|
|||
+ (self.height / 2.),
|
||||
self.start_y + dodge / 2.,
|
||||
);
|
||||
context.line_to(self.total_length, self.start_y + dodge / 2.);
|
||||
pen.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(
|
||||
pen.move_to(self.start_x, self.start_y);
|
||||
pen.line_to(self.start_x, self.start_y + self.start_length);
|
||||
pen.line_to(
|
||||
self.start_x + dodge,
|
||||
self.start_y + self.start_length + self.height,
|
||||
);
|
||||
context.line_to(
|
||||
pen.line_to(
|
||||
self.start_x + dodge,
|
||||
self.start_y + self.start_length + self.height + self.cutout_length,
|
||||
);
|
||||
context.line_to(
|
||||
pen.line_to(
|
||||
self.start_x + dodge / 2.,
|
||||
self.start_y
|
||||
+ self.start_length
|
||||
|
@ -441,7 +450,7 @@ impl AsymLineCutout {
|
|||
+ self.cutout_length
|
||||
+ (self.height / 2.),
|
||||
);
|
||||
context.line_to(self.start_x + dodge / 2., self.total_length);
|
||||
pen.line_to(self.start_x + dodge / 2., self.total_length);
|
||||
}
|
||||
_ => panic!("unknown orientation"),
|
||||
}
|
||||
|
@ -459,7 +468,7 @@ struct AsymLine {
|
|||
}
|
||||
|
||||
impl AsymLine {
|
||||
fn draw(&self, context: &Context) {
|
||||
fn draw(&self, pen: &impl Pen) {
|
||||
let dodge = if self.invert {
|
||||
self.height
|
||||
} else {
|
||||
|
@ -467,13 +476,13 @@ impl AsymLine {
|
|||
};
|
||||
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(
|
||||
pen.move_to(self.start_x, self.start_y);
|
||||
pen.line_to(self.start_x + self.start_length, self.start_y);
|
||||
pen.line_to(
|
||||
self.start_x + self.start_length + self.height,
|
||||
self.start_y + dodge,
|
||||
);
|
||||
context.line_to(self.start_x + self.total_length, self.start_y + dodge);
|
||||
pen.line_to(self.start_x + self.total_length, self.start_y + dodge);
|
||||
}
|
||||
gtk::Orientation::Vertical => {}
|
||||
_ => panic!("unknown orientation"),
|
||||
|
@ -551,6 +560,80 @@ impl SlashMeter {
|
|||
}
|
||||
}
|
||||
|
||||
trait Pen {
|
||||
fn move_to(&self, x: f64, y: f64);
|
||||
fn line_to(&self, x: f64, y: f64);
|
||||
fn stroke(&self);
|
||||
|
||||
fn finish(self) -> Pattern;
|
||||
}
|
||||
|
||||
struct GlowPen {
|
||||
blur_context: Context,
|
||||
draw_context: Context,
|
||||
|
||||
line_width: f64,
|
||||
blur_line_width: f64,
|
||||
blur_size: f64,
|
||||
}
|
||||
|
||||
impl GlowPen {
|
||||
fn new(
|
||||
width: i32,
|
||||
height: i32,
|
||||
line_width: f64,
|
||||
blur_line_width: f64,
|
||||
blur_size: f64,
|
||||
color: (f64, f64, f64),
|
||||
) -> Self {
|
||||
let blur_context =
|
||||
Context::new(ImageSurface::create(Format::Rgb24, width, height).unwrap()).unwrap();
|
||||
blur_context.set_line_width(blur_line_width);
|
||||
blur_context.set_source_rgba(color.0, color.1, color.2, 0.5);
|
||||
blur_context.push_group();
|
||||
blur_context.set_line_cap(LineCap::Round);
|
||||
|
||||
let draw_context =
|
||||
Context::new(ImageSurface::create(Format::Rgb24, width, height).unwrap()).unwrap();
|
||||
draw_context.set_line_width(line_width);
|
||||
draw_context.set_source_rgb(color.0, color.1, color.2);
|
||||
draw_context.push_group();
|
||||
draw_context.set_line_cap(LineCap::Round);
|
||||
|
||||
Self {
|
||||
blur_context,
|
||||
draw_context,
|
||||
line_width,
|
||||
blur_line_width,
|
||||
blur_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Pen for GlowPen {
|
||||
fn move_to(&self, x: f64, y: f64) {
|
||||
self.blur_context.move_to(x, y);
|
||||
self.draw_context.move_to(x, y);
|
||||
}
|
||||
|
||||
fn line_to(&self, x: f64, y: f64) {
|
||||
self.blur_context.line_to(x, y);
|
||||
self.draw_context.line_to(x, y);
|
||||
}
|
||||
|
||||
fn stroke(&self) {
|
||||
self.blur_context.stroke();
|
||||
self.draw_context.stroke();
|
||||
}
|
||||
|
||||
fn finish(self) -> Pattern {
|
||||
let foreground = self.draw_context.pop_group().unwrap();
|
||||
self.blur_context.set_source(foreground).unwrap();
|
||||
self.blur_context.paint().unwrap();
|
||||
self.blur_context.pop_group().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let app = gtk::Application::builder()
|
||||
.application_id("com.luminescent-dreams.cyberpunk-splash")
|
||||
|
|
Loading…
Reference in New Issue