Achieving Sub-Frame Interpolation with GSAP and Web Workers

Browser animation timing is limited by the refresh rate (typically 60fps). But with a bit of creative hacking, we can simulate sub-frame interpolation — making animations feel smoother than the frame rate allows. This guide uses GSAP and Web Workers to blend physics-calculated positions with the current render frame, unlocking ultra-fluid motion. Why Sub-Frame Interpolation? Even with requestAnimationFrame, you’re capped at ~16.7ms updates. For high-speed or high-precision visuals (e.g. physics, UI drag), this isn’t enough. We’ll decouple physics updates and blend them at render-time for “in-between” values. Step 1: Spawn a Web Worker for Physics Updates This runs physics logic independently of the main render loop. // physics.worker.js let x = 0, v = 0.1; function step() { x += v; postMessage({ x }); setTimeout(step, 5); // ~200Hz physics loop } onmessage = (e) => { if (e.data === 'start') step(); }; Step 2: Set Up the Main Thread Animation Loop We'll interpolate between the last two physics values. const worker = new Worker('physics.worker.js'); let current = 0, previous = 0, alpha = 0; worker.onmessage = ({ data }) => { previous = current; current = data.x; }; worker.postMessage('start'); function animate(timestamp) { alpha += 0.05; if (alpha > 1) alpha = 1; const interpolated = previous * (1 - alpha) + current * alpha; gsap.set("#ball", { x: interpolated * 300 }); requestAnimationFrame(animate); } requestAnimationFrame(animate); Step 3: Render the Element Basic HTML + CSS to visualize it: ball { width: 30px; height: 30px; border-radius: 50%; background: hotpink; position: absolute; } How It Works The worker calculates the next physics state ~200 times per second, storing the last and current positions. On the main thread, we interpolate between those two values each frame to simulate in-between states. The result is smoother perceived motion without locking to the frame rate. Pros and Cons ✅ Pros Visibly smoother animations under heavy load Offloads calculations to Web Workers Works great for physics-based UI or motion trails ⚠️ Cons Added complexity with worker communication Interpolation logic must be carefully tuned Minimal benefit for low-speed animations

Apr 26, 2025 - 10:33
 0
Achieving Sub-Frame Interpolation with GSAP and Web Workers

Browser animation timing is limited by the refresh rate (typically 60fps). But with a bit of creative hacking, we can simulate sub-frame interpolation — making animations feel smoother than the frame rate allows. This guide uses GSAP and Web Workers to blend physics-calculated positions with the current render frame, unlocking ultra-fluid motion.

Why Sub-Frame Interpolation?


Even with requestAnimationFrame, you’re capped at ~16.7ms updates. For high-speed or high-precision visuals (e.g. physics, UI drag), this isn’t enough. We’ll decouple physics updates and blend them at render-time for “in-between” values.

Step 1: Spawn a Web Worker for Physics Updates


This runs physics logic independently of the main render loop.

// physics.worker.js
let x = 0, v = 0.1;

function step() {
x += v;
postMessage({ x });
setTimeout(step, 5); // ~200Hz physics loop
}

onmessage = (e) => {
if (e.data === 'start') step();
};

Step 2: Set Up the Main Thread Animation Loop


We'll interpolate between the last two physics values.

const worker = new Worker('physics.worker.js');
let current = 0, previous = 0, alpha = 0;

worker.onmessage = ({ data }) => {
previous = current;
current = data.x;
};

worker.postMessage('start');

function animate(timestamp) {
alpha += 0.05;
if (alpha > 1) alpha = 1;

const interpolated = previous * (1 - alpha) + current * alpha;
gsap.set("#ball", { x: interpolated * 300 });

requestAnimationFrame(animate);
}

requestAnimationFrame(animate);

Step 3: Render the Element


Basic HTML + CSS to visualize it:




How It Works


The worker calculates the next physics state ~200 times per second, storing the last and current positions. On the main thread, we interpolate between those two values each frame to simulate in-between states. The result is smoother perceived motion without locking to the frame rate.

Pros and Cons

✅ Pros


  • Visibly smoother animations under heavy load
  • Offloads calculations to Web Workers
  • Works great for physics-based UI or motion trails

⚠️ Cons


  • Added complexity with worker communication
  • Interpolation logic must be carefully tuned
  • Minimal benefit for low-speed animations