···
19
19
pub mod rendering;
20
20
pub mod synchronization;
21
21
pub mod ui;
22
22
-
pub mod video;
23
22
24
23
#[cfg(feature = "web")]
25
24
pub mod wasm;
···
37
36
CSSRenderable, SVGAttributesRenderable, SVGRenderable, fonts,
38
37
};
39
38
pub use synchronization::audio::MusicalDurationUnit::*;
39
39
+
40
40
+
#[cfg(feature = "video")]
41
41
+
pub mod video;
42
42
+
#[cfg(feature = "video")]
40
43
pub use video::{
41
44
Animation, AttachHooks, Scene, Timestamp, Video, animation, context,
42
45
};
···
1
1
-
use chrono::DateTime;
2
1
use itertools::Itertools;
3
2
use std::collections::HashMap;
4
4
-
use std::ops::Range;
5
3
use std::time::Duration;
6
6
-
7
7
-
use crate::Timestamp;
8
4
9
5
pub(crate) trait Pretty {
10
6
fn pretty(&self) -> String;
···
49
45
impl DivRem<u128> for u128 {
50
46
fn div_rem(&self, rhs: &u128) -> (u128, u128) {
51
47
(self / rhs, self % rhs)
52
52
-
}
53
53
-
}
54
54
-
55
55
-
impl Pretty for Timestamp {
56
56
-
fn pretty(&self) -> String {
57
57
-
format!(
58
58
-
"{}",
59
59
-
DateTime::from_timestamp_millis(self.ms() as i64)
60
60
-
.unwrap()
61
61
-
.format("%H:%M:%S%.3f")
62
62
-
)
63
63
-
}
64
64
-
}
65
65
-
66
66
-
impl Pretty for Range<Timestamp> {
67
67
-
fn pretty(&self) -> String {
68
68
-
format!("from {} to {}", self.start.pretty(), self.end.pretty())
69
48
}
70
49
}
71
50
···
5
5
pub mod scene;
6
6
pub mod video;
7
7
8
8
-
#[cfg(feature = "video")]
9
8
pub mod encoders;
10
10
-
#[cfg(feature = "video")]
11
9
pub mod encoding;
12
10
13
11
#[cfg(feature = "video-server")]
···
8
8
ui::{self, Log, Pretty},
9
9
video::hooks::{AttachHooks, CommandAction, Hook},
10
10
};
11
11
+
use chrono::DateTime;
11
12
use measure_time::debug_time;
12
13
use std::{
13
14
collections::HashMap, fmt::Formatter, ops::Range, path::PathBuf,
···
54
55
55
56
pub fn from_ms(ms: usize) -> Self {
56
57
Self(ms)
58
58
+
}
59
59
+
}
60
60
+
61
61
+
impl Pretty for Timestamp {
62
62
+
fn pretty(&self) -> String {
63
63
+
format!(
64
64
+
"{}",
65
65
+
DateTime::from_timestamp_millis(self.ms() as i64)
66
66
+
.unwrap()
67
67
+
.format("%H:%M:%S%.3f")
68
68
+
)
69
69
+
}
70
70
+
}
71
71
+
72
72
+
impl Pretty for Range<Timestamp> {
73
73
+
fn pretty(&self) -> String {
74
74
+
format!("from {} to {}", self.start.pretty(), self.end.pretty())
57
75
}
58
76
}
59
77
···
34
34
35
35
pub fn paint_all(&self, color: Color, opacity: Option<f32>, filter: Filter) {
36
36
canvas()
37
37
-
.layer(&self.name)
37
37
+
.layer_unchecked(&self.name)
38
38
.paint_all_objects(Fill::Translucent(color, opacity.unwrap_or(1.0)));
39
39
-
canvas().layer(&self.name).filter_all_objects(filter);
39
39
+
canvas()
40
40
+
.layer_unchecked(&self.name)
41
41
+
.filter_all_objects(filter);
40
42
}
41
43
42
44
pub fn random(name: &str) -> Self {
···
58
60
color: Color,
59
61
) {
60
62
canvas()
61
61
-
.layer(name)
63
63
+
.layer_unchecked(name)
62
64
.set(name, Object::Line(start, end, thickness).colored(color))
63
65
}
64
66
pub fn new_curve_outward(
···
69
71
thickness: f32,
70
72
color: Color,
71
73
) {
72
72
-
canvas().layer(name).set(
74
74
+
canvas().layer_unchecked(name).set(
73
75
name,
74
76
Object::CurveOutward(start, end, thickness).colored(color),
75
77
)
···
82
84
thickness: f32,
83
85
color: Color,
84
86
) {
85
85
-
canvas().layer(name).set(
87
87
+
canvas().layer_unchecked(name).set(
86
88
name,
87
89
Object::CurveInward(start, end, thickness).colored(color),
88
90
)
89
91
}
90
92
pub fn new_small_circle(&self, name: &str, center: Point, color: Color) {
91
93
canvas()
92
92
-
.layer(name)
94
94
+
.layer_unchecked(name)
93
95
.set(name, Object::SmallCircle(center).colored(color))
94
96
}
95
97
pub fn new_dot(&self, name: &str, center: Point, color: Color) {
96
98
canvas()
97
97
-
.layer(name)
99
99
+
.layer_unchecked(name)
98
100
.set(name, Object::Dot(center).colored(color))
99
101
}
100
102
pub fn new_big_circle(&self, name: &str, center: Point, color: Color) {
101
103
canvas()
102
102
-
.layer(name)
104
104
+
.layer_unchecked(name)
103
105
.set(name, Object::BigCircle(center).colored(color))
104
106
}
105
107
pub fn new_text(
···
111
113
color: Color,
112
114
) {
113
115
canvas()
114
114
-
.layer(name)
116
116
+
.layer_unchecked(name)
115
117
.set(name, Object::Text(anchor, text, font_size).colored(color))
116
118
}
117
119
pub fn new_rectangle(
···
122
124
color: Color,
123
125
) {
124
126
canvas()
125
125
-
.layer(name)
127
127
+
.layer_unchecked(name)
126
128
.set(name, Object::Rectangle(topleft, bottomright).colored(color))
127
129
}
128
130
}
···
156
156
157
157
#[wasm_bindgen]
158
158
pub fn get_layer(name: &str) -> Result<LayerWeb, JsValue> {
159
159
-
match canvas().layer_safe(name) {
160
160
-
Some(layer) => Ok(LayerWeb {
159
159
+
match canvas().layer(name) {
160
160
+
Ok(layer) => Ok(LayerWeb {
161
161
name: layer.name.clone(),
162
162
}),
163
163
-
None => Err(JsValue::from_str("Layer not found")),
163
163
+
Err(_) => Err(JsValue::from_str("Layer not found")),
164
164
}
165
165
}
166
166