···
1
1
-
use crate::State;
2
2
-
use itertools::Itertools;
3
3
-
use shapemaker::*;
4
4
-
5
5
-
pub fn intro() -> Scene<State> {
6
6
-
Scene::<State>::new("intro")
7
7
-
.init(&|canvas, _| {
8
8
-
canvas.clear();
9
9
-
canvas.set_background(Color::Black);
10
10
-
11
11
-
let mut kicks = Layer::new("anchor kick");
12
12
-
13
13
-
let circle_at = |x: usize, y: usize| Object::SmallCircle(Point(x, y));
14
14
-
15
15
-
let (end_x, end_y) = {
16
16
-
let Point(x, y) = canvas.world_region.end;
17
17
-
(x - 2, y - 2)
18
18
-
};
19
19
-
kicks.set("top left", circle_at(1, 1));
20
20
-
kicks.set("top right", circle_at(end_x, 1));
21
21
-
kicks.set("bottom left", circle_at(1, end_y));
22
22
-
kicks.set("bottom right", circle_at(end_x, end_y));
23
23
-
canvas.add_or_replace_layer(kicks);
24
24
-
25
25
-
let mut ch = Layer::new("ch");
26
26
-
ch.set("0", Object::Dot(Point(0, 0)));
27
27
-
canvas.add_or_replace_layer(ch);
28
28
-
29
29
-
Ok(())
30
30
-
})
31
31
-
.on_note("anchor kick", &|canvas, ctx| {
32
32
-
canvas
33
33
-
.layer("anchor kick")
34
34
-
.paint_all_objects(Fill::Translucent(ctx.extra.kick_color, 1.0));
35
35
-
36
36
-
ctx.animate_layer("anchor kick", 200, &|t, layer, _| {
37
37
-
layer.objects.values_mut().for_each(
38
38
-
|ColoredObject { fill, .. }| {
39
39
-
*fill = fill.opacify(1.0 - t);
40
40
-
},
41
41
-
);
42
42
-
Ok(())
43
43
-
});
44
44
-
45
45
-
Ok(())
46
46
-
})
47
47
-
.on_note("bass", &|canvas, ctx| {
48
48
-
let pitch = ctx
49
49
-
.notes_of_stem("bass")
50
50
-
.find(|note| note.is_on())
51
51
-
.map(|note| note.pitch);
52
52
-
53
53
-
let area = (2, 2);
54
54
-
let bounds = canvas.world_region.resized(-2, -2);
55
55
-
ctx.extra.bass_pattern_at = match pitch {
56
56
-
Some(32 | 33 | 34) => bounds.starting_from_topleft(area),
57
57
-
Some(39) => bounds.starting_from_topright(area),
58
58
-
Some(35) => bounds.starting_from_bottomleft(area),
59
59
-
Some(42 | 41) => bounds.starting_from_bottomright(area),
60
60
-
_ => bounds.starting_from_bottomleft(area),
61
61
-
}
62
62
-
.unwrap();
63
63
-
64
64
-
let mut bass = canvas.random_layer_within(
65
65
-
&mut ctx.extra.rng,
66
66
-
"bass",
67
67
-
&ctx.extra.bass_pattern_at,
68
68
-
);
69
69
-
70
70
-
bass.paint_all_objects(Fill::Solid(Color::White));
71
71
-
canvas.add_or_replace_layer(bass);
72
72
-
73
73
-
Ok(())
74
74
-
})
75
75
-
.on_note("powerful clap hit, clap, perclap", &|canvas, ctx| {
76
76
-
let mut claps = canvas.random_layer_within(
77
77
-
&mut ctx.extra.rng,
78
78
-
"claps",
79
79
-
&ctx.extra.bass_pattern_at.translated(2, 0),
80
80
-
);
81
81
-
claps.paint_all_objects(Fill::Solid(Color::Red));
82
82
-
canvas.add_or_replace_layer(claps);
83
83
-
Ok(())
84
84
-
})
85
85
-
.on_note(
86
86
-
"rimshot, glitchy percs, hitting percs, glitchy percs",
87
87
-
&|canvas, ctx| {
88
88
-
let mut foley = canvas.random_layer_within(
89
89
-
&mut ctx.extra.rng,
90
90
-
"percs",
91
91
-
&ctx.extra.bass_pattern_at.translated(2, 0),
92
92
-
);
93
93
-
foley.paint_all_objects(Fill::Translucent(Color::Red, 0.5));
94
94
-
canvas.add_or_replace_layer(foley);
95
95
-
Ok(())
96
96
-
},
97
97
-
)
98
98
-
.on_note("qanda", &|canvas, ctx| {
99
99
-
let canvas_line_width = canvas.object_sizes.default_line_width;
100
100
-
let mut qanda = canvas.random_curves_within(
101
101
-
&mut ctx.extra.rng,
102
102
-
"qanda",
103
103
-
&ctx.extra.bass_pattern_at.translated(-1, -1).enlarged(1, 1),
104
104
-
3..=5,
105
105
-
);
106
106
-
qanda.paint_all_objects(Fill::Solid(Color::Orange));
107
107
-
qanda.object_sizes.default_line_width =
108
108
-
canvas_line_width * 4.0 * ctx.stem("qanda").velocity_relative();
109
109
-
110
110
-
canvas.add_or_replace_layer(qanda);
111
111
-
Ok(())
112
112
-
})
113
113
-
.on_note("brokenup", &|canvas, ctx| {
114
114
-
let canvas_line_width = canvas.object_sizes.default_line_width;
115
115
-
let mut brokenup = canvas.random_curves_within(
116
116
-
&mut ctx.extra.rng,
117
117
-
"brokenup",
118
118
-
&ctx.extra.bass_pattern_at.translated(0, -2),
119
119
-
3..=5,
120
120
-
);
121
121
-
brokenup.paint_all_objects(Fill::Solid(Color::Yellow));
122
122
-
brokenup.object_sizes.default_line_width = canvas_line_width
123
123
-
* 4.0
124
124
-
* ctx.stem("brokenup").velocity_relative();
125
125
-
126
126
-
canvas.add_or_replace_layer(brokenup);
127
127
-
Ok(())
128
128
-
})
129
129
-
.on_note("goup", &|canvas, ctx| {
130
130
-
let canvas_line_width = canvas.object_sizes.default_line_width;
131
131
-
let mut goup = canvas.random_curves_within(
132
132
-
&mut ctx.extra.rng,
133
133
-
"goup",
134
134
-
&ctx.extra.bass_pattern_at.translated(0, 2),
135
135
-
3..=5,
136
136
-
);
137
137
-
goup.paint_all_objects(Fill::Solid(Color::Green));
138
138
-
goup.object_sizes.default_line_width =
139
139
-
canvas_line_width * 4.0 * ctx.stem("goup").velocity_relative();
140
140
-
141
141
-
canvas.add_or_replace_layer(goup);
142
142
-
Ok(())
143
143
-
})
144
144
-
.on_note("ch", &|canvas, ctx| {
145
145
-
let world = canvas.world_region.clone();
146
146
-
147
147
-
// keep only the last 2 dots
148
148
-
let dots_to_keep = canvas
149
149
-
.layer("ch")
150
150
-
.objects
151
151
-
.iter()
152
152
-
.sorted_by_key(|(name, _)| name.parse::<usize>().unwrap())
153
153
-
.rev()
154
154
-
.take(2)
155
155
-
.map(|(name, _)| name.clone())
156
156
-
.collect::<Vec<_>>();
157
157
-
158
158
-
let layer = canvas.layer("ch");
159
159
-
layer.object_sizes.empty_shape_stroke_width = 2.0;
160
160
-
layer.objects.retain(|name, _| dots_to_keep.contains(name));
161
161
-
162
162
-
let object_name = format!("{}", ctx.ms);
163
163
-
layer.set(
164
164
-
&object_name,
165
165
-
Object::Dot(
166
166
-
world.resized(-1, -1).random_point(&mut ctx.extra.rng),
167
167
-
)
168
168
-
.colored(Color::Cyan),
169
169
-
);
170
170
-
171
171
-
canvas.put_layer_on_top("ch");
172
172
-
Ok(())
173
173
-
})
174
174
-
}
1
1
+
use crate::State;
2
2
+
use itertools::Itertools;
3
3
+
use shapemaker::*;
4
4
+
5
5
+
pub fn intro() -> Scene<State> {
6
6
+
Scene::<State>::new("intro")
7
7
+
.init(&|canvas, _| {
8
8
+
canvas.clear();
9
9
+
canvas.set_background(Color::Black);
10
10
+
11
11
+
let mut kicks = Layer::new("anchor kick");
12
12
+
13
13
+
let circle_at = |x: usize, y: usize| Object::SmallCircle(Point(x, y));
14
14
+
15
15
+
let (end_x, end_y) = {
16
16
+
let Point(x, y) = canvas.world_region.end;
17
17
+
(x - 2, y - 2)
18
18
+
};
19
19
+
kicks.set("top left", circle_at(1, 1));
20
20
+
kicks.set("top right", circle_at(end_x, 1));
21
21
+
kicks.set("bottom left", circle_at(1, end_y));
22
22
+
kicks.set("bottom right", circle_at(end_x, end_y));
23
23
+
canvas.add_or_replace_layer(kicks);
24
24
+
25
25
+
let mut ch = Layer::new("ch");
26
26
+
ch.set("0", Object::Dot(Point(0, 0)));
27
27
+
canvas.add_or_replace_layer(ch);
28
28
+
29
29
+
Ok(())
30
30
+
})
31
31
+
.on_note("anchor kick", &|canvas, ctx| {
32
32
+
canvas
33
33
+
.layer("anchor kick")
34
34
+
.paint_all_objects(Fill::Translucent(ctx.extra.kick_color, 1.0));
35
35
+
36
36
+
ctx.animate_layer("anchor kick", 200, &|t, layer, _| {
37
37
+
layer.objects.values_mut().for_each(
38
38
+
|ColoredObject { fill, .. }| {
39
39
+
*fill = fill.opacify(1.0 - t);
40
40
+
},
41
41
+
);
42
42
+
Ok(())
43
43
+
});
44
44
+
45
45
+
Ok(())
46
46
+
})
47
47
+
.on_note("bass", &|canvas, ctx| {
48
48
+
let pitch = ctx
49
49
+
.notes_of_stem("bass")
50
50
+
.find(|note| note.is_on())
51
51
+
.map(|note| note.pitch);
52
52
+
53
53
+
let area = (2, 2);
54
54
+
let bounds = canvas.world_region.resized(-2, -2);
55
55
+
ctx.extra.bass_pattern_at = match pitch {
56
56
+
Some(32 | 33 | 34) => bounds.starting_from_topleft(area),
57
57
+
Some(39) => bounds.starting_from_topright(area),
58
58
+
Some(35) => bounds.starting_from_bottomleft(area),
59
59
+
Some(42 | 41) => bounds.starting_from_bottomright(area),
60
60
+
_ => bounds.starting_from_bottomleft(area),
61
61
+
}
62
62
+
.unwrap();
63
63
+
64
64
+
let mut bass = canvas.random_layer_within(
65
65
+
&mut ctx.extra.rng,
66
66
+
"bass",
67
67
+
&ctx.extra.bass_pattern_at,
68
68
+
);
69
69
+
70
70
+
bass.paint_all_objects(Fill::Solid(Color::White));
71
71
+
canvas.add_or_replace_layer(bass);
72
72
+
73
73
+
Ok(())
74
74
+
})
75
75
+
.on_note("powerful clap hit, clap, perclap", &|canvas, ctx| {
76
76
+
let mut claps = canvas.random_layer_within(
77
77
+
&mut ctx.extra.rng,
78
78
+
"claps",
79
79
+
&ctx.extra.bass_pattern_at.translated(2, 0),
80
80
+
);
81
81
+
claps.paint_all_objects(Fill::Solid(Color::Red));
82
82
+
canvas.add_or_replace_layer(claps);
83
83
+
Ok(())
84
84
+
})
85
85
+
.on_note(
86
86
+
"rimshot, glitchy percs, hitting percs, glitchy percs",
87
87
+
&|canvas, ctx| {
88
88
+
let mut foley = canvas.random_layer_within(
89
89
+
&mut ctx.extra.rng,
90
90
+
"percs",
91
91
+
&ctx.extra.bass_pattern_at.translated(2, 0),
92
92
+
);
93
93
+
foley.paint_all_objects(Fill::Translucent(Color::Red, 0.5));
94
94
+
canvas.add_or_replace_layer(foley);
95
95
+
Ok(())
96
96
+
},
97
97
+
)
98
98
+
.on_note("qanda", &|canvas, ctx| {
99
99
+
let canvas_line_width = canvas.object_sizes.default_line_width;
100
100
+
let mut qanda = canvas.random_curves_within(
101
101
+
&mut ctx.extra.rng,
102
102
+
"qanda",
103
103
+
&ctx.extra.bass_pattern_at.translated(-1, -1).enlarged(1, 1),
104
104
+
3..=5,
105
105
+
);
106
106
+
qanda.paint_all_objects(Fill::Solid(Color::Orange));
107
107
+
qanda.object_sizes.default_line_width =
108
108
+
canvas_line_width * 4.0 * ctx.stem("qanda").velocity_relative();
109
109
+
110
110
+
canvas.add_or_replace_layer(qanda);
111
111
+
Ok(())
112
112
+
})
113
113
+
.on_note("brokenup", &|canvas, ctx| {
114
114
+
let canvas_line_width = canvas.object_sizes.default_line_width;
115
115
+
let mut brokenup = canvas.random_curves_within(
116
116
+
&mut ctx.extra.rng,
117
117
+
"brokenup",
118
118
+
&ctx.extra.bass_pattern_at.translated(0, -2),
119
119
+
3..=5,
120
120
+
);
121
121
+
brokenup.paint_all_objects(Fill::Solid(Color::Yellow));
122
122
+
brokenup.object_sizes.default_line_width = canvas_line_width
123
123
+
* 4.0
124
124
+
* ctx.stem("brokenup").velocity_relative();
125
125
+
126
126
+
canvas.add_or_replace_layer(brokenup);
127
127
+
Ok(())
128
128
+
})
129
129
+
.on_note("goup", &|canvas, ctx| {
130
130
+
let canvas_line_width = canvas.object_sizes.default_line_width;
131
131
+
let mut goup = canvas.random_curves_within(
132
132
+
&mut ctx.extra.rng,
133
133
+
"goup",
134
134
+
&ctx.extra.bass_pattern_at.translated(0, 2),
135
135
+
3..=5,
136
136
+
);
137
137
+
goup.paint_all_objects(Fill::Solid(Color::Green));
138
138
+
goup.object_sizes.default_line_width =
139
139
+
canvas_line_width * 4.0 * ctx.stem("goup").velocity_relative();
140
140
+
141
141
+
canvas.add_or_replace_layer(goup);
142
142
+
Ok(())
143
143
+
})
144
144
+
.on_note("ch", &|canvas, ctx| {
145
145
+
let world = canvas.world_region.clone();
146
146
+
147
147
+
// keep only the last 2 dots
148
148
+
let dots_to_keep = canvas
149
149
+
.layer("ch")
150
150
+
.objects
151
151
+
.iter()
152
152
+
.sorted_by_key(|(name, _)| name.parse::<usize>().unwrap())
153
153
+
.rev()
154
154
+
.take(2)
155
155
+
.map(|(name, _)| name.clone())
156
156
+
.collect::<Vec<_>>();
157
157
+
158
158
+
let layer = canvas.layer("ch");
159
159
+
layer.object_sizes.empty_shape_stroke_width = 2.0;
160
160
+
layer.objects.retain(|name, _| dots_to_keep.contains(name));
161
161
+
162
162
+
let object_name = format!("{}", ctx.ms);
163
163
+
layer.set(
164
164
+
&object_name,
165
165
+
Object::Dot(
166
166
+
world.resized(-1, -1).random_point(&mut ctx.extra.rng),
167
167
+
)
168
168
+
.colored(Color::Cyan),
169
169
+
);
170
170
+
171
171
+
canvas.put_layer_on_top("ch");
172
172
+
Ok(())
173
173
+
})
174
174
+
}
···
16
16
/// Creates an angle given an amount, and what a full turn is equal to
17
17
/// ```
18
18
/// use shapemaker::geometry::Angle;
19
19
-
///
19
19
+
///
20
20
/// assert_eq!(Angle::from_ratio(0.5, 1.0).degrees() as usize, 180);
21
21
/// assert_eq!(Angle::from_radians(std::f32::consts::TAU).degrees() as usize, 360);
22
22
/// ```
···
40
40
pub use rendering::{
41
41
CSSRenderable, SVGAttributesRenderable, SVGRenderable, fonts,
42
42
};
43
43
+
pub use synchronization::audio::MusicalDurationUnit::*;
43
44
pub use video::{
44
45
Animation, AttachHooks, Scene, Timestamp, Video, animation, context,
45
46
};
46
46
-
pub use synchronization::audio::MusicalDurationUnit::*;
47
47
48
48
trait Toggleable {
49
49
fn toggle(&mut self);