SOURCE / PINNED RELEASE
Made of little things.
Sketch Loop
- Release
- 14966bba4a2a…
- Author-recorded commit
- e68361295d81…
- License
- LICENSE
- Author’s source reference
- nostr://npub1n8ga89w8h6tvwamxusfyzexw8gjy84yxu9rxgnmk955cxtml4ujswzxydd/wss%3A%2F%2Fgit.napplet.soy%2F/n-929bc2a88cb
Archive hash verified: 5e0385e3c08f944f…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Paste a 2D creative-code sketch, explore it live, and make a timed GIF." />
<title>Sketch Loop</title>
</head>
<body>
<div id="app" data-view="preview">
<nav class="toolbar" aria-label="Sketch controls">
<div class="view-tabs" aria-label="Workspace view">
<button data-view="editor" title="Edit sketch" aria-label="Edit sketch"><span aria-hidden="true">{ }</span><span class="label">Code</span></button>
<button data-view="preview" title="Live preview" aria-label="Live preview" aria-pressed="true"><span aria-hidden="true">◉</span><span class="label">Preview</span></button>
<button data-view="export" title="GIF export" aria-label="GIF export"><span aria-hidden="true">▤</span><span class="label">GIF</span></button>
</div>
<div class="toolbar-actions">
<button id="run" class="primary" title="Run edited sketch" aria-label="Run edited sketch"><span aria-hidden="true">▶</span><span class="label">Run</span></button>
<button id="pause" title="Pause preview" aria-label="Pause preview">Ⅱ</button>
<button id="restart" title="Restart at frame 1" aria-label="Restart at frame 1">↺</button>
<button id="help-toggle" title="Help and supported APIs" aria-label="Help and supported APIs" aria-expanded="false">?</button>
</div>
</nav>
<main class="workspace">
<section class="editor-pane" aria-label="Sketch editor">
<div class="pane-bar">
<label class="sr-only" for="example">Example sketch</label>
<select id="example"><option value="0">BusyMozaic</option><option value="1">Orbit study</option><option value="2">Ribbon field</option><option value="custom" hidden>Custom sketch</option></select>
<span class="badge">2D</span>
<button id="save-draft" title="Save code and export settings">Save draft</button>
</div>
<div class="code-wrap"><div id="line-numbers" aria-hidden="true"></div><textarea id="code" aria-label="Sketch source code" spellcheck="false" autocapitalize="off" autocomplete="off" autocorrect="off" wrap="off" maxlength="24000"></textarea></div>
<div class="editor-meta"><span id="edit-state">Ready to edit</span><span id="code-count"></span></div>
</section>
<section class="preview-pane" aria-label="Artwork preview">
<div class="pane-bar"><span class="live-dot" id="live-dot"></span><span id="play-state">Live preview</span><span class="spacer"></span><span id="dimensions" class="mono">450 × 300</span></div>
<div id="stage" class="stage"><div id="canvas-slot"></div><div id="frame-label" class="frame-label mono">FRAME 00000</div></div>
<div class="preview-meta"><span id="credit"></span><span id="fps-label" class="mono">60 fps</span></div>
</section>
<section class="export-pane" aria-label="GIF export settings">
<div class="export-top"><span class="section-label">Make a GIF</span><span class="export-description">Your code, frame by frame.</span><button id="settings" title="Open export defaults" aria-label="Open export defaults">⚙</button></div>
<div class="export-fields">
<label>Duration<div class="input-unit"><input id="duration" type="number" min="1" max="30" step="0.1" value="5" required /><span>sec</span></div></label>
<label>Start at<div class="input-unit"><input id="start" type="number" min="0" max="30" step="0.1" value="5" required /><span>sec</span></div></label>
<label>Frame rate<select id="fps"><option>10</option><option selected>15</option><option>20</option><option>25</option><option>30</option></select></label>
<label>Size<select id="scale"><option value="1">Original</option><option value="0.5">Half size</option></select></label>
</div>
<div class="export-actions"><label class="check-label"><input id="loop" type="checkbox" checked />Repeat GIF</label><span id="export-summary" class="mono"></span><button id="export" class="primary">Render GIF <span aria-hidden="true">↗</span></button><button id="cancel" hidden>Cancel</button></div>
<div id="progress-area" hidden><progress id="progress" max="1" value="0"></progress><span id="progress-label" class="mono"></span></div>
<div id="result" hidden><img id="gif-preview" alt="Rendered animated GIF" /><div class="result-info"><strong>GIF ready</strong><span id="result-details" class="mono"></span><button id="save-gif" class="primary">Save GIF ↓</button></div></div>
<p class="export-hint">Start at 0 for the first frame. Use a later start to let accumulating sketches fill in. Repeating does not guarantee a seamless loop.</p>
</section>
</main>
<output id="status" role="status" aria-live="polite">Loading sketch…</output>
<aside id="help" hidden aria-label="Sketch help">
<div class="pane-bar"><strong>Sketch guide</strong><button id="close-help" aria-label="Close help">×</button></div>
<div class="help-content">
<p>Paste a self-contained 2D p5-style sketch, then press <strong>Run</strong>. The editor accepts <code>draw = _ => { … }</code> and <code>function setup() / draw()</code>. Code runs only when you press Run; edits are used by the next GIF export.</p>
<p><strong>Drawing</strong><br>createCanvas, background, clear, fill, stroke, noFill, noStroke, strokeWeight, strokeCap, rect, square, ellipse, circle, line, point, triangle, beginShape, vertex, bezierVertex, endShape, text, textSize.</p>
<p><strong>Color & motion</strong><br>color, colorMode (RGB / HSB / HSL), translate, rotate, scale, push, pop, resetMatrix, rectMode, ellipseMode (CENTER / CORNER / RADIUS), angleMode, frameCount, frameRate, millis, noLoop, loop.</p>
<p><strong>Math</strong><br>sin, cos, tan, abs, floor, ceil, round, sqrt, pow, min, max, map, constrain, lerp, dist, random, randomSeed, noise, noiseSeed, PI, TWO_PI and Math. Noise is deterministic value noise.</p>
<p>This is a bounded 2D subset, not the full p5.js library. Assets, WebGL, DOM, imports, async code, classes, array methods and browser APIs are unavailable. Errors stop the sketch so you can edit it. Canvas size is limited to 1,024 × 1,024.</p>
<p>GIF export starts from fresh code with a fixed random seed. The sketch runs at 60 fps unless it sets frameRate(); export FPS samples that animation. Transparent pixels are exported on black.</p>
<p id="capabilities"></p><p>BusyMozaic example by Kurt Moerman (@KurtMoerman4), supplied with the project brief.</p>
</div>
</aside>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>