今天在看周刊的时候发现一个有趣的动画库 Atroposjs,它可以实现非常酷炫的 3D parallax hover effects(以前锤子官网首页 Banner 的同款效果)。先看实现效果:
这样的小动画往往会让人眼前一亮,忍不住多体验几次,产品曝光度就上来了。
Atroposjs 代码很简洁,仅有 2KB, 零依赖还支持很多定制化配置。如果仅需要实现最基础的 3D 视差悬停效果,仅需几十行代码。
这篇文章,我们将来开发一个最基础的实现,完整代码可以看下面的【码上掘金】 或者我的 Codepen
整体上这个动效分为两个部分,第一部分是鼠标 Hover 到卡片上时,卡片需要感知鼠标的位置,并做出相应的倾斜;第二部分是视差(Parallax) 效果,卡片内的元素根据”远近“的不同,移动速率不一样,以产生层次感。
Hover Effect 🖱
当鼠标在卡片上移动时,卡片会发生的形变。以卡片中心为远点将卡片划分为四个象限,结合 rotateX
和 rotateY
的方向可以得到在各个象限的旋转符号。
![](https://i-blog.csdnimg.cn/blog_migrate/93dd5cc4fbc7c974529b5106b6bdd2d2.gif)
rotateX
, rotateY
的旋转角度(越来越大)
rotateX,rotateY 要看出 3D 效果,和
perspective
属性相关,它是用来设置观察者和 z=0 平面的距离的。处于 z > 0 位置的物体会比正常看起来更大,处于 z < 0 位置的物体回避正常看起来小。
在第一象限,rotateX
,rotateY
都是正数;第二象限 rotateX
是正数,rotateY
是负数,第三象限…
![](https://i-blog.csdnimg.cn/blog_migrate/4e5cb77141701caa13b7a9803d8c6e5e.webp?x-image-process=image/format,png)
鼠标距离原点越近,卡片倾斜角度越小,距离越远,倾斜角度越大,如果单看 X 轴或 Y 轴,这个关系是线性的。还有一个特点是,鼠标纵方向移动时需要旋转 X 轴,横向移动时,旋转的是 Y 轴。分析完毕之后就可以开始写代码了。
// mousemove 事件
// 最大旋转角度
const maxRotate = 20
// 原点位置
const centerX = width / 2;
const centerY = height / 2;
// 鼠标位置相对卡片左上角的坐标
const offsetX = clientX - left
const offsetY = clientY - top
// 将和原点的距离线性折算成旋转角度
// 📢 X 方向移动旋转 Y 轴,Y 方向移动旋转 X 轴
let rotateX = (maxRotate * (offsetY - centerY)) / (centerY) * -1;
let rotateY = (maxRotate * (offsetX - centerX)) / (centerX);
// 设置 CSS Variables
this.style.setProperty('--rotateX', rotateX);
this.style.setProperty('--rotateY', rotateY);
接着将旋转角度应用到卡片上。
.parallax-rotator {position: relative;transition: 300ms ease-out;transform: rotateX(calc(var(--rotateX) * 1deg)) rotateY(calc(var(--rotateY) * 1deg));
}
得到效果:
![](https://i-blog.csdnimg.cn/blog_migrate/3f216a767b2b3ea2a4f67be4930b4ada.gif)
简简单单地几行代码就可以实现这么惊艳的效果,🐂 🍺!
Parallax Effect 😲
视差效果其实就是在 2D 的平面上,利用不同元素位置变化的速度不同,来模拟肉眼对物理世界远近感知的差异。观察者位移,距离近的物体位置变化大,而距离远的物体位置的变化小。
回到卡片上,我们将多张图片分层叠加在一起,给它们分别设置远近系数。
<img src="./images/bg.svg" style="--parallaxOffset: -4.5" />
<img src="./images/mountains.svg" style="--parallaxOffset: -2.5" />
<img src="./images/forest-back.svg" style="--parallaxOffset: 0" />
<img src="./images/forest-mid.svg" style="--parallaxOffset: 2" />
<img src="./images/forest-front.svg" style="--parallaxOffset: 4" />
在鼠标移动时,通过远近系数控制物体的偏移,这里可以复用上面的 --rotateX
和 --rotateY
,计算出偏移量。需要注意旋转 Y 轴的时候需要 X 方向偏移,旋转 X 轴的时候需要 Y 方向偏移~
transform: translate3d(calc(var(--parallaxOffset) * var(--rotateY) / var(--maxRotate) * 1%),calc(var(--parallaxOffset) * var(--rotateX) / var(--maxRotate) * -1%), 0);
![](https://i-blog.csdnimg.cn/blog_migrate/c60e395d5359a772d349ec5d160f7f80.gif)
总结 📚
最后将两个部分合并在一起就可以得到酷炫吊炸天的效果了,在没动手实践过之前觉得这个效果很难,无从下手。梳理完之后核心只有寥寥数行代码。
最后
最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。
有需要的小伙伴,可以点击下方卡片领取,无偿分享