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.
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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
