前言
常常使用网易云音乐,看见它的首页轮播图想自己也实现一个,本文会通过 animation 结合 perspective 等 css 属性实现3d轮播的效果。让我们开始吧!
步骤
为了简单起步我们先使用三张图片,定义基础的 html 和 css 结构如下:
- 我们设定图片的宽度 329px ,为了凸显出中间这张图片,左右两种使用
transform:scale(0.8)
,然后让两边的图片的大小缩放 0.8 我们要做的就是让图片动起来就实现了轮播的效果。 - 动起来还只是平面的移动,为了实现3d的效果,引入
transform-style
和perspective
这两个概念
接下来围绕这两点展开分析如何实现。
动起来
选用animation写动画
动起来就是动画可以通过 css animation 以及 js中的 requestAnimationFrame 这两种。我选用 animation 作为实现手段。
分析动起来的阶段
只看一张图的周期分为三个阶段也就是 左边,中间,右边
,假设我们在每个阶段都停留2s,那么整个周期需要6s的时间。为了让过渡自然些,每次过渡的时候都预留0.5s过渡时间。那么过渡时间总共要1.5s 所有时间加起来需要 7.5s
animation使用
- 使用translateX 来实现图片 x 轴位置的移动
- animation-delay 支持负值,如
animation: three-D 7.5s ease -5s infinite;
表示整个过渡时间是 7.5s 由于 animation-delay 设置为 -5s 表示已经运动来 5秒也就是来到动画的 66% 的进度了。
/* 总时长是 7.5s */
@keyframes three-D {
/* 停留2秒 */
0%,27%{
transform: translateX(230.3px) scale(0.8);
z-index: 1;
}
/* 过渡时间为 0.5s */
34%,61%{
z-index: 2;
transform: translateX(98.7px) scale(1);
}
/* 过渡时间为 0.5s */
68% ,95%{
z-index: 1;
transform: translateX(-32.9px) scale(0.8);
}
/* 过渡时间为 0.5s */
100% {
z-index: 1;
transform: translateX(230.3px) scale(0.8);
}
}
设置3d效果
给他们的图片的父级设置视角,展示方式为3d。更多属性可以参考张旭鑫 CSS3 3D文章解释
transform-style: preserve-3d;
perspective: 800px;
使用了这个属性后,我们可以在图片的 左中上
三种位置来改变他们不同的translateZ
的值来实现3d的效果,其实 translateZ
就是改变图片和用户的距离,我们通过 scale(0.8) 已经达到相同的效果,因为距离用户近也就以为这图片要大。
除了改变用户的距离,我们还自定义的添加一些属性如,图片 rotateY 的角度,来实现开屏的效果。可根据自己的业务需要来添加。
完整demo地址
层级问题
当轮播图超过3张以上,拿四张来举例,一张图的周期需要划分为四个阶段。如下图分别在这四个阶段,3,4表示在同一个位置,还是和之前一样在每个阶段停留 2s 停留总时间为 8s , 1-2,2-3,4-1需要过渡时间 0.5s 总的过渡时间为 1.5s 。最终所需时间为 9.5s 。
如果还是像三张图片时只设置了 2 的层级比其他高,那么在 3,4这个阶段会出现层级问题。由于1,3,4层级相同,那么最后一张图片的时候会一直在左边的位置会一直盖住其他图片。我采用的方式是当图片到了第四个阶段就让他的 opacity 为 0 ,那么即使最后一张图片到了第四个阶段也不会遮住上一张。
/* 总时长是 9.5s */
@keyframes three-D {
/* 停留2秒 */
0%,21%{
transform: translateX(230.3px) translateZ(40px) scale(0.8);
z-index: 3;
}
/* 过渡时间为 0.5s */
26%,47%{
z-index: 4;
transform: translateX(98.7px) scale(1);
}
/* 过渡时间为 0.5s */
51% ,73%{
z-index: 2;
opacity: 1;
transform: translateX(-32.9px) scale(0.8);
}
/* 第三阶段图片隐藏 */
74%,96%{
opacity: 0;
z-index: 1;
transform: translateX(-32.9px) scale(0.8);
}
/* 过渡时间为 0.5s */
100% {
opacity: 1;
z-index: 1;
transform: translateX(230.3px) scale(0.8);
}
}
轮播图层级问题解决demo源码
最后
通过css实现了网易云音乐轮播的效果,如果想要和轮播图有交互 会用到 animation-play-state 这个属性,如果业务有需求也可以加上。最后关于3d轮播图有好的实现方式可以在留言区评论。