-
Notifications
You must be signed in to change notification settings - Fork 58
/
Copy pathdraw_path_flower.rs
95 lines (79 loc) · 2.44 KB
/
draw_path_flower.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
// This example is a port of javascript code made by Ibon Tolosona (@hyperandroid)
// https://codepen.io/hyperandroid/full/yLyRQmw
use notan::draw::*;
use notan::prelude::*;
const CENTER_X: f32 = 400.0;
const CENTER_Y: f32 = 300.0;
const START_RADIUS: usize = 20;
const RADIUS_INCREMENT: usize = 13;
const MAX_RADIUS: usize = 250;
const MAX_LINES: usize = (MAX_RADIUS - START_RADIUS) / RADIUS_INCREMENT;
const AMPLITUDE: f32 = 30.0;
const PERIOD: f32 = 6.0;
const PI: f32 = std::f32::consts::PI;
#[notan_main]
fn main() -> Result<(), String> {
notan::init()
.add_config(WindowConfig::new().set_multisampling(8))
.add_config(DrawConfig)
.draw(draw)
.build()
}
fn draw(app: &mut App, gfx: &mut Graphics) {
let time = app.timer.elapsed_f32() * 1000.0;
let mut draw = gfx.create_draw();
draw.clear(Color::BLACK);
let mut count = 0.0;
for (line_index, i) in (START_RADIUS..MAX_RADIUS)
.step_by(RADIUS_INCREMENT as _)
.enumerate()
{
let ti = ((time + line_index as f32 * 79.0) % 2000.0) / 2000.0;
draw_flower(
draw.path(),
i as _,
((time % 38000.0) / 38000.0) * 2.0 * PI,
count,
(ti * PI * 2.0).cos(),
);
count += if line_index <= MAX_LINES / 2 {
2.0
} else {
-2.0
};
}
gfx.render(&draw);
}
fn draw_flower(
mut path_builder: DrawBuilder<Path>,
radius: f32,
initial_angle: f32,
index: f32,
amplitude_modifier: f32,
) {
let segments = (2.0 * PI * radius).floor();
let mut begin = false;
for i in 0..segments as usize {
let n = i as f32;
let period_segments = segments / PERIOD;
let current_periods = n % period_segments;
let radians_period = if current_periods < radius {
current_periods / radius
} else {
0.0
};
let c_radius = radius
+ AMPLITUDE
* (radians_period * (3.0 + index) * PI).sin()
* ((radians_period * PI).sin() / 2.0 * amplitude_modifier);
let radians = n / segments * 2.0 * PI + initial_angle;
let x = CENTER_X + c_radius * radians.cos();
let y = CENTER_Y + c_radius * radians.sin();
if !begin {
path_builder.move_to(x, y);
begin = true;
}
path_builder.line_to(x, y);
}
path_builder.close().color(Color::MAGENTA).stroke(3.0);
}