Skip to content

Latest commit

 

History

15 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

3D Beating Heart Viewer

A browser-based 3D heart viewer. Two anatomical models, one driven by its baked skeletal animation, the other by a procedural cardiac rhythm sampled from the first. Pulsing galaxy backdrop for vibes.

No build step, no npm — open index.html through a local HTTP server and it runs.

Credits — 3D Models

This project does not redistribute the heart models. The .gitignore excludes *.glb. You need to download both yourself from Sketchfab (free account required, CC BY 4.0):

Slot Model Author License
public/heart.glb Beating Heart jalmer CC BY 4.0
public/heart-alt.glb Animated Beating Heart nitwit.friends CC BY 4.0

Please respect the original authors' licenses if you fork or redistribute this project.

Setup

  1. Download both GLBs from the links above. Sketchfab's "glTF" download bundles the .glb inside a .zip. For jalmer's model the file is nested at source/Beating heart.glb inside the inner zip.
  2. Save them in public/:
    • public/heart.glb (primary, cutaway with skeletal animation)
    • public/heart-alt.glb (alt, low-poly with morph target)
  3. Start a local HTTP server (browsers block fetch from file://):
    python3 -m http.server 8000
  4. Open http://localhost:8000.

Controls

  • Drag — rotate
  • Scroll — zoom
  • "Switch model" (top right) — toggle between the two hearts

How it works

  • Primary heart plays its baked 1-second skeletal animation through Three.js AnimationMixer. 21 joints, 63 channels.
  • Alt heart's baked clip had duplicate frames and a mid-beat reversal that read as arrhythmia, so it's bypassed. Instead, the morph target weight is driven on the CPU using a curve sampled from the primary heart's right-atrium displacement track — same rhythm, normalized to [0, 1].
  • Atrioventricular delay: each vertex of the alt heart gets a phase offset based on its Y position. Top vertices (atria region) fire first; bottom vertices (ventricles) lag by 0.25s. This produces a visible "lub-dub" wave through the mesh.
  • Material restyle: alt heart gets MeshPhysicalMaterial with beige base color and clearcoat for wet sheen; normals are recomputed from the geometry each frame to keep shading smooth through the deformation.
  • Galaxy backdrop: ~4,000 stars on a sphere plus a ~9,000-point 4-arm spiral disk, written with a small ShaderMaterial so every star has its own random base size, phase delay (0–0.18s), and pulse amplitude. They pulse in time with the heartbeat — a ripple of light propagating through the field on every beat.

All of the per-frame logic lives in main.js. The tunable constants are clustered near the top of each system.

Stack

  • Three.js 0.160.0 (ESM, loaded from unpkg via import map)
  • Vanilla JS / HTML / CSS
  • No bundler, no transpiler, no dependencies to install

Contributing

Ideas if you want to play:

  • Add audio — synthesize a "lub-dub" tone driven by sampleBeat() for true cardiac feel
  • ECG strip overlay along the bottom, tracing the morph weight curve
  • Per-vertex hue shift on the alt heart synced to the contraction (paler at peak)
  • A third model slot for any GLB you find
  • Camera auto-orbit when the user hasn't interacted for a while
  • Asymmetric atrial-vs-ventricular curves (right now both phases use the same shape, just time-shifted; real cardiac timing has different waveforms)

PRs welcome. Open an issue first if you want to discuss a larger change.

License

The code in this repo is MIT licensed — see LICENSE.

The 3D models are not covered by this license. They are distributed by their original authors under CC BY 4.0 (see Credits above).

About

3D beating heart in Three.js with synthesized cardiac rhythm and a pulsing galaxy backdrop

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages