src
geometry
graphics
video
wasm
···
2565
2565
]
2566
2566
2567
2567
[[package]]
2568
2568
+
name = "serde-wasm-bindgen"
2569
2569
+
version = "0.6.5"
2570
2570
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2571
2571
+
checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b"
2572
2572
+
dependencies = [
2573
2573
+
"js-sys",
2574
2574
+
"serde",
2575
2575
+
"wasm-bindgen",
2576
2576
+
]
2577
2577
+
2578
2578
+
[[package]]
2568
2579
name = "serde_cbor"
2569
2580
version = "0.11.2"
2570
2581
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2713
2724
"rust-analyzer",
2714
2725
"serde",
2715
2726
"serde-aux",
2727
2727
+
"serde-wasm-bindgen",
2716
2728
"serde_cbor",
2717
2729
"serde_json",
2718
2730
"slug",
···
33
33
"dep:ws",
34
34
"dep:tungstenite",
35
35
]
36
36
-
web = ["dep:wasm-bindgen", "dep:web-sys"]
36
36
+
web = ["dep:wasm-bindgen", "dep:serde-wasm-bindgen", "dep:web-sys"]
37
37
video = [
38
38
"dep:env_logger",
39
39
"dep:vgv",
···
42
42
"dep:easing-function",
43
43
]
44
44
video-server = ["dep:axum"]
45
45
+
serde-wasm-bindgen = ["dep:serde-wasm-bindgen"]
45
46
46
47
[dependencies]
47
48
nih_plug = { git = "https://github.com/robbert-vdh/nih-plug.git", features = [
···
95
96
easing-function = { version = "0.1.1", optional = true }
96
97
quick-xml = "0.38.3"
97
98
num = "0.4.3"
99
99
+
serde-wasm-bindgen = { version = "0.6.5", optional = true }
98
100
99
101
100
102
[dev-dependencies]
···
1
1
use num::FromPrimitive;
2
2
-
3
3
-
#[cfg(feature = "web")]
4
4
-
use wasm_bindgen::prelude::*;
2
2
+
use serde::{Deserialize, Serialize};
5
3
6
4
use crate::{
7
5
Point::{Center, Corner},
···
10
8
11
9
use super::Angle;
12
10
13
13
-
#[cfg_attr(feature = "web", wasm_bindgen)]
14
14
-
#[derive(Debug, Clone, Copy, PartialEq)]
11
11
+
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
12
12
+
#[cfg_attr(feature = "web", serde(tag = "type", content = "data"))]
15
13
pub enum Point {
16
14
Corner(usize, usize),
17
15
Center(usize, usize),
···
1
1
+
use itertools::Itertools;
2
2
+
1
3
use crate::{Fill, Filter, Object, ObjectSizes, Point, Region, Toggleable};
2
4
use std::{collections::HashMap, fmt::Display};
3
5
···
38
40
39
41
pub fn safe_object(&mut self, name: &str) -> Option<&mut Object> {
40
42
self.objects.get_mut(name)
43
43
+
}
44
44
+
45
45
+
// Useful to be able to guarantee a stable order when rendering.
46
46
+
pub fn objects_sorted(&self) -> impl Iterator<Item = (&String, &Object)> {
47
47
+
self.objects
48
48
+
.iter()
49
49
+
.sorted_by_cached_key(|&(id, _)| id.clone())
50
50
+
}
51
51
+
52
52
+
// Useful to be able to guarantee a stable order when rendering.
53
53
+
pub fn objects_sorted_mut(
54
54
+
&mut self,
55
55
+
) -> impl Iterator<Item = (&String, &mut Object)> {
56
56
+
self.objects
57
57
+
.iter_mut()
58
58
+
.sorted_by_cached_key(|&(id, _)| id.clone())
41
59
}
42
60
43
61
pub fn objects_in(
···
159
159
}
160
160
}
161
161
162
162
-
//
163
163
-
// ```rs
164
164
-
// use shapemaker::{Line, Point::Corner};
165
165
-
// let line = |x1: usize, y1: usize, x2: usize, y2: usize| Line(Corner(x1, y1), Corner(x2, y2), 1.0);
166
166
-
// assert!(line(1, 1, 4, 4).intersects_with(line(1, 4, 4, 1)));
167
167
-
// assert!(line(7, 6, 9, 7).intersects_with(line(7, 7, 9, 4)));
168
168
-
// ```
162
162
+
/// Check if this line intersects with another line.
163
163
+
/// Panics if either shape is not a line.
164
164
+
///
165
165
+
/// ```
166
166
+
/// use shapemaker::{Line, Point::Corner};
167
167
+
/// let line = |x1: u32, y1: u32, x2: u32, y2: u32| Line(Center(x1, y1), Center(x2, y2), 1.0);
168
168
+
/// assert!(line(1, 1, 4, 4).intersects_with(line(1, 4, 4, 1)));
169
169
+
/// assert!(line(7, 6, 9, 7).intersects_with(line(7, 7, 9, 4)));
170
170
+
/// assert!(line(4, 4, 6, 3).intersects_with(line(5, 2, 6, 5)));
171
171
+
/// ```
169
172
pub fn intersects_with(&self, line: Shape) -> bool {
170
173
match (self, &line) {
171
174
(&Line(s1, e1, _), &Line(s2, e2, _)) => {
···
42
42
update: Box::new(f),
43
43
}
44
44
}
45
45
-
46
46
-
// /// Example:
47
47
-
// /// ```
48
48
-
// /// use shapemaker::*;
49
49
-
// /// animation.at(50.0, Box::new(|canvas, _| canvas.root().set_background(Color::Black)));
50
50
-
// /// ```
51
51
-
// pub fn at(&mut self, percent: f32, action: Box<RenderFunction<C>>) {
52
52
-
// self.keyframes.push(Keyframe {
53
53
-
// at: percent / 100.0,
54
54
-
// action,
55
55
-
// });
56
56
-
// }
57
45
}
58
46
59
47
impl From<(String, Box<AnimationUpdateFunction>)> for Animation {
···
1
1
use super::canvas;
2
2
use crate::{
3
3
-
Color, Fill, Filter, Layer, Object, Point,
3
3
+
Color, Fill, Filter, Layer, Object, Point, Shape,
4
4
wasm::{RNG, append_new_div_inside, render_canvas, replace_content_with},
5
5
};
6
6
use wasm_bindgen::prelude::wasm_bindgen;
···
61
61
) {
62
62
canvas()
63
63
.layer_unchecked(name)
64
64
-
.set(name, Object::Line(start, end, thickness).colored(color))
64
64
+
.set(name, Shape::Line(start, end, thickness).colored(color))
65
65
}
66
66
pub fn new_curve_outward(
67
67
&self,
···
73
73
) {
74
74
canvas().layer_unchecked(name).set(
75
75
name,
76
76
-
Object::CurveOutward(start, end, thickness).colored(color),
76
76
+
Shape::CurveOutward(start, end, thickness).colored(color),
77
77
)
78
78
}
79
79
pub fn new_curve_inward(
···
86
86
) {
87
87
canvas().layer_unchecked(name).set(
88
88
name,
89
89
-
Object::CurveInward(start, end, thickness).colored(color),
89
89
+
Shape::CurveInward(start, end, thickness).colored(color),
90
90
)
91
91
}
92
92
pub fn new_small_circle(&self, name: &str, center: Point, color: Color) {
93
93
canvas()
94
94
.layer_unchecked(name)
95
95
-
.set(name, Object::SmallCircle(center).colored(color))
95
95
+
.set(name, Shape::SmallCircle(center).colored(color))
96
96
}
97
97
pub fn new_dot(&self, name: &str, center: Point, color: Color) {
98
98
canvas()
99
99
.layer_unchecked(name)
100
100
-
.set(name, Object::Dot(center).colored(color))
100
100
+
.set(name, Shape::Dot(center).colored(color))
101
101
}
102
102
pub fn new_big_circle(&self, name: &str, center: Point, color: Color) {
103
103
canvas()
104
104
.layer_unchecked(name)
105
105
-
.set(name, Object::BigCircle(center).colored(color))
105
105
+
.set(name, Shape::BigCircle(center).colored(color))
106
106
}
107
107
pub fn new_text(
108
108
&self,
···
114
114
) {
115
115
canvas()
116
116
.layer_unchecked(name)
117
117
-
.set(name, Object::Text(anchor, text, font_size).colored(color))
117
117
+
.set(name, Shape::Text(anchor, text, font_size).colored(color))
118
118
}
119
119
pub fn new_rectangle(
120
120
&self,
···
125
125
) {
126
126
canvas()
127
127
.layer_unchecked(name)
128
128
-
.set(name, Object::Rectangle(topleft, bottomright).colored(color))
128
128
+
.set(name, Shape::Rectangle(topleft, bottomright).colored(color))
129
129
}
130
130
}
···
1
1
pub mod layer;
2
2
pub mod transform;
3
3
pub mod web;
4
4
+
pub mod point;
4
5
5
6
pub use layer::*;
6
7
pub use transform::*;
7
8
pub use web::*;
9
9
+
pub use point::*;
···
1
1
+
use crate::Point;
2
2
+
use serde_wasm_bindgen;
3
3
+
use wasm_bindgen::{JsValue, convert::FromWasmAbi, convert::IntoWasmAbi};
4
4
+
5
5
+
impl From<Point> for JsValue {
6
6
+
fn from(val: Point) -> Self {
7
7
+
serde_wasm_bindgen::to_value(&val).unwrap()
8
8
+
}
9
9
+
}
10
10
+
11
11
+
impl wasm_bindgen::describe::WasmDescribe for Point {
12
12
+
fn describe() {
13
13
+
JsValue::describe()
14
14
+
}
15
15
+
}
16
16
+
17
17
+
impl wasm_bindgen::convert::IntoWasmAbi for Point {
18
18
+
type Abi = <JsValue as IntoWasmAbi>::Abi;
19
19
+
20
20
+
fn into_abi(self) -> Self::Abi {
21
21
+
serde_wasm_bindgen::to_value(&self).unwrap().into_abi()
22
22
+
}
23
23
+
}
24
24
+
25
25
+
impl wasm_bindgen::convert::FromWasmAbi for Point {
26
26
+
type Abi = <JsValue as FromWasmAbi>::Abi;
27
27
+
28
28
+
unsafe fn from_abi(js: Self::Abi) -> Self {
29
29
+
serde_wasm_bindgen::from_value(unsafe { JsValue::from_abi(js) }).unwrap()
30
30
+
}
31
31
+
}