Skip to content

Repository files navigation

Heart Explorer

checks

An interactive 3D heart anatomy viewer that runs in the browser. No build step, no bundler, and no 3D model files.

Heart Explorer

Open the live demo →

Why I built this

This is a proof of concept for a larger project.

My dad had a brain aneurysm in October 2013. The years since have produced a lot of medical history, and one of the recurring problems is handing that history to a new doctor in a form they can actually absorb in the few minutes they have. I'm building a retrieval system over those records to deal with the search half of that problem.

The other half is presentation. Being able to point at something and say here, this is what happened and where turns out to matter as much as being able to find the record. Heart Explorer is where I tested that half: different organ, same question. Can you build an interactive anatomical view that loads instantly in a browser, with no install and nothing to configure, and still be precise enough to point at specific structures?

That constraint is why there's no build step and no asset pipeline here. If it can't open on an unfamiliar machine in one click, it's not useful in the room where you'd need it.

The idea

Most 3D anatomy viewers ship a big binary mesh built in Blender or ZBrush. That works, but the geometry becomes a black box. You can't diff it, review it, or reason about it in code.

I wanted to try the opposite. Here the heart is described as data and assembled at runtime. There are 47 structures, each with an anatomical group, a short summary, the view modes it appears in, and a 3D anchor point. Geometry gets built from spheres, tori, tubes and swept segments. The whole model is plain text under version control.

That one constraint ended up shaping most of the interesting decisions in the code.

What's in it

47 structures across 8 groups: chambers, valves, great vessels, septa and wall layers, coronary circulation, the conduction system, internal supports, and external landmarks.

Three view modes:

  • Surface shows chambers, vessels and coronary landmarks
  • Cutaway opens it up to valves, septa and wall layers
  • Systems highlights coronary circulation and the electrical conduction pathway

You can focus a single structure, explode the model to separate the parts, or toggle guide pins. Clicking anywhere in the scene picks the structure under the cursor via raycasting, and there's search and per-group filtering in the side panel.

How it fits together

STRUCTURES[]  47 records: id, label, group, summary, modes, anchor
     |
     |-- buildHeart()        assembles meshes from primitives
     |-- registerStructure() maps each mesh back to its structure id
     |
     |-- raycaster           click in scene -> structure id -> selection
     `-- renderStructureList() / syncSelectedPanel() keep the DOM in sync

Opacity is layered per class of structure. Chambers, shells, vessels and system overlays each carry their own alpha, which is what lets the cutaway view stay readable without depth-sorting artifacts.

Running it

No build step and nothing to install. A bundled server ships with it:

git clone https://github.com/Ark2027/heart-explorer
cd heart-explorer
node server.mjs

Then open http://localhost:8000. Set PORT if 8000 is taken.

Anything else that serves static files works too, for example npx serve . or python -m http.server 8000.

It needs to be served over http rather than opened as a file, since ES module imports don't work on the file:// protocol.

Notes

Three.js is pulled in through an import map declared in index.html, so there's no bundler and no node_modules at runtime. The browser resolves the bare three and three/addons/ specifiers directly. OrbitControls is the only addon used.

The control panel uses semantic landmarks and aria labels, and the selected-structure panel is an aria-live region so screen readers announce changes as you move through the model.

index.html    markup, import map, panel structure
app.mjs       structure data, geometry, interaction, UI sync
styles.css    layout and theming
server.mjs    optional static server

Things I'd change

app.mjs got long. buildHeart() is about 600 lines on its own and the structure table takes up another 380 or so. Splitting it into structures.mjs, primitives.mjs, and a buildHeart() broken up by anatomical group is the first thing I'd do next.

The anatomy is a teaching approximation rather than a clinically accurate model. Proportions and anchor points were tuned so structures stay legible when you rotate, not for precision.

License

MIT

About

Interactive 3D heart anatomy in the browser. Every structure is built from code, so there's no model file to download and nothing to build.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages