An interactive WebGL model tracing one stimulus — intermittent fasting — through five scales of the genome: nuclear architecture, chromatin/histone marks, DNA methylation, gene activity, and downstream phenotype. Built with three.js for the 3D scenes and GSAP for animated transitions.
Move the metabolic-state slider (Fed → Extended fast) and pick a gene to inspect; every panel — the nuclear compartment/loop diagram, the nucleosome fiber, the DNA methylation helix, the expression bars, and the phenotype gauges — recomputes and animates together. Each 3D scene supports drag-to-rotate and scroll-to-zoom.
Six genes are modeled (SIRT1, FOXO3, PPARGC1A/PGC-1α, ATG7, RPS6KB1, IL6), spanning both fasting-induced and fasting-suppressed programs, with values that synthesize established fasting/epigenetics biology (see the in-app "About this model" section for what's grounded vs. illustrative).
src/
data.js gene dataset (fed/fasted pairs) + interpolation helpers
theme.js reads CSS custom properties into JS-usable colors
sway.js idle turntable motion for the 3D scenes
scene-nucleus.js 3D scene: chromosome territories, A/B compartment, CTCF loop
scene-chromatin.js 3D scene: nucleosome fiber + histone PTM flags
scene-helix.js 3D scene: DNA double helix + CpG methylation markers
main.js DOM wiring, SVG bar/gauge charts, master update loop
styles.css design tokens (light/dark) + layout
index.html dev shell — loads dist/bundle.{js,css}
build-artifact.mjs inlines the minified bundle into a single self-contained page
npm install
npm run build # writes dist/bundle.js + dist/bundle.css
npm run serve # serves this directory at http://localhost:8935Then open http://localhost:8935/index.html. Re-run npm run build after editing
anything in src/.
npm run build:artifactWrites dist/artifact.html — a single self-contained file (CSS and minified JS
inlined, no external requests) suitable for publishing anywhere as one page.
npm run check runs the build guards in scripts/check-build.mjs, which encode
this project's actual constraints rather than generic linting:
- the standalone artifact exists and stays under the 16 MB publish limit
- it references no external URLs and makes no external network calls — the
published page runs under a CSP that blocks every external host, so a stray
CDN
<script>is a shipping bug - every element id referenced by
getElementByIdinsrc/exists inindex.html— a missing id fails silently at load in a page with six independent WebGL scenes - every
scene-*.jsmodule is actually mounted inmain.js
Three workflows live in .github/workflows/:
| Workflow | Trigger | What it does |
|---|---|---|
ci.yml |
push / PR to main |
installs, builds, runs the guards, and uploads artifact.html as a downloadable build artifact (30-day retention) |
release.yml |
tag matching v* |
builds and attaches the standalone page to a GitHub Release |
pages.yml |
manual only | deploys the page to GitHub Pages |
To cut a release:
git tag v1.0.0 && git push origin v1.0.0Note on Pages: GitHub Pages is not available for private repositories on the
Free plan, so pages.yml is manual-trigger only and fails fast with an
explanatory message while the repo is private. It becomes usable as soon as the
repo is made public or the account moves to Pro — at which point set
Settings → Pages → Source to "GitHub Actions". Until then, ci.yml and
release.yml cover build verification and distribution.
Educational model, not medical advice. Exact percentages and the smooth 0–100 slider are an illustrative synthesis, not measurements from one dataset — see the in-app methodology notes for details and caveats.