专注于目标,全世界都会给你让路
❞
做这个效果的初衷是当年在第一家公司的时候,我们的UI小姐姐拿着B站的视频效果
问:「“这个效果可以实现吗?”」
答:「“你想我死可以直说,不用拐弯抹角 ”」
年少不知道男人不能说不行,现在想要弥补一下遗憾,于是花了点时间实现了「抛物线跳跃交互底部导航栏」。
原理其实非常简单:「两点之间的抛物线运动 + CSS3镂空效果」
在上一篇文章里我们似乎出现过这个词,但是实现方式却是通过现成的API实现。今天我们通过 「数学公式」 来完成。
先把热乎的饭菜端上:
/**
* @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;
}
这是通过下面公式转换而来的
❝「y = a * x * x + b * x + c」
❞
公式中有 3 个变量 「a、b、c」。我们假设抛物线经过(0,0),将x = 0,y = 0代入公式,可以得知「c = 0」; 已知变量 a 是 常量,抛物线起终两点也已知,那 b 点也自然能够算出。
❝「b = (y2 - a * (x2 * x2)) / x2」
❞
三个变量都已知后,就可以算出抛物线的轨迹了
CSS3 镂空效果实现方式有很多种,就不展开讲了。我这边使用的CSS3中的 「遮罩 + 径向渐变」
径向渐变MDN
❝background-image: radial-gradient(「shape size」 at 「position, start-color, ..., last-color」);
❞
background-image: radial-gradient(circle at 50% 0upx, transparent 200upx, white 200upx);
当相邻颜色偏移量相等时,不出现渐变情况,语法简单,不多展开。
语法与 background 相似,不展开。
-webkit-mask: radial-gradient(circle at 50rpx 0rpx, transparent 45rpx, #999999 45rpx)
「tips: 不透明色显示底色(白色),所以后面的颜色可随便填写」
到这里用到的知识点都介绍完了,接下来我们只需要设置一个位移变量控制镂空与小球位置就行了。
想要实现CSS 「transition」 丝滑的运动效果,需使用之前「requestAnimationFrame」控制每一帧位移量。
/*
* @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();
}
每次位移时,保存初始位置 「sourceLeft」 , 和计算出位移长度 「distance」 与 每帧位移的长度 「speed」。
这样就完成了丝滑的运动。
效果还不错吧
相信大家看完后能够学习或者复习到 「抛物线公式、径向渐变等」 一些常用的知识点,看完后大家也动手实现一个有意思的底部导航栏吧~
❝码字不易,看到这的话就动手点点赞吧,您每次的随手点赞都能给到我很大的动力!
❞
如果文章对你有帮助的话欢迎
「关注+点赞+收藏」