Game Primitive ~3 KB No deps

FROG HOP

Click a lily pad. He jumps. Sometimes he lands. Sometimes the pad sinks.

SVG RAF Web Audio Parabolic arc
LIVE DEMO ·
HOPS0 SPLASH0
tap a pad →

The Trick

True parabolic motion via requestAnimationFrame. Each frame computes x as linear interpolation, y as lerp_y − sin(t·π) · arcHeight — so the frog rises and falls in a clean arc, not a bezier approximation.

Each pad has 12% chance of being rotten. Land on a rotten pad → it sinks, frog splashes, miss counter ticks. Risk + delight.

Why parabola

A CSS cubic-bezier curve can fake an arc but breaks if you change start/end mid-flight. RAF lets you retarget instantly.

Why squish-on-land

Three-keyframe scale animation sells weight without physics — the frog feels like it has mass.

Why rotten pads

Without failure, hopping has no texture. 12% spice rate = enough surprise, not enough to frustrate.

The Hop

// parabolic arc — t goes 0→1, sin(t*π) peaks at .5
function hop(frog, fromX, fromY, toX, toY, arcHeight, duration){
  const t0 = performance.now();
  function step(now){
    const t = Math.min(1, (now - t0) / duration);
    const x = fromX + (toX - fromX) * t;
    const y = fromY + (toY - fromY) * t - Math.sin(t * Math.PI) * arcHeight;
    frog.style.transform = `translate(${x}px, ${y}px)`;
    if (t < 1) requestAnimationFrame(step);
    else frog.classList.add('land');
  }
  requestAnimationFrame(step);
}

Drop in any container with class .pond. Frog + pads render themselves.