阅读原文:原文地址
一、前言
在Web开发中,轮播图(Carousel)是一种非常常见的功能,用于展示图片或内容,通过自动或手动的方式切换不同的视图,在网页设计中扮演着重要的角色。
吸引注意力:轮播图通常位于页面的显眼位置,如首页的顶部或中心区域,能够立即吸引访问者的注意力。通过展示精美、引人注目的图片或视频,轮播图能够激发访问者的兴趣,促使他们进一步探索网站的内容。
展示重要信息:轮播图是一种高效展示重要信息或促销活动的方式。商家可以在轮播图中展示最新的产品、优惠活动、重要公告等,以吸引潜在客户的注意并促进销售。
增加互动性:一些轮播图设计会包含导航按钮(如前后翻页按钮)或指示器(如小圆点),允许用户手动切换图片。这种交互性设计能够提升用户体验,让用户更加主动地参与到内容浏览中来。
节省空间:在有限的网页空间内,轮播图提供了一种有效的方式来展示多个内容项。通过自动或手动切换,轮播图能够在不占用过多页面空间的情况下,展示更多的图片或信息。
提升网站美观度:轮播图通常采用高质量的图片和动画效果,能够提升网站的整体美观度和视觉吸引力。一个设计精良的轮播图不仅可以吸引访问者的眼球,还能增加网站的专业感和可信度。
引导用户行为:轮播图有时也用作引导用户行为的工具。例如,在电商网站的轮播图中,可以放置“立即购买”、“了解更多”等按钮,直接引导用户进行购买或查看更多信息。
3D轮播图是一种通过添加3D变换效果使轮播图呈现出立体感的展示方式。它通过在轮播过程中,对图片的旋转、缩放、移动等动画效果的处理,使得图片在视觉上产生深度感,给用户一种身临其境的视觉体验。
CSS3中的transform、perspective、animation等属性是实现3D轮播图的重要工具。transform属性用于对元素进行旋转、缩放、移动或倾斜,而perspective属性则用于设置观察者与屏幕之间的距离,从而创建出3D效果。
二、实现过程及分析
2.1 基础布局代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>c.html</title>
<style type="text/css">
.carousel {
width: 100%;
position: relative;
height: 400px;
overflow: hidden;
margin-top: 2em;
}
.carousel-list {
width: 100%;
height: 100%;
position: relative;
perspective: 1000px;
}
.carousel-item {
width: 600px;
height: 100%;
position: absolute;
user-select: none;
transition: 0.4s;
left: 50%;
top: 0;
margin-left: -300px;
}
.arrow {
position: absolute;
top: 50%;
margin-top: -50px;
}
.arrow img {
width: 100px;
}
.prev {
left: 30px;
}
.next {
right: 30px;
}
</style>
</head>
<body>
<div class="carousel">
<div class="carousel-list">
<img class="carousel-item" src="./img/carousel-1.jpeg" alt="" />
<img class="carousel-item" src="./img/carousel-2.jpeg" alt="" />
<img class="carousel-item" src="./img/carousel-3.jpeg" alt="" />
<img class="carousel-item" src="./img/carousel-4.jpeg" alt="" />
<img class="carousel-item" src="./img/carousel-5.jpeg" alt="" />
<img class="carousel-item" src="./img/carousel-6.jpeg" alt="" />
<img class="carousel-item" src="./img/carousel-7.jpeg" alt="" />
</div>
<div class="prev arrow">
<img src="./img/arrow-left.png" alt="" />
</div>
<div class="next arrow">
<img src="./img/arrow.png" alt="" />
</div>
</div>
</body>
</html>
2.2 左右切换事件
获取所有的轮播图元素,声明index变量记录当前是第几张轮播图索引,在获取向左和向右的按钮,并注册事件。
// 获取所有的轮播元素
const items = document.querySelectorAll('.carousel-item');
// 当前显示的第几张轮播图
let index = 0;
function layout() {}
layout();
const prev = document.querySelector('.prev');
const next = document.querySelector('.next');
// 向左
prev.addEventListener('click', () => {
index --;
if(index < 0) {
index = 0;
}
layout();
})
// 向右
next.addEventListener('click', () => {
index ++;
if(index > items.length - 1) {
index = items.length - 1;
}
layout();
})
// 点击图片切换
items.forEach((item, i) => {
item.addEventListener('click', () => {
index = i;
layout()
})
})
2.3 实现layout函数
const items = document.querySelectorAll('.carousel-item');
// 当前显示的第几张轮播图
let index = 3;
function layout() {
// 图片之间的间隔
const xOffsetStep = 100;
// 两张轮播图之间的递减缩放倍率
const scaleStep = 0.6;
// 两张轮播图之间的透明度递减倍率
const opacityStep = 0.5;
for (let i = 0; i < items.length; i++) {
const item = items[i];
// 计算每张图片i距离当前图片index之间间隔几张
const dis = Math.abs(i - index);
// 返回1,-1,0,-0,当做一个正负号
const sign = Math.sign(i - index);
let xOffset = (i - index) * xOffsetStep;
// 每张图片的初始偏移量,解决初始偏移距离太小的问题
if (i !== index) {
// sign为正数,右边的每张图片加上100的偏移量;
// sign为负数,左边的每张图片减去100的偏移量。
xOffset = xOffset + 100 * sign;
}
// 每张图片缩放倍数
const scale = scaleStep ** dis;
// 如果是当前的不旋转,否则左边旋转45度,右边旋转-45度
const rotateY = i === index ? 0 : 45 * -sign;
item.style.transform = `translateX(${xOffset}px) scale(${scale}) rotateY(${rotateY}deg)`;
// scale同理,每张图片的透明度,越远透明度越小
const opacity = opacityStep ** dis;
item.style.opacity = opacity;
// 设置每张图片的层级,距离当前index越远的,层级越低
const zIndex = items.length - dis;
item.style.zIndex = zIndex;
}
}
解析1:
let xOffset = (i - index) * xOffsetStep;
解析2:
const dis = Math.abs(i - index);
const zIndex = items.length - dis;
item.style.zIndex = zIndex;
解析3:
const dis = Math.abs(i - index);
// 每张图片缩放倍数
const scale = scaleStep ** dis;
效果如下:
三、完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>3D渐变的轮播图效果</title>
<style type="text/css">
.carousel {
width: 100%;
position: relative;
height: 400px;
overflow: hidden;
margin-top: 2em;
}
.carousel-list {
width: 100%;
height: 100%;
position: relative;
perspective: 1000px;
}
.carousel-item {
width: 600px;
height: 100%;
position: absolute;
user-select: none;
transition: 0.4s;
left: 50%;
top: 0;
margin-left: -300px;
}
.arrow {
position: absolute;
top: 50%;
margin-top: -50px;
}
.arrow img {
width: 60px;
}
.prev {
left: 30px;
}
.next {
right: 30px;
}
</style>
</head>
<body>
<div class="carousel">
<div class="carousel-list">
<img class="carousel-item" src="./img/carousel-1.jpeg" alt="" />
<img class="carousel-item" src="./img/carousel-2.jpeg" alt="" />
<img class="carousel-item" src="./img/carousel-3.jpeg" alt="" />
<img class="carousel-item" src="./img/carousel-4.jpeg" alt="" />
<img class="carousel-item" src="./img/carousel-5.jpeg" alt="" />
<img class="carousel-item" src="./img/carousel-6.jpeg" alt="" />
<img class="carousel-item" src="./img/carousel-7.jpeg" alt="" />
</div>
<div class="prev arrow">
<img src="./img/arrow-left.png" alt="" />
</div>
<div class="next arrow">
<img src="./img/arrow.png" alt="" />
</div>
</div>
</body>
<script>
const items = document.querySelectorAll('.carousel-item');
// 当前显示的第几张轮播图
let index = 3;
function layout() {
// 图片之间的间隔
const xOffsetStep = 100;
// 两张轮播图之间的递减缩放倍率
const scaleStep = 0.6;
// 两张轮播图之间的透明度递减倍率
const opacityStep = 0.5;
for (let i = 0; i < items.length; i++) {
const item = items[i];
// 计算每张图片i距离当前图片index之间间隔几张
const dis = Math.abs(i - index);
// 返回1,-1,0,-0,当做一个正负号
const sign = Math.sign(i - index);
let xOffset = (i - index) * xOffsetStep;
// 每张图片的初始偏移量,解决初始偏移距离太小的问题
if (i !== index) {
// sign为正数,右边的每张图片加上100的偏移量;
// sign为负数,左边的每张图片减去100的偏移量。
xOffset = xOffset + 100 * sign;
}
// 每张图片缩放倍数
const scale = scaleStep ** dis;
// 如果是当前的不旋转,否则左边旋转45度,右边旋转-45度
const rotateY = i === index ? 0 : 45 * -sign;
item.style.transform = `translateX(${xOffset}px) scale(${scale}) rotateY(${rotateY}deg)`;
// scale同理,每张图片的透明度,越远透明度越小
const opacity = opacityStep ** dis;
item.style.opacity = opacity;
// 设置每张图片的层级,距离当前index越远的,层级越低
const zIndex = items.length - dis;
item.style.zIndex = zIndex;
}
}
layout();
const prev = document.querySelector('.prev');
const next = document.querySelector('.next');
prev.addEventListener('click', () => {
index--;
if (index < 0) {
index = 0;
}
layout();
})
next.addEventListener('click', () => {
index++;
if (index > items.length - 1) {
index = items.length - 1;
}
layout();
})
// 点击图片切换
items.forEach((item, i) => {
item.addEventListener('click', () => {
index = i;
layout()
})
})
</script>
</html>
四、总结
3D轮播图效果就是利用CSS3中transform属性用于对元素进行旋转、缩放、移动或倾斜,而perspective属性则用于设置观察者与屏幕之间的距离,从而创建出3D效果。
优点:
提升用户体验:3D立体轮播效果可以给用户带来沉浸式的视觉体验,增强轮播图的吸引力,提升用户对内容的关注度。
增加页面互动性:通过添加3D旋转、缩放等效果,使轮播图具有更多的动态感,增加页面的互动性和趣味性。
增强品牌形象:采用3D立体轮播效果展示产品或品牌相关的图片可以更好地突出产品特点和品牌形象,提高用户对品牌的认知和记忆度。
缺点:
在实现3D轮播图时,需要注意兼容性问题。虽然现代浏览器大多支持CSS3的3D变换效果,但仍需考虑旧版浏览器的兼容情况。
3D轮播图的动画效果可能会增加页面的加载时间和资源消耗,因此需要合理控制动画的复杂度和数量,以确保页面的流畅性和性能。
阅读原文:原文地址