【动效实现】超酷炫的 3D 视差 Hover 效果

今天在看周刊的时候发现一个有趣的动画库 Atroposjs[1],它可以实现非常酷炫的 3D parallax hover effects(以前锤子官网首页 Banner 的同款效果)。先看实现效果:

这样的小动画往往会让人眼前一亮,忍不住多体验几次,产品曝光度就上来了。

Atroposjs[2] 代码很简洁,仅有 2KB, 零依赖还支持很多定制化配置。如果仅需要实现最基础的 3D 视差悬停效果,仅需几十行代码。

这篇文章,我们将来开发一个最基础的实现,完整代码可以看下面的【码上掘金】 或者我的 Codepen[3]

c6b1fe5a4c2be0ab76650114266bd474.png

整体上这个动效分为两个部分,第一部分是鼠标 Hover 到卡片上时,卡片需要感知鼠标的位置,并做出相应的倾斜;第二部分是视差(Parallax) 效果,卡片内的元素根据”远近“的不同,移动速率不一样,以产生层次感。

Hover Effect 🖱

当鼠标在卡片上移动时,卡片会发生的形变。以卡片中心为远点将卡片划分为四个象限,结合 rotateXrotateY 的方向可以得到在各个象限的旋转符号。

rotateX, rotateY 的旋转角度(越来越大)

rotateX,rotateY 要看出 3D 效果,和 perspective 属性相关,它是用来设置观察者和 z=0 平面的距离的。处于 z > 0 位置的物体会比正常看起来更大,处于 z < 0 位置的物体回避正常看起来小。

在第一象限,rotateX,rotateY 都是正数;第二象限 rotateX 是正数,rotateY 是负数,第三象限...

outside_default.png
image.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));
}
复制代码

得到效果:

outside_default.png
屏幕录制2022-07-31 上午10.20.56.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);
复制代码

总结 📚

最后将两个部分合并在一起就可以得到酷炫吊炸天的效果了,在没动手实践过之前觉得这个效果很难,无从下手。梳理完之后核心只有寥寥数行代码。

文章中我只贴出核心代码,完整实现可以看下面的【码上掘金】 或者我的 Codepen[4]。如果你觉得这个实现还不错的话,欢迎点赞 ❤️ + 评论 + 收藏 + 关注~

文章中用到的素材都来自 Atroposjs[5] 官网,这个库还贴心地提供了 Vue/React/Svelte 的示例,感兴趣的盆友可以看看。

b7c0428ce352ed7458b28bdf4bc32621.png

关于本文

作者:FESKY

https://juejin.cn/post/7126369893930237989

最后

欢迎关注【前端瓶子君】✿✿ヽ(°▽°)ノ✿

回复「算法」,加入前端编程源码算法群,每日一道面试题(工作日),第二天瓶子君都会很认真的解答哟!

回复「交流」,吹吹水、聊聊技术、吐吐槽!

回复「阅读」,每日刷刷高质量好文!

如果这篇文章对你有帮助,「在看」是最大的支持

 》》面试官也在看的算法资料《《

“在看和转发”就是最大的支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值