Frontend Development 5 min read

Implementing a Parabolic Jump Interaction for Bottom Navigation with CSS3 Mask and JavaScript

This article explains how to create a bottom navigation bar that jumps along a parabolic trajectory using a mathematical formula for the curve, CSS3 mask and radial‑gradient techniques, and a requestAnimationFrame‑driven JavaScript animation loop.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Implementing a Parabolic Jump Interaction for Bottom Navigation with CSS3 Mask and JavaScript

In this tutorial the author describes the motivation and implementation of a "parabolic jump" interaction for a bottom navigation bar, originally inspired by a UI video from a previous employer.

Parabolic Motion

The motion is derived from the classic quadratic equation y = a * x * x + b * x + c . Assuming the curve passes through the origin (0,0) gives c = 0 . With a constant a and known start and end points, b can be calculated as b = (y2 - a * (x2 * x2)) / x2 . Once a , b , and c are known, the full trajectory can be computed.

/**
 * @param target 目标点的x,y坐标
 * @param x      当前x坐标
 * @param a      常量,决定曲率
 */
const curve = (target : { x : number, y : number }, x : number, a : number = 0.001) => {
  let b = (target.y - a * (target.x * target.x)) / target.x;
  let y = a * (x * x) + b * x;
  return y;
}

CSS3 Mask Effect

The visual hole effect is achieved with a CSS mask combined with a radial gradient. The mask syntax mirrors the background property.

background-image: radial-gradient(circle at 50% 0upx, transparent 200upx, white 200upx);

Mask example:

-webkit-mask: radial-gradient(circle at 50rpx 0rpx, transparent 45rpx, #999999 45rpx);

Images illustrate the resulting mask and gradient effects.

Animation with requestAnimationFrame

To achieve a smooth transition, the author uses requestAnimationFrame to update the position each frame based on the calculated curve.

/* @param target 目标位置
 * @param time   运动时长 */
const move = (target, time) => {
  let distance = target - circleLeft.value;
  let speed = distance / (time / 60);
  let isMoveLeft = circleLeft.value > target;
  let sourceLeft = JSON.parse(JSON.stringify(circleLeft.value));

  const resetStatus = () => {
    cancelAnimationFrame(timer);
    circleTop.value = 0;
    circleLeft.value = target;
  }

  let animate = () => {
    circleLeft.value += speed;
    circleTop.value = curve({ x: distance, y: 0 }, circleLeft.value - sourceLeft);
    if (isMoveLeft) {
      if (circleLeft.value <= target) resetStatus();
    } else {
      if (circleLeft.value >= target) resetStatus();
    }
    timer = requestAnimationFrame(animate);
  }
  animate();
}

The animation updates the horizontal position, computes the vertical offset using the parabolic formula, and stops when the target is reached, resulting in a silky motion.

Final Result

The completed effect shows a bottom navigation bar where the active icon follows a smooth parabolic jump, with a masked radial gradient creating a visual hole that follows the moving element.

Feel free to try implementing this interactive navigation bar yourself.

JavaScriptcss3maskParabolic Motion
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.