-
Notifications
You must be signed in to change notification settings - Fork 6
/
wibble.rs
100 lines (80 loc) · 3.77 KB
/
wibble.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use flo_draw::*;
use flo_draw::canvas::*;
use flo_curves::*;
use flo_curves::bezier::*;
use flo_curves::bezier::path::*;
use futures::prelude::*;
use futures::executor;
use futures::stream;
use std::f64;
use std::thread;
use std::sync::*;
use std::time::{Duration, Instant};
///
/// Demonstrates capturing the paths for text rendering, and then distorting them using flo_curves
///
pub fn main() {
with_2d_graphics(|| {
let lato = CanvasFontFace::from_slice(include_bytes!("Lato-Regular.ttf"));
// Create a window
let canvas = create_drawing_window("Wibble");
// Measure the text
let text_string = "Wibble";
let wibble_size = measure_text(&lato, text_string, 200.0);
let (min, max) = wibble_size.inner_bounds;
let x_pos = (1000.0 - (max.x()-min.x()))/2.0;
let y_pos = 400.0;
// Render the text to a set of paths
let mut render_text = vec![];
render_text.define_font_data(FontId(1), Arc::clone(&lato));
render_text.set_font_size(FontId(1), 200.0);
render_text.draw_text(FontId(1), text_string.to_string(), x_pos as _, y_pos as _);
// Lay out the text, convert the glyphs to paths, convert the drawing instructions to SimpleBezierPaths
let render_text = stream::iter(render_text.into_iter());
let text_paths = drawing_with_laid_out_text(render_text);
let text_paths = drawing_with_text_as_paths(text_paths);
let text_paths = drawing_to_paths::<SimpleBezierPath, _>(text_paths);
let text_paths = executor::block_on(async move { text_paths.collect::<Vec<_>>().await });
// Draw the text with a moving distortion
let start_time = Instant::now();
loop {
// Get the current time where we're rendering this
let since_start = Instant::now().duration_since(start_time);
let since_start = since_start.as_nanos() as f64;
let amplitude = 12.0;
// Distort each of the paths in turn
let distorted_text_paths = text_paths.iter()
.map(|path_set| path_set.iter()
.map(move |path: &SimpleBezierPath| distort_path::<_, _, SimpleBezierPath>(path, |point: Coord2, _curve, _t| {
let distance = point.magnitude();
let ripple = (since_start / (f64::consts::PI * 500_000_000.0)) * 10.0;
let offset_x = (distance / (f64::consts::PI*5.0) + ripple).sin() * amplitude * 0.5;
let offset_y = (distance / (f64::consts::PI*4.0) + ripple).cos() * amplitude * 0.5;
Coord2(point.x() + offset_x, point.y() + offset_y)
}, 1.0, 0.1).unwrap())
.collect::<Vec<_>>());
// Render the current frame
canvas.draw(|gc| {
// Clear the canvas
gc.clear_canvas(Color::Rgba(0.7, 0.9, 0.9, 1.0));
gc.canvas_height(1000.0);
gc.center_region(0.0, 0.0, 1000.0, 1000.0);
gc.fill_color(Color::Rgba(1.0, 1.0, 1.0, 1.0));
gc.stroke_color(Color::Rgba(0.0, 0.0, 0.0, 1.0));
gc.line_width(6.0);
// Render the distorted paths
for path_set in distorted_text_paths {
gc.new_path();
for path in path_set {
gc.bezier_path(&path);
gc.close_path();
}
gc.fill();
gc.stroke();
}
});
// Wait for the next frame
thread::sleep(Duration::from_nanos(1_000_000_000 / 60));
}
});
}