Skip to content
Builds
Native Lab experiment, designed and built solo

A mascot rigged in code, not animated

A to-do list mascot who watches your finger, giggles when poked, flies when flung, leans when you tilt the phone and cheers your last task.

React Native Skia · Reanimated · Worklets · Gesture Handler · Expo Sensors · Expo Haptics

1Demo

  • Buddy cheering the last task with confetti

Scripted simulator take: the finger and the tilt are scripted. Not yet tested on a phone.

2Flow

  1. 1Touch the screenYouhis eyes follow your finger; lift it and they wander
  2. 2Poke himYoua light haptic tap, a surprised face, then a giggle
  3. 3Fling himYouhe flies, bounces off the walls and lands with a squash; a hard landing makes him dizzy
  4. 4Tilt the phonePhonegravity turns with it, and he leans to stay upright
  5. 5Tick the last taskYouhe jumps, cheers and throws confetti, with a success haptic
Every motion has a cause. Left alone, he waddles back to his spot.

3How it fits

System
UI threadpointerDown / Upgravity anglecheer()everyframecreatePicturescheduleOnRNYour fingerGesture.PanPhone tiltuse-gravity.tsLast task tickedtoggle() in the listRigrig.ts · stepRig()PoseposeOf()Skia picturedraw.ts · drawBuddy()Hapticsfeedback.ts
Inputs only nudge the rig. Each frame it steps, becomes a pose and is drawn; haptics come from its events.

4Code

    if (r.y >= floor) {
      const impact = r.vy;
      r.y = floor;
      if (impact > 380) {
        r.vy = -impact * 0.36;
        r.vx *= 0.7;
        r.sy = Math.max(0.68, 1 - impact / 4200);
        r.syV = 0;
        r.landed = Math.max(r.landed, impact);
        if (impact > 1500 && r.expr !== 'cheer') set(r, 'dizzy', 2.6);
      } else {
        r.vy = 0;
        if (!r.grounded && r.expr === 'wee') set(r, 'giggle', 0.8);
        r.grounded = true;
      }
    } else if (r.y < floor - 0.5) {
      r.grounded = false;
    }
  }

  // Expression timers.
  if (r.expr !== 'idle') {
    r.exprT -= dt;
    if (r.exprT <= 0) set(r, 'idle', 0);
  }
  const e = r.expr;

  // Squash and stretch: a spring back to 1, stretched along a fall.
  const airStretch = r.grounded || r.dragging ? 0 : Math.min(0.1, Math.abs(r.vy) / 9000);
  const waddle = r.walking ? Math.abs(Math.sin(r.t * 13)) * 0.04 : 0;
  const giggleBounce = e === 'giggle' ? Math.sin(r.t * 26) * 0.035 : 0;
  [r.sy, r.syV] = spring(r.sy, r.syV, 1 + airStretch + giggleBounce + waddle, 420, 13, dt);

  // Lean: against the tilt to stay upright in the world, into his own motion, wobbling when dizzy.
  const wobble = r.dizzy * Math.sin(r.t * 7) * 0.14;
  const leanTarget = -tilt * 0.8 + Math.max(-0.4, Math.min(0.4, r.vx / 3000)) + wobble;
  [r.lean, r.leanV] = spring(r.lean, r.leanV, leanTarget, 140, 11, dt);

A landing squashes him by how hard he hit, a hard one makes him dizzy, and springs ease squash and lean back to their targets.

5Decisions

  • A rig drawn in code every frame over a Rive or Lottie animation

    a timeline plays whether you're there or not; here every motion has a cause

  • Expressions as short timed states over switching between animations

    a state only sets the targets the springs chase, so poke, giggle and dizzy blend

  • A small Gfx drawing interface over calling Skia directly

    the same drawing code renders offline in CanvasKit, which is how the design was tuned

  • A scripted finger on the real pointer path over a staged animation for the video

    the take runs through the same code a real finger hits, so his reactions are his own

More builds

  • Dragging a bottle of Chianti off the receipt onto Everyone

    Split the bill by dragging

    Drag each item off the receipt onto whoever had it, and their share rolls up, service included.

    Native Lab experiment, designed and built soloDemo · Flow · System · Code

    24 Oct 2026

  • 12:41 PM in London, and everyone is awake

    A globe that shows who's awake

    Your people on a globe lit by the real Sun: scrub the next day to see who is awake, or tap once for a time that suits everyone.

    Native Lab experiment, designed and built soloDemo · Flow · System · Code

    23 Oct 2026

Meer's mascot, waving a peace sign

Have an app in mind?

Tell me what you're building. Replies within 24h. It's in Chittagong.

Booking new projects for Q4

Free 30-minute call

Talk through your app with me. You leave with a plan and a fixed price.

Video callShown in your time zone in Chittagong