Skip to content

Commit 227d925

Browse files
committed
Webcomponent to ease integration in HTML
1 parent 2e20ec1 commit 227d925

File tree

2 files changed

+54
-38
lines changed

2 files changed

+54
-38
lines changed

index.html

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,69 +13,58 @@ <h1>Olive.c Demos</h1>
1313
<div id="sec-triangle">
1414
<h2 id="demo-triangle"><a href="#demo-triangle">Triangle</a></h2>
1515
<p>Rainbow triangle together with a transparent circle. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/triangle.c">demos/triangle.c</a></p>
16-
<canvas id="app-triangle"></canvas>
16+
<olivec-canvas src="./wasm/triangle.wasm" />
1717
</div>
1818

1919
<div id="sec-dots3d">
2020
<h2 id="demo-dots3d"><a href="#demo-dots3d">Dots 3D</a></h2>
2121
<p>A bunch of 3D dots projected onto your 2D screen plus a text with a builtin monospaced font. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/dots3d.c">demos/dots3d.c</a></p>
22-
<canvas id="app-dots3d"></canvas>
22+
<olivec-canvas src="./wasm/dots3d.wasm" />
2323
</div>
2424

2525
<div id="sec-squish">
2626
<h2 id="demo-squish"><a href="#demo-squish">Squish</a></h2>
2727
<p>Resizing images on the fly. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/squish.c">demos/squish.c</a></p>
28-
<canvas id="app-squish"></canvas>
28+
<olivec-canvas src="./wasm/squish.wasm" />
2929
</div>
3030

3131
<div id="sec-triangle3d">
3232
<h2 id="demo-triangle3d"><a href="#demo-triangle3d">Triangle 3D</a></h2>
3333
<p>Rotating rainbow triangle in 3D. Unlike <a href="#demo-3d">3D dots above</a> this is a solid shape. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/triangle3d.c">demos/triangle3d.c</a></p>
34-
<canvas id="app-triangle3d"></canvas>
34+
<olivec-canvas src="./wasm/triangle3d.wasm" />
3535
</div>
3636

3737
<div id="sec-triangleTex">
3838
<h2 id="demo-triangleTex"><a href="#demo-triangleTex">Rotating 2D Textures</a></h2>
3939
<p>Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/triangleTex.c">demos/triangleTex.c</a></p>
40-
<canvas id="app-triangleTex"></canvas>
40+
<olivec-canvas src="./wasm/triangleTex.wasm" />
4141
</div>
4242

4343
<div id="sec-triangle3dTex">
4444
<h2 id="demo-triangle3dTex"><a href="#demo-triangle3dTex">Rotating 3D Textures</a></h2>
4545
<p>Textures by <a href="https://opengameart.org/content/handpainted-stone-texture">MELLE</a>. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/triangle3dTex.c">demos/triangle3dTex.c</a></p>
46-
<canvas id="app-triangle3dTex"></canvas>
46+
<olivec-canvas src="./wasm/triangle3dTex.wasm" />
4747
</div>
4848

4949
<div id="sec-cup3d">
5050
<h2 id="demo-cup3d"><a href="#demo-cup3d">Cup 3D</a></h2>
5151
<p>Design by <a href="https://github.com/rexim">rexim</a>. 3D model by <a href="https://github.com/kolumb">kolumb</a>. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/cup3d.c">demos/cup3d.c</a></p>
52-
<canvas id="app-cup3d"></canvas>
52+
<olivec-canvas src="./wasm/cup3d.wasm" />
5353
</div>
5454

5555
<div id="sec-teapot3d">
5656
<h2 id="demo-teapot3d"><a href="#demo-teapot3d">Utah Teapot</a></h2>
5757
<p>Famous <a href="https://en.wikipedia.org/wiki/Utah_teapot">Utah Teapot</a>. Model by <a href="https://graphics.stanford.edu/courses/cs148-10-summer/as3/code/as3/teapot.obj">Standford University</a>. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/teapot3d.c">demos/teapot3d.c</a></p>
5858
<p>(I have no idea why it runs with a reasonable FPS)</p>
59-
<canvas id="app-teapot3d"></canvas>
59+
<olivec-canvas src="./wasm/teapot3d.wasm" />
6060
</div>
6161

