Add Go CDN and playground server
Build Core and Handles into in-memory CDN modules, add the marketing site and tutorial docs, and provide a SQLite-backed WebGPU playground with TypeScript tooling and profiling. Amp-Thread-ID: https://ampcode.com/threads/T-01a02485-5574-707c-bff4-5668d83bee8a Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#f7fbff" />
|
||||
<meta name="description" content="Write, run, profile, and share Yawn WebGPU scenes." />
|
||||
<title>Yawn Playground</title>
|
||||
<link rel="stylesheet" href="/assets/playground.css" />
|
||||
<script src="/assets/monaco/vs/loader.js"></script>
|
||||
<script type="module" src="/assets/playground.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<main class="playground-app">
|
||||
<header class="playground-header">
|
||||
<a class="playground-brand" href="/" aria-label="Yawn home">
|
||||
<span class="brand-mark" aria-hidden="true"><i></i><i></i><i></i></span><strong>Yawn</strong>
|
||||
</a>
|
||||
<div class="header-divider"></div>
|
||||
<div class="project-name">
|
||||
<input id="project-title" maxlength="80" value="Sky triangle" aria-label="Playground title" />
|
||||
<span id="dirty-indicator" title="Unsaved changes"></span>
|
||||
<span id="revision-label">Draft</span>
|
||||
</div>
|
||||
<nav class="playground-nav" aria-label="Playground links">
|
||||
<a href="/docs">Docs</a>
|
||||
<a href="https://git.heaust.org/heaust/yawn">Source</a>
|
||||
</nav>
|
||||
<button id="share-button" class="tool-button" type="button" hidden>
|
||||
<span aria-hidden="true">↗</span> Share
|
||||
</button>
|
||||
<button id="save-button" class="tool-button" type="button">
|
||||
<span aria-hidden="true">◇</span> Save
|
||||
</button>
|
||||
<button id="run-button" class="run-button" type="button">
|
||||
<span aria-hidden="true">▶</span> Run <kbd>Ctrl ↵</kbd>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<div class="playground-tools">
|
||||
<div class="tool-group">
|
||||
<button id="snippets-button" type="button"><span class="braces">{ }</span> Snippets</button>
|
||||
<button id="reset-button" type="button"><span aria-hidden="true">↶</span> Reset</button>
|
||||
<button id="format-button" type="button"><span aria-hidden="true">≡</span> Format</button>
|
||||
</div>
|
||||
<div class="tool-context">
|
||||
<span class="language-dot"></span>
|
||||
<span>TypeScript</span>
|
||||
<span class="context-divider"></span>
|
||||
<span id="type-status">Starting language service…</span>
|
||||
</div>
|
||||
<div class="tool-group tool-group-right">
|
||||
<button id="inspector-button" type="button" aria-pressed="true"><span aria-hidden="true">▤</span> Inspector</button>
|
||||
<button id="fullscreen-button" type="button" aria-label="Toggle fullscreen"><span aria-hidden="true">⛶</span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="workbench" id="workbench">
|
||||
<section class="editor-pane" aria-label="TypeScript editor">
|
||||
<div class="pane-tabs">
|
||||
<button class="pane-tab active" type="button"><span class="ts-icon">TS</span> scene.ts <i id="tab-dirty"></i></button>
|
||||
</div>
|
||||
<div id="editor" class="editor"><div class="editor-loading">Loading TypeScript editor…</div></div>
|
||||
<footer class="editor-status">
|
||||
<span id="cursor-status">Ln 1, Col 1</span>
|
||||
<span>Spaces: 2</span>
|
||||
<span>UTF-8</span>
|
||||
<span class="status-spacer"></span>
|
||||
<span id="editor-diagnostics"><i></i> No problems</span>
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<div class="resize-handle" id="resize-handle" role="separator" aria-orientation="vertical" aria-label="Resize editor and preview"></div>
|
||||
|
||||
<section class="stage-pane" aria-label="Yawn output">
|
||||
<div class="stage-toolbar">
|
||||
<div class="stage-tabs">
|
||||
<button type="button" class="active">Preview</button>
|
||||
</div>
|
||||
<div class="stage-meta">
|
||||
<span id="run-status"><i></i> Ready</span>
|
||||
<span class="stage-divider"></span>
|
||||
<span id="fps-status">0 FPS</span>
|
||||
<span class="stage-divider"></span>
|
||||
<span id="resolution-status">—</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="preview" id="preview">
|
||||
<canvas id="canvas" aria-label="Yawn WebGPU preview"></canvas>
|
||||
<div class="preview-message" id="preview-message">
|
||||
<span class="preview-message-icon">Y</span>
|
||||
<strong>Preparing your scene</strong>
|
||||
<small>The first run compiles the render graph.</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inspector" id="inspector">
|
||||
<div class="inspector-tabs" role="tablist">
|
||||
<button type="button" class="active" role="tab" aria-selected="true" data-panel="console">Console <span id="console-count">0</span></button>
|
||||
<button type="button" role="tab" aria-selected="false" data-panel="profile">GPU profiler</button>
|
||||
<button id="clear-console" class="clear-console" type="button">Clear</button>
|
||||
</div>
|
||||
<div class="console-panel inspector-panel active" id="console-panel" role="tabpanel">
|
||||
<div class="console-empty" id="console-empty"><span>›_</span> Output from <code>log()</code> appears here.</div>
|
||||
<ol id="console-lines"></ol>
|
||||
</div>
|
||||
<div class="profile-panel inspector-panel" id="profile-panel" role="tabpanel">
|
||||
<div class="profile-empty" id="profile-empty">
|
||||
<span class="pulse-icon">⌁</span>
|
||||
<div><strong>Waiting for GPU timestamps</strong><small>Run the scene to inspect its physical passes.</small></div>
|
||||
</div>
|
||||
<div class="profile-results" id="profile-results" hidden>
|
||||
<div class="profile-summary"><div><small>Total GPU time</small><strong id="profile-total">—</strong></div><div><small>Readback latency</small><strong id="profile-latency">—</strong></div><div><small>Adapter</small><strong id="profile-adapter">—</strong></div></div>
|
||||
<table><thead><tr><th>Physical pass</th><th>GPU time</th></tr></thead><tbody id="profile-passes"></tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<dialog id="snippets-dialog" class="snippets-dialog">
|
||||
<div class="dialog-heading">
|
||||
<div><span>Code library</span><h2>Snippets</h2><p>Insert a focused building block at your cursor.</p></div>
|
||||
<button type="button" data-close-dialog aria-label="Close snippets">×</button>
|
||||
</div>
|
||||
<div class="snippet-search"><span>⌕</span><input type="search" placeholder="Find a snippet" aria-label="Find a snippet" /></div>
|
||||
<div class="snippet-grid">
|
||||
<button type="button" data-snippet="camera"><span class="snippet-icon">◎</span><div><strong>Orbit camera</strong><small>Pointer orbit and wheel zoom</small><code>ArcRotateCamera</code></div><b>+</b></button>
|
||||
<button type="button" data-snippet="light"><span class="snippet-icon">☀</span><div><strong>Point light</strong><small>Warm, local illumination</small><code>PointLight</code></div><b>+</b></button>
|
||||
<button type="button" data-snippet="instances"><span class="snippet-icon">◇</span><div><strong>Mesh instances</strong><small>Clone shared geometry</small><code>mesh.clone()</code></div><b>+</b></button>
|
||||
<button type="button" data-snippet="rows"><span class="snippet-icon">≋</span><div><strong>Shared rows</strong><small>Add application-owned hot data</small><code>scene.ensureRows()</code></div><b>+</b></button>
|
||||
<button type="button" data-snippet="post"><span class="snippet-icon">✦</span><div><strong>Post processing</strong><small>Color grading and FXAA</small><code>batchGraphUpdates()</code></div><b>+</b></button>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<div class="toast" id="toast" role="status" aria-live="polite"></div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user