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

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

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

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

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

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

Hover Effect 🖱

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

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

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

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

鼠标距离原点越近,卡片倾斜角度越小,距离越远,倾斜角度越大,如果单看 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));
} 

得到效果:

简简单单地几行代码就可以实现这么惊艳的效果,🐂 🍺!

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); 

总结 📚

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

最后

最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现Unity3D视差Shader的一般步骤如下: 1. 在ShaderLab中创建一个新的shader,并指定渲染队列。 2. 在CG程序中编写实现视差效果的代码。通常,这涉及到计算纹理坐标的偏移量,根据深度信息计算出位移量。最终,将位移量添加到纹理坐标中,使纹理随着深度变化而产生位移。 下面是一个简单的视差Shader代码示例: Shader "Custom/Parallax" { Properties { _MainTex ("Texture", 2D) = "white" {} _BumpMap ("BumpMap", 2D) = "bump" {} _Parallax ("Parallax", Range(0, 1)) = 0.02 } SubShader { Tags {"Queue"="Transparent" "RenderType"="Opaque"} Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; float2 texcoord : TEXCOORD0; }; struct v2f { float2 texcoord : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; sampler2D _BumpMap; float _Parallax; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = v.texcoord; return o; } fixed4 frag (v2f i) : SV_Target { float2 uv = i.texcoord; float depth = tex2D(_BumpMap, uv).r; float2 offset = normalize(i.vertex.xy / i.vertex.w - i.texcoord) * depth * _Parallax; uv += offset; return tex2D(_MainTex, uv); } ENDCG } } FallBack "Diffuse" } 这个Shader使用了一张主纹理和一张法线贴图,同时增加了一个Parallax参数。在片段着色器中,使用法线贴图中的深度信息计算位移量,并将其添加到纹理坐标中,产生视差效果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值