制作酷炫的3D轮播图教程
前言
掘友们好!最近笔者在网上刷到一个3D
效果的轮播图,觉得挺有意思,今天跟大家分享一下实现的过程,毕竟轮播图这个玩意在很多场景都会用到,虽然每个组件库都有对应的实现,但是咱作为一名前端也不能只会用,还是得自己会写对吧!笔者实现了三个效果,最终代码只需要稍微改动即可切换成另一种效果。
效果1:
效果2:
效果3:
除了两侧的按钮点击可以切换之外,点击某张图片也可以实现切换。
阅读本文,你将学会:
使用HTML
、CSS
和 JavaScript
来实现这个精彩的 3D
轮播图,让你的网页在视觉上更加吸引人。
好了废话不多说,接下来就描述一下笔者实现的思路。
实现3D轮播图
实现思路
咱们来想一下,大致的思路:
- 要实现
3D
的效果,那么肯定要使用CSS
动画的3D
转换。 - 要有多张图片,并且一开始堆叠在一起,然后通过
translateX
设置X坐标偏移量实现向两侧扩展,通过rotateY
设置旋转角度,通过scale
设置缩放,通过opacity
设置透明度,通过z-index
设置层级(光看也许看不出来需要这些属性,但是我们可以通过把一张图片调试成这个样子就能得到)。 - 需要有一个变量(
index
)——当前激活的图片的索引。 - 要实现一个函数,用于根据当前的
index
更新图片的style
,在这个函数中计算3D
转换的相关样式。 - 给按钮绑定点击事件,调用第四点的函数即可。
- 给多张图片的父节点绑定点击事件,事件委托,点击某张图片时根据
event.target
拿到点击的哪张图片,然后还是调用第四点的函数。
然后就能实现一个大致的逻辑,如下:
// 当前显示图片的索引
let index = 0
// 多张图片
const imgs = [...document.querySelectorAll('img')]
// 实现切换逻辑
function setStyle(index) {
// 根据索引计算以下样式
// translateX 偏移量
// rotateY 旋转角度
// scale 缩放
// opacity 透明度
// z-index
}
// 图片父节点的点击
function imgContainerClick(e) {
// 点击的是图片父节点本身,直接return
if (e.currentTarget === e.target) {
return
}
const index = imgs.indexOf(e.target)
setStyle(index)
}
// 左右侧按钮点击
function btnClick(type) {
index = type === 'next' ? index + 1 : index - 1
// 判断边界
if(index < 0) return index = 0
if(index > l - 1) return index = l - 1
setStyle(index)
}
// 初始化调用一次
setStyle(index)
HTML
结构如下
style
样式如下
有了以上的样式就能水平垂直居中,而且让多张图片堆在一起,如下图:
注意: 这些非关键的样式都很简单,笔者就不过多描述了哦!
接下来就是setStyle
的实现。
如何根据 index 计算 translateX
根据观察,不难看出,当前展示的index
两侧是对称的一个结构,比如 index = 2
(偏移值为0
,因为所有图片都堆在一起,偏移值都为0
),那么index = 1
的图片,就往左侧偏移(偏移值为负数),index = 3
的图片就往右侧偏移(偏移值为正数),再加上对称,那么index = 1
的偏移值 与 index = 3
的偏移值除了符号之外相等,如下图:
那怎么动态的算这个偏移量呢?
首先,咱们先要设置一个固定的偏移量,比如200
,代表每隔一张图片,偏移量加200
。其次咱们用遍历图片的索引减去当前显示的index
,就能得到两个对称的值。比如index = 2
,它的上一张图片索引1
减去 index
= -1
;下一张图片索引 3
减去 index
= 1
;-1 和 1 就是对称的值。那么分别用这个值乘以我们固定的偏移量,就得到了 -200
和 200
。
const offsetX = 200 // 固定的偏移量
(i - index) * 200 // i 为遍历图片时的索引,index 为当前激活图片的索引
如何根据 index 计算 z-index、opacity、scale
之所以这三个放在一起,因为我们从图中不难看出,这三个属性的值也是对称的,并且index
两侧相等,没有负数(Math.abs(i - index)
),笔者是这么算的:
const OPACITY = 0.6 // 固定透明度
const SCALE = 0.8 // 固定缩放
const l = imgs.length // 图片数量
const abs = Math.abs(i - index) // 第 i 张图片与 index 的距离
const zIndex = l - abs // i === index 时 zIndex = l 最大;往两侧递减
const scale = Math.pow(SCALE, abs) // 当abs为0,scale = 1
const opacity = Math.pow(OPACITY, abs) // 当abs为0,opacity = 1
那现在就只剩下最后一个rotateY
了。
如何根据 index 计算rotateY
这个属性值的计算与translateX
类似,但是我们发现每张图片的旋转角度是一样的,没有随着距离的增大而增大,并且两侧一正一负。
const sign = Math.sign(i - index) // 返回 -1,0,1 中的一个,我们只需要符号,不需要倍率
const rotateY = abs === 0 ? 0 : sign * ROTATE
设置style
最后就是将这些属性设置到img
:
img.style = `transform: translateX(${translateX}px) rotateY(${rotateY}deg) scale(${scale});opacity: ${opacity};z-index: ${zIndex};`
到这里你就能得到效果3。
怎么得到效果2
给.carousel
添加样式perspective: 1000px;
。
关于perspective属性的说明:
怎么得到效果1
改变一下旋转的角度,比如:
const rotateY = abs === 0 ? 0 : -1 * sign * ROTATE
就能得到效果1了,更多的效果等着你去发现!
最后附上源码: 宽度太小了,展示不全。????
总结
本文通过使用HTML
、CSS
和 JavaScript
实现了 3D
轮播图的效果,分享了完整的实现思路——可能一开始并不知道我们怎么实现这些效果,可以尝试着去控制台试试,可能就有思路了。
如果本文对你有一点点帮助,点个赞支持一下吧,你的每一个【赞
】都是我创作的最大动力 ^_^
。