6262
<div id="sec-penger3d">
6363
<h2 id="demo-penger3d"><a href="#demo-penger3d">Penger</a></h2>
6464
<p><a href="https://penger.neocities.org/">Penger</a> - The Mascot of Tsoding Discord Community. The character design by <a href="https://github.com/LainLayer">LainLayer</a>. The model by <a href="https://github.com/Max-Kawula">Max-Kawula</a>. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/penger3d.c">demos/penger3d.c</a></p>
65-
<canvas id="app-penger3d"></canvas>
65+
<olivec-canvas src="./wasm/penger3d.wasm" />
6666
</div>
6767

6868
<script src="js/vc.js"></script>
69-
<script>
70-
startDemo("triangle", "./wasm/triangle.wasm");
71-
startDemo("dots3d", "./wasm/dots3d.wasm");
72-
startDemo("squish", "./wasm/squish.wasm");
73-
startDemo("triangle3d", "./wasm/triangle3d.wasm");
74-
startDemo("triangleTex", "./wasm/triangleTex.wasm");
75-
startDemo("triangle3dTex", "./wasm/triangle3dTex.wasm");
76-
startDemo("cup3d", "./wasm/cup3d.wasm");
77-
startDemo("teapot3d", "./wasm/teapot3d.wasm");
78-
startDemo("penger3d", "./wasm/penger3d.wasm");
79-
</script>
8069
</body>
8170
</html>

js/vc.js

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,11 @@ function readCanvasFromMemory(memory_buffer, canvas_ptr)
3939
};
4040
}
4141

42-
async function startDemo(elementId, wasmPath) {
43-
const app = document.getElementById(`app-${elementId}`);
44-
if (app === null) {
45-
console.error(`Could not find element app-${elementId}. Skipping demo ${wasmPath}...`);
46-
return;
47-
}
48-
const sec = document.getElementById(`sec-${elementId}`);
49-
if (sec === null) {
50-
console.error(`Could not find element sec-${elementId}. Skipping demo ${wasmPath}...`);
51-
return;
52-
}
53-
54-
let paused = true;
55-
sec.addEventListener("mouseenter", () => paused = false);
56-
sec.addEventListener("mouseleave", () => paused = true);
57-
42+
/**
43+
* @param {HTMLCanvasElement} app
44+
* @param {string} wasmPath
45+
*/
46+
async function startDemo(app, wasmPath) {
5847
const ctx = app.getContext("2d");
5948
const w = await WebAssembly.instantiateStreaming(fetch(wasmPath), {
6049
"env": make_environment(libm)
@@ -67,7 +56,7 @@ async function startDemo(elementId, wasmPath) {
6756
const buffer = w.instance.exports.memory.buffer;
6857
w.instance.exports.vc_render(heap_base, dt*0.001);
6958
const canvas = readCanvasFromMemory(buffer, heap_base);
70-
if (canvas.width != canvas.stride) {
59+
if (canvas.width !== canvas.stride) {
7160
// TODO: maybe we can preallocate a Uint8ClampedArray on JavaScript side and just copy the canvas data there to bring width and stride to the same value?
7261
console.error(`Canvas width (${canvas.width}) is not equal to its stride (${canvas.stride}). Unfortunately we can't easily support that in a browser because ImageData simply does not accept stride. Welcome to 2022.`);
7362
return;
@@ -87,8 +76,46 @@ async function startDemo(elementId, wasmPath) {
8776
function loop(timestamp) {
8877
const dt = timestamp - prev;
8978
prev = timestamp;
90-
if (!paused) render(dt);
79+
if (app.dataset['visible'] === 'true') render(dt);
9180
window.requestAnimationFrame(loop);
9281
}
9382
window.requestAnimationFrame(first);
9483
}
84+
85+
class OliveCanvas extends HTMLElement {
86+
constructor() {
87+
super();
88+
}
89+
90+
connectedCallback() {
91+
const wasmPath = this.getAttribute('src');
92+
if (!wasmPath) {
93+
console.error(`Should define a src attribute on olive-canvas`)
94+
return;
95+
}
96+
97+
const canvas = document.createElement("canvas");
98+
this.appendChild(canvas);
99+
100+
// Create an observer that monitors entering/exiting the viewport
101+
this.observer = new IntersectionObserver(
102+
([entry]) => {
103+
canvas.dataset['visible'] = String(entry.isIntersecting);
104+
},
105+
{
106+
root: null,
107+
rootMargin: '0px',
108+
threshold: 0,
109+
}
110+
);
111+
112+
this.observer.observe(canvas);
113+
startDemo(canvas, wasmPath);
114+
}
115+
116+
disconnectedCallback() {
117+
this.observer.disconnect();
118+
}
119+
}
120+
121+
customElements.define("olivec-canvas", OliveCanvas);

0 commit comments

Comments
 (0)