gantz 0.2.0

An environment for creative systems.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="icon" href="data:,">

    <!-- trunk asset directives -->
    <link data-trunk rel="rust" href="../Cargo.toml" data-bin="gantz"
          data-cargo-profile-release="wasm_release"
          data-wasm-opt="z"
          data-wasm-opt-params="--enable-bulk-memory --enable-reference-types --enable-multivalue --enable-tail-call --enable-nontrapping-float-to-int"
          data-initializer="initializer.js" />
    <link data-trunk rel="copy-file" href="manifest.json" />
    <link data-trunk rel="copy-file" href="sw.js" />

    <!-- PWA stuff -->
    <link rel="manifest" href="manifest.json">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-title" content="PAW">

    <title>gantz</title>
    <style>
        body, html {
            margin: 0;
            padding: 0;
            width: 100vw;
            height: 100%;
            background-color: #1b1b1b;
        }
        canvas {
            display: block;
            touch-action: none;
        }
        canvas:focus {
            outline: none;
        }
        #loading {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            color: #f0f0f0;
            font-family: sans-serif;
            text-align: center;
        }
        #loading-title {
            font-size: 18px;
            letter-spacing: 0.5em;
            margin: 0 0 12px 0;
        }
        #loading-track {
            width: 100%;
            height: 2px;
            background: #333;
        }
        #loading-bar {
            width: 0%;
            height: 100%;
            background: #f0f0f0;
            transition: width 0.2s ease;
        }
    </style>
</head>
<body>
    <div id="loading">
        <p id="loading-title">g a n t z</p>
        <div id="loading-track"><div id="loading-bar"></div></div>
    </div>
    <script>
        document.body.addEventListener("contextmenu", (e) => {
            e.preventDefault();
            e.stopPropagation();
        });

        // Insert hack to make sound autoplay on Chrome as soon as the user interacts with the tab:
        // https://developers.google.com/web/updates/2018/11/web-audio-autoplay#moving-forward
        (function () {
            const audioContextList = [];
            const userInputEventNames = [
                "click", "contextmenu", "auxclick", "dblclick",
                "mousedown", "mouseup", "pointerup", "touchend",
                "keydown", "keyup",
            ];

            self.AudioContext = new Proxy(self.AudioContext, {
                construct(target, args) {
                    const result = new target(...args);
                    audioContextList.push(result);
                    return result;
                },
            });

            function resumeAllContexts(_event) {
                let count = 0;
                audioContextList.forEach((context) => {
                    if (context.state !== "running") {
                        context.resume();
                    } else {
                        count++;
                    }
                });

                if (count > 0 && count === audioContextList.length) {
                    userInputEventNames.forEach((eventName) => {
                        document.removeEventListener(eventName, resumeAllContexts);
                    });
                }
            }

            userInputEventNames.forEach((eventName) => {
                document.addEventListener(eventName, resumeAllContexts);
            });
        })();

        // Service Worker for the PWA
        if ('serviceWorker' in navigator) {
            window.addEventListener('load', () => {
                navigator.serviceWorker.register('sw.js')
                    .then(registration => {
                        console.log('ServiceWorker registered:', registration);
                    })
                    .catch(error => {
                        console.log('ServiceWorker registration failed:', error);
                    });
            });
        }
    </script>
</body>
</html>