on master help sign in
Merge branch 'sierpinski'
537d524Nick Fitzgerald
Cargo.lock+17−5
@@ -1,5 +1,3 @@
1−# This file is automatically @generated by Cargo.
2−# It is not intended for manual editing.
3[[package]]
1[[package]]
4name = "aho-corasick"
2name = "aho-corasick"
5version = "0.6.10"
3version = "0.6.10"
@@ -41,7 +39,7 @@ name = "backtrace-sys"
41version = "0.1.28"
39version = "0.1.28"
42source = "registry+https://github.com/rust-lang/crates.io-index"
40source = "registry+https://github.com/rust-lang/crates.io-index"
43dependencies = [
41dependencies = [
44− "cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
42+ "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
45 "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
43 "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
46]
44]
47
45
@@ -57,7 +55,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
57
55
58[[package]]
56[[package]]
59name = "cc"
57name = "cc"
60−version = "1.0.30"
58+version = "1.0.31"
61source = "registry+https://github.com/rust-lang/crates.io-index"
59source = "registry+https://github.com/rust-lang/crates.io-index"
62
60
63[[package]]
61[[package]]
@@ -191,6 +189,20 @@ dependencies = [
191 "web-sys 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
189 "web-sys 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
192]
190]
193
191
192+[[package]]
193+name = "dodrio-sierpinski"
194+version = "0.1.0"
195+dependencies = [
196+ "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
197+ "dodrio 0.1.0",
198+ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
199+ "js-sys 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
200+ "wasm-bindgen 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
201+ "wasm-bindgen-futures 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
202+ "wasm-bindgen-test 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
203+ "web-sys 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
204+]
205+
194[[package]]
206[[package]]
195name = "dodrio-todomvc"
207name = "dodrio-todomvc"
196version = "0.1.0"
208version = "0.1.0"
@@ -651,7 +663,7 @@ dependencies = [
651"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
663"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
652"checksum bumpalo 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "20bd7761c869bd69b5bd9dbbb1bd84de2f3970b764172efc41e67a06b508c56e"
664"checksum bumpalo 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "20bd7761c869bd69b5bd9dbbb1bd84de2f3970b764172efc41e67a06b508c56e"
653"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
665"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
654−"checksum cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)" = "d01c69d08ff207f231f07196e30f84c70f1c815b04f980f8b7b01ff01f05eb92"
666+"checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d"
655"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
667"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
656"checksum console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
668"checksum console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
657"checksum console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e7871d2947441b0fdd8e2bd1ce2a2f75304f896582c0d572162d48290683c48"
669"checksum console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e7871d2947441b0fdd8e2bd1ce2a2f75304f896582c0d572162d48290683c48"
Cargo.toml+1
@@ -64,5 +64,6 @@ members = [
64 "./examples/input-form",
64 "./examples/input-form",
65 "./examples/js-component",
65 "./examples/js-component",
66 "./examples/moire",
66 "./examples/moire",
67+ "./examples/sierpinski-triangle",
67 "./examples/todomvc",
68 "./examples/todomvc",
68]
69]
examples/sierpinski-triangle/Cargo.tomlnew file+29
@@ -0,0 +1,29 @@
1+[package]
2+name = "dodrio-sierpinski"
3+version = "0.1.0"
4+authors = ["Steven Seguin <steven.seguin@gmail.com>"]
5+edition = "2018"
6+
7+[lib]
8+crate-type = ["cdylib"]
9+
10+[dependencies]
11+dodrio = { path = "../.." }
12+wasm-bindgen = "0.2.39"
13+console_error_panic_hook = "0.1.6"
14+js-sys = "0.3.16"
15+wasm-bindgen-futures = "0.3.16"
16+futures = "0.1.25"
17+
18+[dependencies.web-sys]
19+version = "0.3.16"
20+features = [
21+ "Document",
22+ "HtmlElement",
23+ "Node",
24+ "Performance",
25+ "Window",
26+]
27+
28+[dev-dependencies]
29+wasm-bindgen-test = "0.2.39"
examples/sierpinski-triangle/README.mdnew file+24
@@ -0,0 +1,24 @@
1+# Sierpinski Triangle
2+
3+A Sierpinkski triangle that constantly shrinks and grows, and whose nodes have
4+a value that increments by one every second.
5+
6+Ported from the React Fiber example [here](https://github.com/claudiopro/react-fiber-vs-stack-demo).
7+
8+## Source
9+
10+See `src/lib.rs`.
11+
12+## Build
13+
14+```
15+wasm-pack build --target no-modules
16+```
17+
18+## Serve
19+
20+Use any HTTP server, for example:
21+
22+```
23+python -m http.server
24+```
examples/sierpinski-triangle/ferris.pngnew file

Binary file not shown.

examples/sierpinski-triangle/index.htmlnew file+69
@@ -0,0 +1,69 @@
1+<!DOCTYPE html>
2+<html>
3+
4+<head>
5+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
6+ <title>Sierpinski Triangle</title>
7+ <style>
8+ .container {
9+ position: absolute;
10+ transform-origin: 0 0;
11+ left: 50%;
12+ top: 50%;
13+ width: 10px;
14+ height: 10px;
15+ background: #eee;
16+ }
17+
18+ .dot {
19+ position: absolute;
20+ background: #61dafb;
21+ font: normal 15px sans-serif;
22+ text-align: center;
23+ cursor: pointer;
24+ }
25+
26+ .dot:hover {
27+ background: url("ferris.png") no-repeat center center;
28+ z-index: 999;
29+ }
30+
31+ code {
32+ position: relative;
33+ font-size: 150%;
34+ }
35+ </style>
36+</head>
37+
38+<body>
39+ <code>FPS: <output id="fps">...</output></code>
40+ <div id="scene"></div>
41+
42+ <script src="pkg/dodrio_sierpinski.js"></script>
43+ <script>
44+ wasm_bindgen("pkg/dodrio_sierpinski_bg.wasm");
45+ </script>
46+
47+ <script>
48+ let lastTime = 0;
49+ let frameCount = 0;
50+ const fps = document.getElementById('fps');
51+
52+ function updateFPS(time) {
53+ frameCount++;
54+ if (lastTime + 1000.0 <= time) {
55+ fps.textContent = frameCount;
56+ lastTime = time;
57+ frameCount = 0;
58+ }
59+ }
60+
61+ requestAnimationFrame(function loop(now) {
62+ updateFPS(now);
63+ requestAnimationFrame(loop);
64+ })
65+
66+ </script>
67+</body>
68+
69+</html>
examples/sierpinski-triangle/src/lib.rsnew file+173
@@ -0,0 +1,173 @@
1+use dodrio::bumpalo::{self, Bump};
2+use dodrio::{Node, Render, Vdom};
3+use std::cell::RefCell;
4+use std::rc::Rc;
5+use wasm_bindgen::prelude::*;
6+use wasm_bindgen::JsCast;
7+use web_sys::Window;
8+
9+// Triangle container defining target size.
10+struct Container {
11+ size: f64,
12+}
13+
14+impl Container {
15+ // Construct a new container.
16+ pub fn new() -> Container {
17+ Container { size: 25.0 }
18+ }
19+
20+ // Generate the container style to fluctuate triangle width.
21+ fn container_transform<'a, 'bump>(&'a self, bump: &'bump Bump, elapsed: f64) -> &'bump str
22+ where
23+ 'a: 'bump,
24+ {
25+ let t = elapsed % 10.0;
26+ let scale = 0.45 + (if t > 5.0 { 10.0 - t } else { t }) / 40.0;
27+ let transform = bumpalo::format!(
28+ in bump,
29+ "transform: scaleX({}) scaleY(0.7) translateZ(0.1px)",
30+ scale
31+ );
32+ transform.into_bump_str()
33+ }
34+
35+ // Generate the dot's position on the grid.
36+ fn dot_style<'a, 'bump>(&'a self, bump: &'bump Bump, x: f64, y: f64) -> &'bump str
37+ where
38+ 'a: 'bump,
39+ {
40+ let s = self.size * 1.3;
41+ let radius = s / 2.0;
42+ let styles = bumpalo::format!(
43+ in bump,
44+ r#"
45+ width: {}px;
46+ height: {}px;
47+ left: {}px;
48+ top: {}px;
49+ border-radius: {}px;
50+ line-height: {}px;
51+ "#,
52+ s, s, x, y, radius, s
53+ );
54+ styles.into_bump_str()
55+ }
56+
57+ // Create a dot node.
58+ fn dot<'a, 'bump>(&'a self, bump: &'bump Bump, x: f64, y: f64, content: u32) -> Node<'bump>
59+ where
60+ 'a: 'bump,
61+ {
62+ use dodrio::builder::{div, text};
63+
64+ div(bump)
65+ .attr("class", "dot")
66+ .attr("style", self.dot_style(bump, x, y))
67+ .child(text(
68+ bumpalo::format!(in bump, "{}", content).into_bump_str(),
69+ ))
70+ .finish()
71+ }
72+
73+ // Create a flattened vector of dot nodes (arranged in recursive triangles)
74+ fn triangle<'a, 'bump>(
75+ &'a self,
76+ bump: &'bump Bump,
77+ x: f64,
78+ y: f64,
79+ s: f64,
80+ content: u32,
81+ children: &mut bumpalo::collections::Vec<Node<'bump>>,
82+ ) where
83+ 'a: 'bump,
84+ {
85+ if s <= self.size {
86+ children.push(self.dot(bump, x, y, content));
87+ return;
88+ }
89+
90+ let s = s / 2.0;
91+
92+ // Top of triangle
93+ self.triangle(bump, x, y - (s / 2.0), s, content, children);
94+ // Bottom-left of triangle
95+ self.triangle(bump, x - s, y + (s / 2.0), s, content, children);
96+ // Bottom-right of triangle
97+ self.triangle(bump, x + s, y + (s / 2.0), s, content, children);
98+ }
99+}
100+
101+impl Render for Container {
102+ fn render<'a, 'bump>(&'a self, bump: &'bump Bump) -> Node<'bump>
103+ where
104+ 'a: 'bump,
105+ {
106+ use dodrio::builder::div;
107+
108+ let elapsed = web_sys::window()
109+ .unwrap_throw()
110+ .performance()
111+ .unwrap_throw()
112+ .now()
113+ / 1000.0;
114+
115+ let modulus = elapsed as u32 % 10;
116+
117+ let mut children = bumpalo::collections::Vec::new_in(bump);
118+ self.triangle(bump, 0.0, 0.0, 1000.0, modulus, &mut children);
119+
120+ div(bump)
121+ .attr("class", "container")
122+ .attr("style", self.container_transform(bump, elapsed))
123+ .children(children)
124+ .finish()
125+ }
126+}
127+
128+// Kick off a loop that keeps re-rendering on every animation frame.
129+fn animate(window: Window, vdom: Vdom) {
130+ let rc: Rc<RefCell<Option<Closure<FnMut()>>>> = Rc::new(RefCell::new(None));
131+ let rc2 = rc.clone();
132+ let window2 = window.clone();
133+ let weak = vdom.weak();
134+ let f = Closure::wrap(Box::new(move || {
135+ weak.schedule_render();
136+ window
137+ .request_animation_frame(
138+ rc.borrow()
139+ .as_ref()
140+ .unwrap_throw()
141+ .as_ref()
142+ .unchecked_ref::<js_sys::Function>(),
143+ )
144+ .unwrap_throw();
145+ }) as Box<FnMut()>);
146+ window2
147+ .request_animation_frame(f.as_ref().unchecked_ref::<js_sys::Function>())
148+ .unwrap_throw();
149+ *rc2.borrow_mut() = Some(f);
150+
151+ // Run the virtual DOM and its listeners forever.
152+ vdom.forget();
153+}
154+
155+#[wasm_bindgen(start)]
156+pub fn run() {
157+ // Set up the panic hook
158+ console_error_panic_hook::set_once();
159+
160+ // Get the scene element to render within
161+ let window = web_sys::window().unwrap();
162+ let document = window.document().unwrap();
163+ let scene = document.get_element_by_id("scene").unwrap();
164+
165+ // Construct a new Container component.
166+ let container = Container::new();
167+
168+ // Mount our container component to the scene div.
169+ let vdom = Vdom::new(&scene, container);
170+
171+ // Kick off animation loop
172+ animate(window, vdom);
173+}