···
5
5
path::PathBuf,
6
6
};
7
7
8
8
-
use itertools::Itertools;
9
8
use serde::Deserialize;
9
9
+
use wasm_bindgen::prelude::*;
10
10
11
11
+
#[wasm_bindgen]
11
12
#[derive(Debug, Clone, Copy, PartialEq)]
12
13
pub enum Color {
13
14
Black,
···
47
48
"gray" => Color::Gray,
48
49
_ => panic!("Invalid color: {}", s),
49
50
}
51
51
+
}
52
52
+
}
53
53
+
54
54
+
impl Color {
55
55
+
pub fn to_string(self, mapping: &ColorMapping) -> String {
56
56
+
match self {
57
57
+
Color::Black => mapping.black.to_string(),
58
58
+
Color::White => mapping.white.to_string(),
59
59
+
Color::Red => mapping.red.to_string(),
60
60
+
Color::Green => mapping.green.to_string(),
61
61
+
Color::Blue => mapping.blue.to_string(),
62
62
+
Color::Yellow => mapping.yellow.to_string(),
63
63
+
Color::Orange => mapping.orange.to_string(),
64
64
+
Color::Purple => mapping.purple.to_string(),
65
65
+
Color::Brown => mapping.brown.to_string(),
66
66
+
Color::Cyan => mapping.cyan.to_string(),
67
67
+
Color::Pink => mapping.pink.to_string(),
68
68
+
Color::Gray => mapping.gray.to_string(),
69
69
+
}
70
70
+
}
71
71
+
72
72
+
pub fn name(&self) -> String {
73
73
+
match self {
74
74
+
Color::Black => "black",
75
75
+
Color::White => "white",
76
76
+
Color::Red => "red",
77
77
+
Color::Green => "green",
78
78
+
Color::Blue => "blue",
79
79
+
Color::Yellow => "yellow",
80
80
+
Color::Orange => "orange",
81
81
+
Color::Purple => "purple",
82
82
+
Color::Brown => "brown",
83
83
+
Color::Cyan => "cyan",
84
84
+
Color::Pink => "pink",
85
85
+
Color::Gray => "gray",
86
86
+
}
87
87
+
.to_string()
50
88
}
51
89
}
52
90
···
203
241
}
204
242
}
205
243
}
206
206
-
207
207
-
impl Color {
208
208
-
pub fn to_string(self, mapping: &ColorMapping) -> String {
209
209
-
match self {
210
210
-
Color::Black => mapping.black.to_string(),
211
211
-
Color::White => mapping.white.to_string(),
212
212
-
Color::Red => mapping.red.to_string(),
213
213
-
Color::Green => mapping.green.to_string(),
214
214
-
Color::Blue => mapping.blue.to_string(),
215
215
-
Color::Yellow => mapping.yellow.to_string(),
216
216
-
Color::Orange => mapping.orange.to_string(),
217
217
-
Color::Purple => mapping.purple.to_string(),
218
218
-
Color::Brown => mapping.brown.to_string(),
219
219
-
Color::Cyan => mapping.cyan.to_string(),
220
220
-
Color::Pink => mapping.pink.to_string(),
221
221
-
Color::Gray => mapping.gray.to_string(),
222
222
-
}
223
223
-
}
224
224
-
}
···
5
5
6
6
#[wasm_bindgen(start)]
7
7
pub fn main() -> Result<(), JsValue> {
8
8
-
render_image(0.0, "black")?;
8
8
+
render_image(0.0, Color::Black)?;
9
9
Ok(())
10
10
}
11
11
12
12
+
// Can't bind Color.name directly, see https://github.com/rustwasm/wasm-bindgen/issues/1715
12
13
#[wasm_bindgen]
13
13
-
pub fn render_image(opacity: f32, color: &str) -> Result<(), JsValue> {
14
14
+
pub fn color_name(c: Color) -> String {
15
15
+
c.name()
16
16
+
}
17
17
+
18
18
+
#[wasm_bindgen]
19
19
+
pub fn render_image(opacity: f32, color: Color) -> Result<(), JsValue> {
14
20
let mut canvas = Canvas::default_settings();
15
21
canvas.colormap = ColorMapping {
16
22
black: "#ffffff".into(),
···
29
35
30
36
canvas.set_grid_size(4, 4);
31
37
32
32
-
let mut layer = canvas.random_layer(&color);
38
38
+
let mut layer = canvas.random_layer(&color.name());
33
39
layer.paint_all_objects(Fill::Translucent(color.into(), opacity));
34
40
canvas.add_or_replace_layer(layer);
35
41
···
39
45
40
46
let output = document.create_element("div")?;
41
47
output.set_class_name("frame");
42
42
-
output.set_attribute("data-color", color)?;
48
48
+
output.set_attribute("data-color", &color.name())?;
43
49
output.set_inner_html(&canvas.render(&vec!["*"], false));
44
50
body.append_child(&output)?;
45
51
Ok(())
···
7
7
</head>
8
8
<body>
9
9
<script type="module">
10
10
-
import init, { render_image } from "./shapemaker.js"
10
10
+
import init, { render_image, Color, color_name } from "./shapemaker.js"
11
11
async function run() {
12
12
await init()
13
13
-
window.render_image = (vel, col) => {
13
13
+
window.renderImage = (vel, col) => {
14
14
console.log([...arguments])
15
15
-
document.querySelector(`.frame[data-color=${col}]`)?.remove()
15
15
+
document.querySelector(`.frame[data-color=${color_name(col)}]`)?.remove()
16
16
render_image(vel, col)
17
17
}
18
18
}
···
22
22
23
23
window.addEventListener("keypress", (e) => {
24
24
if (e.key === " ") {
25
25
-
window.render_image(1, "white")
25
25
+
window.renderImage(1, Color.White)
26
26
}
27
27
})
28
28
···
46
46
const [pitch, velocity] = args
47
47
if (velocity === 0) return
48
48
const colors = [
49
49
-
"blue",
50
50
-
"purple",
51
51
-
"pink",
52
52
-
"red",
53
53
-
"orange",
54
54
-
"yellow",
55
55
-
"green",
56
56
-
"cyan",
57
57
-
"white",
49
49
+
Color.Blue,
50
50
+
Color.Purple,
51
51
+
Color.Pink,
52
52
+
Color.Red,
53
53
+
Color.Orange,
54
54
+
Color.Yellow,
55
55
+
Color.Green,
56
56
+
Color.Cyan,
57
57
+
Color.White,
58
58
]
59
59
// get color uniformly in this range from 28 (lowest pitch) to 103 (highest pitch)
60
60
61
61
const color =
62
62
colors[Math.floor(((pitch - 28) / (103 - 28)) * colors.length)]
63
63
console.log(pitch, color)
64
64
-
window.render_image(velocity / 128, color ?? "white")
64
64
+
window.renderImage(velocity / 128, color ?? "white")
65
65
}
66
66
})
67
67
})