How it's different

The canvas version renders into a WebGL overlay using KAPLAY. This version skips all of that: the fox is a plain <span> with position: fixed, and physics is a requestAnimationFrame loop that reads getBoundingClientRect() every frame.

No dependencies, no build, ~120 lines of JS. The ledge-extraction algorithm is the same: scan every element, extract top edges, merge overlapping intervals at the same Y-level into thin shelves.

Zero deps

No KAPLAY, no canvas, no CDN. Runs from file://.

Real DOM node

The fox is an actual element โ€” inspectable in DevTools.

Live rects

Platforms re-read on every scroll and resize event.

Because the buddy is position: fixed and platforms come from getBoundingClientRect(), both live in viewport coordinates. Scrolling shifts the DOM elements relative to the buddy โ€” platforms move and the fox responds in real time.

Gravity 800 px/sยฒ
Jump 450 px/s
Speed 80 px/s
Shelf 16 px
Y-merge ยฑ3 px

Canvas vs DOM

๐Ÿ–ผ Canvas (browser-buddy)

WebGL overlay via KAPLAY. Full physics engine. Easy sprites and animations. Heavier โ€” needs CDN.

๐Ÿ“Œ DOM (this)

Fixed-position element. Manual physics loop. No deps. Buddy is a real DOM node.

PropertyCanvasDOM
External libraryKAPLAY (CDN)none
RenderingWebGLCSS transform
Buddy nodevirtual (game object)real DOM element
PhysicsKAPLAY enginemanual rAF loop
InteractionKAPLAY eventsDOM events

Collision detection

Each frame the loop computes the buddy's previous and next bottom edge and checks whether they straddle a platform's top. If they do, the buddy snaps to the surface and vertical velocity zeroes out. There are no side walls โ€” only top-edge shelves โ€” so the fox can never get wedged between elements.

๐ŸŽฎ You're playing right now
๐Ÿ“ Every element is a platform
๐Ÿšซ No canvas involved