fruit-fly-simulation / index.html
Xenova's picture
Xenova HF Staff
Upload 227 files
cc38b25 verified
Raw History Blame Contribute Delete
13.7 kB
<!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="#10171d" />
<meta
name="description"
content="Paint fruit fly neurons and watch their activity drive an animated fly."
/>
<title>Neural Canvas</title>
<link
rel="preload"
href="%BASE_URL%fonts/InterVariable.woff2"
as="font"
type="font/woff2"
crossorigin
/>
</head>
<body>
<svg class="icon-definitions" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<defs>
<symbol id="i-paint" viewBox="0 0 24 24">
<path d="m14.622 17.897-10.68-2.913" />
<path
d="M18.376 2.622a1 1 0 1 1 3.002 3.002L17.36 9.643a.5.5 0 0 0 0 .707l.944.944a2.41 2.41 0 0 1 0 3.408l-.944.944a.5.5 0 0 1-.707 0L8.354 7.348a.5.5 0 0 1 0-.707l.944-.944a2.41 2.41 0 0 1 3.408 0l.944.944a.5.5 0 0 0 .707 0z"
/>
<path
d="M9 8c-1.804 2.71-3.97 3.46-6.583 3.948a.507.507 0 0 0-.302.819l7.32 8.883a1 1 0 0 0 1.185.204C12.735 20.405 16 16.792 16 15"
/>
</symbol>
<symbol id="i-erase" viewBox="0 0 24 24">
<path
d="M21 21H8a2 2 0 0 1-1.42-.587l-3.994-3.999a2 2 0 0 1 0-2.828l10-10a2 2 0 0 1 2.829 0l5.999 6a2 2 0 0 1 0 2.828L12.834 21"
/>
<path d="m5.082 11.09 8.828 8.828" />
</symbol>
<symbol id="i-download" viewBox="0 0 24 24">
<path d="M12 3v12m-5-5 5 5 5-5M4 16v4a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-4" />
</symbol>
<symbol id="i-trash" viewBox="0 0 24 24">
<path d="M3 6h18M8 6V3h8v3M5 6l1 15h12l1-15M10 10v7M14 10v7" />
</symbol>
<symbol id="i-pulse" viewBox="0 0 24 24"><path d="M2 12h4l3-9 5 18 3-9h5" /></symbol>
<symbol id="i-walk" viewBox="0 0 24 24">
<path
d="M4 16v-2.38C4 11.5 2.97 10.5 3 8c.03-2.72 1.49-6 4.5-6C9.37 2 10 3.8 10 5.5c0 3.11-2 5.66-2 8.68V16a2 2 0 1 1-4 0Z"
/>
<path
d="M20 20v-2.38c0-2.12 1.03-3.12 1-5.62-.03-2.72-1.49-6-4.5-6C14.63 6 14 7.8 14 9.5c0 3.11 2 5.66 2 8.68V20a2 2 0 1 0 4 0Z"
/>
<path d="M16 17h4" />
<path d="M4 13h4" />
</symbol>
<symbol id="i-left" viewBox="0 0 24 24">
<path d="m10 3-7 7 7 7M3 10h9c6 0 9 3 9 10" />
</symbol>
<symbol id="i-right" viewBox="0 0 24 24">
<path d="m14 3 7 7-7 7m7-7h-9c-6 0-9 3-9 10" />
</symbol>
<symbol id="i-escape" viewBox="0 0 24 24"><path d="m14 2-10 12h7l-1 8 10-13h-7Z" /></symbol>
<symbol id="i-pause" viewBox="0 0 24 24">
<rect x="6" y="3" width="3" height="18" rx="1" />
<rect x="15" y="3" width="3" height="18" rx="1" />
</symbol>
<symbol id="i-play" viewBox="0 0 24 24"><path d="m7 3 14 9-14 9Z" /></symbol>
<symbol id="i-reset" viewBox="0 0 24 24"><path d="M3 3v6h6M3 9a9 9 0 1 1 0 7" /></symbol>
<symbol id="i-info" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="9" />
<path d="M12 11v6m0-10v.5" />
</symbol>
<symbol id="i-chevron" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6" /></symbol>
</defs>
</svg>
<main class="workspace" id="workspace" inert>
<section class="brain-pane" aria-labelledby="brain-heading">
<div class="pane-head">
<span class="section-index">01</span>
<div class="pane-title">
<h1 id="brain-heading">Paint the brain</h1>
<p id="paint-hint">Paint neurons. Release to stimulate.</p>
</div>
<div class="projection-control">
<select id="projection" aria-label="Anatomical view">
<option value="brain">Brain</option>
<option value="cns">Brain + nerve cord</option></select
><svg class="icon"><use href="#i-chevron" /></svg>
</div>
</div>
<div class="brain-stage" id="brain-stage">
<canvas
id="brain"
tabindex="0"
aria-label="Paint neurons by dragging. Release to pulse. Action buttons below provide a keyboard alternative."
></canvas>
<div id="neuron-tooltip" hidden></div>
<div class="brain-loading" id="anatomy-status">Ready to load</div>
</div>
<div class="brain-key">
<span class="side-label">L</span>
<div class="activity-key">
<span><i class="rest"></i>Resting</span><span><i class="stim"></i>Stimulated</span
><span><i class="fire"></i>Firing</span>
</div>
<span class="side-label">R</span>
</div>
<div class="paint-controls">
<div class="paint-tools">
<button id="brush" class="tool-button" aria-pressed="true">
<svg class="icon"><use href="#i-paint" /></svg><span>Paint</span>
</button>
<button id="erase" class="tool-button" aria-pressed="false">
<svg class="icon"><use href="#i-erase" /></svg><span>Erase</span>
</button>
<label class="brush-size"
><span>Brush size</span
><input
id="size"
type="range"
min="10"
max="120"
value="42"
aria-label="Brush diameter"
/><output id="size-label">42 px</output></label
>
<button id="clear" class="tool-button">
<svg class="icon"><use href="#i-trash" /></svg><span>Clear</span>
</button>
<button id="replay" class="primary" disabled>
<svg class="icon"><use href="#i-pulse" /></svg><span>Pulse again</span>
</button>
</div>
<div class="actions">
<span class="field-label">Actions</span>
<div class="examples" aria-label="Actions">
<button data-preset="walk" aria-pressed="false">
<svg class="icon"><use href="#i-walk" /></svg><span>Walk</span>
</button>
<button data-preset="left" aria-pressed="false">
<svg class="icon"><use href="#i-left" /></svg><span>Turn left</span>
</button>
<button data-preset="right" aria-pressed="false">
<svg class="icon"><use href="#i-right" /></svg><span>Turn right</span>
</button>
<button data-preset="escape" aria-pressed="false">
<svg class="icon"><use href="#i-escape" /></svg><span>Fly</span>
</button>
</div>
</div>
</div>
</section>
<section class="fly-pane" aria-labelledby="fly-heading">
<div class="fly-surface" id="fly-surface">
<div class="pane-head fly-head">
<span class="section-index">02</span>
<h2 id="fly-heading">Watch the response</h2>
<div class="transport">
<button id="pause" disabled>
<svg class="icon"><use id="pause-icon" href="#i-pause" /></svg
><span id="pause-label">Pause</span></button
><span class="divider"></span
><button id="reset" disabled>
<svg class="icon"><use href="#i-reset" /></svg><span>Reset</span>
</button>
</div>
</div>
<div class="response-bar">
<div class="body-state">
<span id="behavior-dot"></span><span id="behavior">At rest</span
><small id="body-description"></small>
</div>
<div class="camera-tabs" aria-label="Camera view">
<button
id="camera-side"
aria-pressed="true"
title="Fixed viewing angle to see the fly turn"
>
Side</button
><button id="camera-top" aria-pressed="false">Top</button
><button
id="camera-follow"
aria-pressed="false"
title="Chase camera that follows the fly’s heading"
>
Follow
</button>
</div>
</div>
<div class="fly-stage" id="fly-stage">
<canvas id="fly" aria-label="Fly response. Drag to orbit; scroll to zoom."></canvas>
</div>
<div class="specimen-line">
<span>Drosophila melanogaster</span
><span class="scale"><i id="scale-bar"></i><span id="scale-value">1 mm</span></span>
</div>
</div>
<div class="readouts">
<div>
<span>Walking drive</span><output id="walk-rate">0 Hz</output>
<div class="meter"><i id="walk-meter"></i></div>
</div>
<div>
<span>Turning</span><output id="turn-rate">0°/s</output>
<div class="balance"><i id="turn-meter"></i><b id="turn-cursor"></b></div>
</div>
<div>
<span>Escape drive</span><output id="escape-rate">0 Hz</output>
<div class="meter"><i id="escape-meter"></i></div>
</div>
</div>
<div class="scene-footer">
<button
id="settings-button"
class="info-button"
aria-label="Experiment settings and information"
title="Experiment settings and information"
>
<svg class="icon"><use href="#i-info" /></svg>
</button>
<div id="status-wrap" class="status-copy" role="status">
<strong id="status">Ready to set up</strong
><span id="status-detail">166,700 neurons</span>
</div>
<details class="compute-select" id="compute-menu">
<summary>
<span class="status-light" id="status-light"></span
><span id="runtime-label">WebGPU · auto</span
><svg class="icon"><use href="#i-chevron" /></svg>
</summary>
<div class="compute-options">
<label
>Backend<select id="backend">
<option value="auto">WebGPU · automatic</option>
<option value="cpu">JavaScript reference</option>
</select></label
><label class="check"
><input id="depth-of-field" type="checkbox" checked /> Macro depth of field</label
>
<p id="compute-detail">Simulation runs locally.</p>
<button id="start" class="start-button" disabled>Start simulation</button>
</div>
</details>
</div>
<progress id="progress" max="1" value="0" hidden></progress>
</section>
</main>
<dialog
id="setup"
class="setup-dialog"
aria-labelledby="setup-heading"
aria-describedby="setup-status setup-detail"
data-state="idle"
open
>
<div class="setup-content">
<h2 id="setup-heading">Neural Canvas</h2>
<p id="setup-status" role="status">
Load the neural weights and prepare the scene to start painting.
</p>
<p id="setup-detail">166,700 neurons · 76 MB neural weights</p>
<progress id="setup-progress" max="1" aria-label="Setup progress" hidden></progress>
<button id="setup-button" class="primary" autofocus>
<svg class="icon"><use href="#i-download" /></svg
><span id="setup-button-label">Download &amp; start</span>
</button>
<p class="setup-note">
Runs locally in your browser. Downloaded weights are cached for next time.
</p>
</div>
</dialog>
<dialog id="settings" aria-labelledby="settings-heading">
<div class="dialog-heading">
<h2 id="settings-heading">Experiment settings</h2>
<button id="close-settings" aria-label="Close settings">×</button>
</div>
<label
>Pulse <input id="strength" type="range" min="50" max="250" step="10" value="180" /><output
id="strength-label"
>180 Hz</output
></label
>
<label class="check"
><input id="silence" type="checkbox" /> Disable recurrent transmission</label
>
<details class="model-details">
<summary>Model & sources</summary>
<p>
166,700 neurons from MaleCNS v1.0. Dataset IDs identify individual cells; they are not
consecutive neuron numbers.
</p>
<p>
Recorded connectivity and adapted spiking dynamics drive crafted walking, turning, and
flight animations. The movements are illustrative, not validated predictions of fly
behavior. The scanned body is a female NeuroMechFly specimen.
</p>
<p>
Turn actions stimulate LC9 and DNa02 on the selected side. Directly stimulated neurons can
still fire when recurrent transmission is disabled.
</p>
<div class="sources">
<a href="https://male-cns.janelia.org/download/" target="_blank" rel="noreferrer"
>MaleCNS data ↗</a
><a
href="https://www.nature.com/articles/s41586-024-07763-9"
target="_blank"
rel="noreferrer"
>Neural model ↗</a
><a href="https://huggingface.co/blog/webgpu-kernels" target="_blank" rel="noreferrer"
>@huggingface/kernels ↗</a
><a href="%BASE_URL%model.json" target="_blank">Model parameters ↗</a>
</div>
</details>
</dialog>
<script type="module" src="/src/main.js"></script>
</body>
</html>