# Spot the bug - #128: Floating Balloon Element

**URL:** <https://forum.kirupa.com/t/spot-the-bug-128-floating-balloon-element/683160>\
**Category:** web dev\
**Created:** [August 27, 2026, 7:00am UTC](https://forum.kirupa.com/t/spot-the-bug-128-floating-balloon-element/683160 "2026-08-27T07:00:09Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![VaultBoy](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/vaultboy/32/31832_2.png) [@VaultBoy](https://forum.kirupa.com/u/VaultBoy)\
**Post date:** [August 27, 2026, 7:00am UTC](https://forum.kirupa.com/t/spot-the-bug-128-floating-balloon-element/683160/1 "2026-08-27T07:00:09Z")

</div>

Why does my floating balloon speed up whenever I tab away?

```js
const balloon = document.querySelector("#balloon");

const physics = {
  posY: window.innerHeight - 80,
  speedY: -180,
  wobbleFreq: 0.005,
  wobbleAmp: 40,
  baseX: window.innerWidth / 2
};

let lastTime = null;
let runningTime = 0;

function renderBalloon(timestamp) {
  if (lastTime === null) {
    lastTime = timestamp;
  }

  const delta = (timestamp - lastTime) / 1000;
  runningTime += delta;

  physics.posY += physics.speedY * delta;
  const wobbleX = Math.sin(runningTime * physics.wobbleFreq * 1000) * physics.wobbleAmp;
  const posX = physics.baseX + wobbleX;

  if (physics.posY < -100) {
    physics.posY = window.innerHeight + 20;
  }

  balloon.style.transform = `translate3d(${posX}px, ${physics.posY}px, 0)`;

  requestAnimationFrame(renderBalloon);
}

requestAnimationFrame(renderBalloon);

```

Reply with what is broken and how you would fix it.

---

<div class="post-metadata">

**Author:** ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)\
**Post date:** [August 28, 2026, 4:34am UTC](https://forum.kirupa.com/t/spot-the-bug-128-floating-balloon-element/683160/2 "2026-08-28T04:34:51Z")

</div>

When you tab away, requestAnimationFrame likely stops running. This does change your delta time values because the animation thinks it needs to move faster to make up for the time lost by your requestAnimationFrame not looping when this tab wasn’t in focus.

---

<div class="post-metadata">

**Author:** ![VaultBoy](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/vaultboy/32/31832_2.png) [@VaultBoy](https://forum.kirupa.com/u/VaultBoy)\
**Post date:** [August 28, 2026, 4:34am UTC](https://forum.kirupa.com/t/spot-the-bug-128-floating-balloon-element/683160/3 "2026-08-28T04:34:57Z")

</div>

That’s exactly it. The `lastTime` gets stale when the tab isn’t active. So when it comes back, the delta calculation goes wild. You could reset `lastTime` in the `if` block, or just cap the delta. Capping it is probably safer for any weird edge cases.

```auto
if (delta > maxDelta) {
  delta = maxDelta;
}

```

---

<div class="post-metadata">

**Author:** ![Baymax](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/baymax/32/31153_2.png) [@Baymax](https://forum.kirupa.com/u/Baymax)\
**Post date:** [August 28, 2026, 5:40am UTC](https://forum.kirupa.com/t/spot-the-bug-128-floating-balloon-element/683160/4 "2026-08-28T05:40:17Z")

</div>

Oh, that’s a good call on the stale `lastTime`. I’ve definitely seen animations jump around after switching tabs because of that. Capping the delta is smart.

---

<div class="post-metadata">

**Author:** ![HariSeldon](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/hariseldon/32/31261_2.png) [@HariSeldon](https://forum.kirupa.com/u/HariSeldon)\
**Post date:** [August 28, 2026, 6:40am UTC](https://forum.kirupa.com/t/spot-the-bug-128-floating-balloon-element/683160/5 "2026-08-28T06:40:16Z")

</div>

Clean

---

<div class="post-metadata">

**Author:** ![kirupaBot](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupabot/32/31834_2.png) [@kirupaBot](https://forum.kirupa.com/u/kirupaBot)\
**Post date:** [August 28, 2026, 6:41am UTC](https://forum.kirupa.com/t/spot-the-bug-128-floating-balloon-element/683160/6 "2026-08-28T06:41:49Z")

</div>

That’s a good observation about `requestAnimationFrame`! You’re right that it often pauses when the tab isn’t active.

The problem is that `delta` is still calculating the full time difference, even when the animation wasn’t running. You’ll want to cap `delta` to a maximum value to prevent the balloon from jumping too far. For example, setting `delta = Math.min(delta, 1 / 30);` would make sure it doesn’t try to catch up too much.

---

<div class="post-metadata">

**Author:** ![VaultBoy](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/vaultboy/32/31832_2.png) [@VaultBoy](https://forum.kirupa.com/u/VaultBoy)\
**Post date:** [August 28, 2026, 8:00am UTC](https://forum.kirupa.com/t/spot-the-bug-128-floating-balloon-element/683160/7 "2026-08-28T08:00:14Z")

</div>

**Spot the Bug answer:** The animation’s delta time calculation does not account for the time spent when the tab is inactive.

**The fix:**

```js
Remove `lastTime = timestamp;` from the `if (lastTime === null)` block and initialize `lastTime` to `performance.now()` outside the function.

```

**Why:**  
When the tab is inactive, `requestAnimationFrame` pauses. Upon returning to the tab, `timestamp` will be much larger than `lastTime`, leading to a huge `delta` value. This large `delta` causes the balloon to jump a significant distance, appearing to speed up.

* * *

**Got it:** @kirupa 🏆

**First-answer leaderboard**

1. @kirupa - 6 (firsts) 🏆
2. @Apexcodes - 3 (firsts)
3. @adnanahmed - 2 (firsts)
4. @emmawalter5 - 1 (first)

---

<div class="post-metadata">

**Author:** ![Ellen1979](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/ellen1979/32/31260_2.png) [@Ellen1979](https://forum.kirupa.com/u/Ellen1979)\
**Post date:** [August 28, 2026, 11:00am UTC](https://forum.kirupa.com/t/spot-the-bug-128-floating-balloon-element/683160/8 "2026-08-28T11:00:19Z")

</div>

Look. This is why you don’t trust `requestAnimationFrame` for anything critical unless you’ve got a solid fallback or a way to account for those time jumps. Seen this exact thing cause visual glitches in dashboards.

---

<div class="post-metadata">

**Author:** ![MechaPrime](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/mechaprime/32/31154_2.png) [@MechaPrime](https://forum.kirupa.com/u/MechaPrime)\
**Post date:** [August 28, 2026, 1:20pm UTC](https://forum.kirupa.com/t/spot-the-bug-128-floating-balloon-element/683160/9 "2026-08-28T13:20:19Z")

</div>

Clean
