soundcraft/apps/soundcraft-web/index.html

42 lines
2.0 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>SoundCraft</title>
<link data-trunk rel="icon" type="image/png" href="../../assets/app-icon/hicolor/64x64/apps/ai.storyteller.soundcraft.png" />
<link data-trunk rel="rust" data-bin="soundcraft-web" data-wasm-opt="z" data-weak-refs />
<style>
html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; background: #1e1f22; }
#soundcraft_canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
#soundcraft_loading { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
color: #b8b8b8; font: 14px system-ui, sans-serif; pointer-events: none; }
</style>
</head>
<body>
<canvas id="soundcraft_canvas"></canvas>
<script>
// cpal (wasm) builds the output stream at startup, before any user gesture, so the
// WebAudio AudioContext stays 'suspended': no audio is heard and the transport clock
// (driven by the audio callback) never advances. Capture the AudioContext cpal creates
// and resume it on the first user gesture. Runs before the wasm module is instantiated.
(function () {
var Orig = window.AudioContext || window.webkitAudioContext;
if (!Orig) return;
var ctxs = [];
function Wrapped(opts) { var c = new Orig(opts); ctxs.push(c); return c; }
Wrapped.prototype = Orig.prototype;
window.AudioContext = Wrapped;
if (window.webkitAudioContext) window.webkitAudioContext = Wrapped;
function resumeAll() {
ctxs.forEach(function (c) { if (c.state === 'suspended') { c.resume().catch(function () {}); } });
}
['pointerdown', 'mousedown', 'touchstart', 'keydown'].forEach(function (ev) {
window.addEventListener(ev, resumeAll, { capture: true });
});
})();
</script>
<div id="soundcraft_loading">Loading SoundCraft&hellip;</div>
</body>
</html>