Mouse-Driven Transforms
CSSThe same 9 elements, the same CSS properties — triggered two different ways. Left: a CSS transition fires when the cursor enters each element. Right: the same scale, glow, and color continuously lerp toward targets set by global cursor distance, before you've even touched an element.
fires on cursor enter/leave — binary, transition-driven
lerps from cursor distance — continuous, no hover needed
concepts
CSS transition fires on mouseenter / mouseleave. The state is strictly on or off — the browser handles interpolation, but only after the cursor crosses the element boundary.
A RAF loop reads global cursor position every frame, computes distance to each element center, and lerps a 0–1 weight. Elements react before you touch them.
dist = √((x − cx)² + (y − cy)²). Dividing by the radius normalizes to [0, 1]: 0 means far away, 1 means directly over the element center.
Lerping the scale each frame (scale += (target - scale) * speed) means the element always moves a fraction toward its target — producing smooth deceleration for free.
core pattern
// Each RAF frame, for each element:
const dist = Math.sqrt((mouseX - cx)**2 + (mouseY - cy)**2);
const t = Math.max(0, 1 - dist / radius); // 0=far, 1=center
// Lerp scale toward the proximity-weighted target
scale += (1 + t * 0.28 - scale) * 0.07;
el.style.transform = `scale(${scale})`;