fysiio/exercise.ts

Exercises are data.
Everything else is derived.

This is the real, working source for Glute Bridge — abridged to fit the panel, nothing invented. Watch it type itself out, then watch the same numbers move a figure on the right.

glute-bridge.ts
// the entire movement is two numbers: lift the pelvis, tilt it slightly.
// feet + hands are pinned to the floor — hip & knee angles are solved, not authored.
export const gluteBridge: ExerciseConfig = {
  id:         'glute-bridge',
  name:       'Glute Bridge',
  posture:    'supine',

  poseAdjust: {
    hipFlexionL: 55,   hipFlexionR: 55,    // knees bent up
    kneeFlexionL: 100, kneeFlexionR: 100,
  },
  activePins: ['footL', 'footR', 'handL', 'handR'],

  keyframes: [
    { id: 'setup', pose: {} },
    { id: 'lift', pose: {
        rootLift: 24,   // pelvis rises — hips, knees, shoulders all follow
      } },
  ],
  // …category, difficulty, cues, sets/reps, muscle curves trimmed for the panel
}
src/lib/exercises/glute-bridge.ts 18 lines shown
figure.js posture: supine
../assets/poses/glute-bridge.json — same file, drawn on a canvas

That's the entire movement. The knee angles you see? Computed by inverse kinematics — never authored.

One JSON file, five faces.

Nothing below is a separate export or a re-shoot. Each surface reads the same keyframes and joint math as the code panel above — a screenshot of the real app, a live canvas, a print layout, a share card.

$ render --as=player
Fysiio player showing the glute bridge exercise with the muscle-activation heatmap panel open.

The full player — scrub, camera, activation heatmap. Real screenshot of the same posture and keyframes.

$ render --as=thumbnail

Live canvas, cropped small — this is the library thumbnail size, drawing the exact same frames.

$ render --as=handout
Printed exercise handout for glute bridge with step illustrations and cues, on white paper.

Print layout, light theme. Real screenshot — same coordinates, no separate illustration pass.

$ render --as=share-card

Live composition built from this page's data — the actual share cards are generated server-side at this size, from the same source.

Every exercise is checked headlessly, not eyeballed.

$ npm run verify && npm run golden
  • pins hold — planted hands and feet don't drift while the pose solves
  • floor contact — nothing sinks below y = 0 at any frame
  • no self-intersection — soft-tissue contact is fine, limbs passing through each other is not
  • ROM-clamped — every joint stays inside normative range-of-motion limits
  • golden-snapshot match — today's output matches the committed reference for every exercise

These are the same headless checks that gate every commit to the engine — run against all 65 exercises and every body-type profile, not just the one on this page.

The data is the point. Go look at more of it.