你不知道的轮播图集合
相信大家在前端的学习过程中一定离不开轮播图的学习,虽说在现在这些轮播图可以通过一些插件库等其他平台快速的完成,但是轮播图作为我们刚接触不久的前端新人来说是一个比较难的一个挑战。 这里我也是学习了经典的轮播图以及一些不同于正常轮播图的轮播图,对于传统的轮播图而言,需要html css配合js完成,其中HTML和css部分相信对于大部分人来说不是上面难题,难点在于js方面的实习以及思路的拓展延申 这里我准备了三种轮播图,一种是经典的轮播图,一种时纯html和css形成的轮播图,另一种是少量js形成的轮播图,接下来我以此进行讲解。 首先放上效果图
这是一个经典的无缝轮播图
接下来是一个纯html和css生成的一个3d轮播图
最后是我们拥有少量js的全屏轮播图
以上就是今天要介绍的三种轮播图了。
首先我们进行第一仲,最常见的无缝轮播图,相信大家学会无缝轮播图后,也能根据所学知识给下面两种轮播图赋予相似的内容
首先我们进行思路方面的说明
**这三张图基本上就说明了做这种无缝轮播图的具体思路在上面,包括一些函数等,具体函数实现我们放在js部分进行讲解,首先我们看思路方面 整体来说,就是划定一个可见区域,剩下的的照片在可见区域的右侧依次浮动排开成一列,通过改变图片的margin-left值,使得不同的照片位移到可见区域的位置,同时在末尾放入最开始的那张照片,否则边无法实现无缝,给用户的体验不好,至于为什么不放剩下的照片呢,是因为没有必要,从最后一张位移到第一张的时候,用户无法感知到相应操作,所以没必要在多复制一份过来 **
目的是为了实现无缝循环的效果。当轮播图滚动到最后一张时,由于下一张是与第一张相同的图片,所以在用户的视觉感知上会形成一种无缝切换的错觉,使得轮播图看起来像是无限循环地播放下去。这样的设计可以提供更流畅和连贯的用户体验。
可以看到我们最后的效果图注释可见区域以外的地方隐藏注释掉之后的效果
众图片依次排开,位于可见区域的右侧部分,当每需要切换图的时候,marginleft值就会发生改变
整体思路大概如此,接下来我们进行详细的说明
这一块没什么好说的,一些基本的html和css的样式,再写的时候我们可以先完成html和css,然后再通过js往html里面添加内容的时候,在注释掉部分代码,比如我这里的img标签
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>无缝轮播图</title>
<link rel="stylesheet" href="./1.css" />
</head>
<body>
<div class="carousel-container">
<div class="carousel-list">
<!-- <img src="../img/1.jpg" alt="" class="carousel-item">
<img src="../img/2.jpg" alt="" class="carousel-item">
<img src="../img/3.jpg" alt="" class="carousel-item">
<img src="../img/4.png" alt="" class="carousel-item">
<img src="../img/5.jpg" alt="" class="carousel-item"> -->
</div>
<div class="indicator">
<!-- 指示器部分 -->
</div>
<div class="arrow">
<!-- 左右点击翻页部分 -->
<div class="arrow-left"></div>
<div class="arrow-right"></div>
</div>
</div>
<script src="./animate.js"></script>
<script src="./index.js"></script>
</body>
</html>
css
body{
background-image: url("../img/3.jpg");
background-size: cover;
}
.carousel-container {
width: 500px;
height: 300px;
/* 将隐藏部分注释掉之后会看到一横排的照片,通过改变margin来变更照片 */
overflow: hidden;
/* outline: 2px solid lightblue; */
margin: 0 auto;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
.carousel-list {
/* 轮播图主要是靠通过改变margin-left来改变图的,所以图片区域宽度为显示区域的700%有几张照片就翻多少+1倍 */
width: 700%;
height: 100%;
}
.carousel-item {
width: 500px;
height: 100%;
/* 图片撑满区域 */
object-fit: cover;
float: left;
}
.indicator {
/* 指示器部分,根据显示区域进行定位到下面 */
position: absolute;
width: 100%;
left: 0;
bottom: 0;
height: 30px;
text-align: center;
}
.indicator-item {
/* 指示器样式 */
display: inline-block;
width: 20px;
height: 4px;
border-radius: 5px;
background: #fff;
cursor: pointer;
margin: 0 5px;
}
.indicator-item.active {
/* 激活时的颜色 */
background: #ffa44f;
}
.arrow-left,
.arrow-right {
/* 左右翻页样式 */
position: absolute;
width: 50px;
height: 104%;
top: -1px;
background: rgba(0, 0, 0, 0.5);
cursor: pointer;
opacity: 0;
color: #fff;
}
.arrow-left:hover,
.arrow-right:hover {
/* 鼠标移入的时候将隐藏显示出来 */
opacity: 1;
}
.arrow-left {
left: 0;
}
.arrow-left::before {
content: '<';
}
.arrow-right {
right: 0;
}
.arrow-right::before {
content: '>';
}
.arrow-left::before,
.arrow-right::before {
position: absolute;
left: 0;
width: 100%;
text-align: center;
top: 50%;
height: 30px;
line-height: 30px;
margin-top: -15px;
}
以上是基本的样式设置,接下来我们进行js部分的书写
第一部分 重置样式
这一部分我们主要对样式进行重构,在之前的html和css中,我们使用了静态创建了样式,但是,我们应该在js中动态的创建样式,以便我们后续更好的维护添加修改
js
function $(selector) {
return document.querySelector(selector);
//在这里封装了一个函数,用以方便获取dom
}
// 初始化
var curIndex = 0; // 当前显示的是第几张图片,以便后续指示器和切换图片的操作
var doms = {
container: $('.carousel-container'),
carouselList: $('.carousel-list'),
indicator: $('.indicator'),
arrowLeft: $('.arrow-left'),
arrowRight: $('.arrow-right'),
//这里获取了整体所需要的一些dom
};
var containerWidth = doms.container.clientWidth; // 容器可见区域的宽度
var urls = [
'../img/1.jpg',
'../img/2.jpg',
'../img/3.jpg',
'../img/4.png',
'../img/5.jpg',
'../img/6.jpg',
]; //用数组记录了要显示的所有轮播图的图片路径,后续用循环往项目里添加图片
//这里便是初始化函数
function init() {
function _img(url) {
//在这里,我们动态的创建了img元素,并且成功的添加到html中,同时设置了img元素需要的相关信息,并且完成相关css样式的设置
const img = document.createElement('img')
img.src = url
img.className = "carousel-item"
doms.carouselList.appendChild(img)
}
//这里根据照片数组的数量进行创建指示器
for (var i = 0; i < urls.length; i++) {
_img(urls[i])
// 创建指示器
var div = document.createElement('div');
div.className = 'indicator-item';
doms.indicator.appendChild(div);
}
_img(urls[0]) //这里单独添加一个照片,就是我们最后一张和第一站张重复的那个,以便提升用户的感知度
// 重新设置容器宽度
//这里根据照片的大小重新设置容器的大小,避免因照片设置不当导致超出容器
doms.carouselList.style.width = doms.carouselList.children.length + '00%';
setActive(),重新再设置激活样式
}
init()
function setActive() {
//这里对指示器进行设置和处理操作
/**
* 根据curIndex来做判断
* 1取消已经激活的样式
* 2设置当前激活样式
*/
//取消
var active = $(".indicator-item.active")
//在这里获取到已经设计了激活样式的指示器
if (active) {
//当存在的时候给她取消掉
active.className = "indicator-item"
}
// // 2. 激活当前的指示器
var index = curIndex;
if (index > urls.length - 1) {
//当进行到最后一张照片的时候,在切换的时候将索引设置为0,不然会出错
index = 0;
}
// 这里对多加入的那一张图片进行的指示器样式的处理,以本项目为例
//有7张图片,当图片进行<=6的时候没有问题,当进行第七章的时候,指示器只有六个,无法激活第七个样式
//所以用这种办法,1%7=1,2%7=2 .......当进行到7的时候 7%7=0就又会重新激活第一个指示器
var index = curIndex % urls.length;
//设置激活样式
doms.indicator.children[index].className = 'indicator-item active';
}
发生在这个阶段,马上要跳到最后那张和第一张重复i的照片时,将索引设置为最初的0
这里提供两个个辅助函数,一个用以设定动画的处理,另一个用以节流防抖处理
javascript
function createAnimation(options) {
// createAnimation 函数用于创建动画效果,接受一个参数 options,其中包含了动画的起始值 from、
//结束值 to、变化的总时间 totalMS 和动画间隔时间 duration。函数通过计算得出每一次变化改变的值
//dis,然后使用定时器不断改变起始值 from,直到变化的次数达到设定值 times,最后触发 options.onmove
//和 options.onend。
var from = options.from; // 起始值
var to = options.to; // 结束值
var totalMS = options.totalMS || 1000; // 变化总时间
var duration = options.duration || 15; // 动画间隔时间
var times = Math.floor(totalMS / duration); // 变化的次数
var dis = (to - from) / times; // 每一次变化改变的值
var curTimes = 0; // 当前变化的次数
var timerId = setInterval(function () {
from += dis;
curTimes++; // 当前变化增加一次
if (curTimes >= times) {
// 变化的次数达到了
from = to; // 变化完成了
clearInterval(timerId); // 不再变化了
options.onmove && options.onmove(from);
options.onend && options.onend();
return;
}
// 无数的可能性
options.onmove && options.onmove(from);
}, duration);
}
// 防抖函数 做节流处理
const debounce = (fn, time = 1000) => {
let timer
return (...arges) => {
clearTimeout(timer)
timer = setTimeout(() => {
fn(...arges)
}, time)
}
}
下面进行切换照片的操作,重难点在这里,需要结合上述的动画函数一起用
javascript
var totalMS = 300;
var isPlaying = false; // 是否有正在进行的切换动画
/**
* 将轮播图从当前的位置,切换到newIndex位置
* @param {*} newIndex 新的位置的图片索引
* @param time 所需要的变换时间
*/
function moveTo(newIndex, onend) {
if (isPlaying || newIndex === curIndex) {
return; // 有动画进行 或 切换目标和当前一致,不做任何事情不然如果从第一张切换到第一张虽然没有变化但是仍然会进行处理
}
isPlaying = true; //标记动画在进行中
// 获取margin值并且转换为浮点数类型
var from = parseFloat(doms.carouselList.style.marginLeft) || 0; //这里精确计算了需要margin-left值,如果没有则代表在第一张的位置,设置为0
// 算出下一个图片的margi值
var to = -newIndex * containerWidth;//通过算出下一个margi值,通过下面的动画函数实现照片的变更
createAnimation({
from: from, //从当前位置
to: to, //到下一个位置
totalMS: totalMS,//经过几秒
onmove: function (n) {
//切换图片函数 //重新设置marginleft值,完成改变
doms.carouselList.style.marginLeft = n + 'px';
},
onend: function () {
//结束后将表示正在进行的动画设置为否
isPlaying = false;
//动画完成后调用这个onend函数
onend && onend();
},
});
curIndex = newIndex;
// 更改当前显示的图片索引
setActive()
}
这里通过控制台看到margin的变化
接下来我们注册点击事件
这里我们开始注册点击事件,指示器和左右切换上下一页的点击事件
js
//注册点击事件,这里根据indicator中子元素的数量添加指示器的点击事件
for (let i = 0; i < doms.indicator.children.length; i++) {
doms.indicator.children[i].onclick = function () {
moveTo(i); //调用moveto函数传入索引,实现点击哪个索引跳转到那一页
}
}
function next() {
// 切换到下一张
var newIndex = curIndex + 1
var onend;
if (newIndex === doms.carouselList.children.length - 1) {
// 切换到最后一张图片了
// 等动画完成后,要回到第一张图片
onend = function () {
doms.carouselList.style.marginLeft = 0;
curIndex = 0;
};
}
moveTo(newIndex, onend);
}
function prev() {
// 切换到上一张图
var newIndex = curIndex - 1;
if (newIndex < 0) {
// 当进行到小于0的时候跳转到倒数第二张
var maxIndex = doms.carouselList.children.length - 1;
// 计算出来倒数第二张的margin值,并且设置
doms.carouselList.style.marginLeft = -maxIndex * containerWidth + 'px';
// 将新的页码设置为倒数第二张的页码
newIndex = maxIndex - 1;
}
// 跳转到
moveTo(newIndex);
}
// 注册左右点击按钮
//这里调用了之前另一个辅助函数,debounce防抖函数,实现节流,避免快速点击切换造成的不必要的浪费
doms.arrowLeft.onclick = debounce(prev,200) ;
doms.arrowRight.onclick = debounce(next,200);
到这里基本上就完成了大部分了,剩下的就是实现自动切换效果
var
var timerId; //计数器,避免出现重复操作,与上述防抖有类似功能
function autoStart() {
if (timerId) {
// 已经有自动切换在进行了
return;
}
//隔一段时间执行next函数
timerId = setInterval(next, duration);
}
function autoStop() {
//停止执行
clearInterval(timerId);
timerId = null;
}
autoStart(); // 最开始自动切换
//当鼠标移入时停止自动切换,移除时加入自动切换
doms.container.onmouseenter = autoStop;
doms.container.onmouseleave = autoStart;
至此,我们完成了常见的无缝轮播图的小项目
再放上效果图
接下来是纯html和css的3d轮播图
初始化样式
ini
<div class="container">
<div class="box">
<div class="card">
<img src="../img/1.jpg" alt="">
</div>
<div class="card">
<img src="../img/2.jpg" alt="">
</div>
<div class="card">
<img src="../img/4.png" alt="">
</div>
<div class="card">
<img src="../img/5.jpg" alt="">
</div>
<div class="card">
<img src="../img/6.jpg" alt="">
</div>
</div>
</div>
</div>
css
* {
/*清除默认样式 */
margin: 0;
padding: 0;
}
body {
/* 进行整体的样式设置,高度为整个视口,设置为弹性盒居中*/
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
/* 这里设计背景图片,先暂时隐藏方便看效果*/
/* background-image: url("../img/3.jpg"); */
overflow: hidden;
/*设置照覆盖为cover形式*/
background-size: cover;
}
.container {
/* 设置整个容器的样式*/
background: red;
width: 600px;
height: 350px;
margin-top: 60px;
/*这里进行定位*/
position: relative;
perspective: 1000px;
/* "perspective: 1000px;" 是一段CSS样式代码,它用于定义3D转换元素的透视视图(perspective view)。通过指定透视视图的大小,可以影响元素在3D空间中的视觉感知。具体而言,这段代码将透视视图的大小设置为1000像素。*/
z-index: 1;
}
.box {
/* 这里是对照片的容器进行一个设置*/
background: blue;
width: 100%;
height: 100%;
/* 启用3d模式 它用于定义一个2D或3D转换,此处是对元素进行平移变换。具体来说,它将元素在Y轴方向上平移0个单位,同时在Z轴方向上平移-700个像素单位。这段代码的效果是将元素在3D空间中向后平移700个像素,使其产生远离观察者的效果。*/
transform-style: preserve-3d;
transform: translateY(0) translateZ(-700px);
/* 后续的动画函数*/
animation: action 10s cubic-bezier(0.77, 0, 0.125, 1) infinite;
z-index: 1;
}
.card {
/* 设置卡片的样式*/
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
.card img {
width: 100%;
height: 100%;
border-radius: 25px;
z-index: 1;
}
我们这里进行了初始化设置,所有照片叠加在了一起,暂时还无法看到布局照片
这里设置了每个卡片的位置样式,因为前面已经开启了3d样式,所以这里通过nth-child选择器选中对应的照片进行位置的设置
css
.card:nth-child(1) {
transform: rotateY(0) translateZ(700px);
}
.card:nth-child(2) {
transform: rotateY(72deg) translateZ(700px);
}
.card:nth-child(3) {
transform: rotateY(144deg) translateZ(700px);
}
.card:nth-child(4) {
transform: rotateY(216deg) translateZ(700px);
}
.card:nth-child(5) {
transform: rotateY(296deg) translateZ(700px);
}
效果:
接下来进行动画的设置
注意这里动画设置要应用到外层box容器上,针对box容器进行的旋转,从而带动周围的图片进行旋转
css
@keyframes action {
0% {
transform: translateZ(-700px) rotateY(0);
}
20% {
transform: translateZ(-700px) rotateY(-72deg);
}
40% {
transform: translateZ(-700px) rotateY(-144deg);
}
60% {
transform: translateZ(-700px) rotateY(-216deg);
}
80% {
transform: translateZ(-700px) rotateY(-296deg);
}
100% {
transform: translateZ(-700px) rotateY(-360deg);
}
}
仔细看里面的的盒子,我在前面设置了背景颜色,方便大家观看
接下来不全html,并且在内部加入一个魔方旋转,显得更为亲和一点
css
/* 新增代码 */
.cube-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* 增加一层包裹魔方的容器 */
.cube-wrapper {
width: 200px;
height: 200px;
perspective: 1000px;
transform: translateY(32px);
z-index: -1;
}
.cube {
width: 100%;
height: 100%;
transform-style: preserve-3d;
animation: rotate 5s infinite linear;
}
.face {
position: absolute;
width: 200px;
height: 200px;
background-color: rgba(255, 255, 255, 0.8);
border: 1px solid #333;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
}
.front {
background-image: url("../img/1.jpg");
overflow: hidden;
background-size: cover;
transform: translateZ(100px);
}
.back {
background-image: url("../img/2.jpg");
overflow: hidden;
background-size: cover;
transform: rotateY(180deg) translateZ(100px);
}
.right {
background-image: url("../img/4.png");
overflow: hidden;
background-size: cover;
transform: rotateY(90deg) translateZ(100px);
}
.left {
background-image: url("../img/5.jpg");
overflow: hidden;
background-size: cover;
transform: rotateY(-90deg) translateZ(100px);
}
.top {
background-image: url("../img/6.jpg");
overflow: hidden;
background-size: cover;
transform: rotateX(90deg) translateZ(100px);
}
.bottom {
background-image: url("../img/3.jpg");
overflow: hidden;
background-size: cover;
transform: rotateX(-90deg) translateZ(100px);
}
@keyframes rotate {
0% {
transform: rotateX(0deg) rotateY(0deg);
}
100% {
transform: rotateX(360deg) rotateY(360deg);
}
}
ini
<body>
<div class="container">
<div class="box">
<div class="card">
<img src="../img/1.jpg" alt="">
</div>
<div class="card">
<img src="../img/2.jpg" alt="">
</div>
<div class="card">
<img src="../img/4.png" alt="">
</div>
<div class="card">
<img src="../img/5.jpg" alt="">
</div>
<div class="card">
<img src="../img/6.jpg" alt="">
</div>
</div>
</div>
<div class="cube-container">
<div class="cube-wrapper">
<div class="cube">
<div class="face front"></div>
<div class="face back"></div>
<div class="face right"></div>
<div class="face left"></div>
<div class="face top"></div>
<div class="face bottom"></div>
</div>
</div>
</div>
至此完成整个3d轮播图的项目
效果:
接下来是最后一个,全屏轮播图
进行初始化设置
js
<div class="container">
<div class="slide">
<div class="item" style="background-image: url('../img/1.jpg');"></div>
<div class="item" style="background-image: url('../img/3.jpg');"></div>
<div class="item" style="background-image: url('../img/2.jpg');"></div>
<div class="item" style="background-image: url('../img/4.png');"></div>
<div class="item" style="background-image: url('../img/5.jpg');"></div>
<div class="item" style="background-image: url('../img/6.jpg');"></div>
</div>
<div class="button">
<div class="left">上一张</div>
<div class="cnt">下载</div>
<div class="right">下一张</div>
</div>
</div>
js
<style>
* {
/* 清楚默认样式*/
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
/* 设置整体容器*/
width: 100vw; /* 注意这里的宽度和高度一个vw一个vh,会根据窗口进行自动变更vw vh单位可以根据窗口的宽度自动改变大小*/
height: 100vh;
position: relative;
overflow: hidden;
background: linear-gradient(200deg, rgba(224, 192, 255, 0.451), #918ef9);
}
.item {
/* 设置卡片区域*/
width: 240px;
height: 160px;
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
border-radius: 10px;
background-color: pink;
/* 过度铺满 */
background-size: cover;
background-position: center;
transition: 1s;
}
</style>
下面进行图片位置的设置和如何全屏展示的设置
单独拿出来说一下这里,这个项目整体思路就是改变图片在数组中的位置,在数组中第一张和第二章都是处于全屏播放的状态,通过改变其他图片在数组中的位置,从而实现叠加显示,比如一开始就是第一张在下面,第二章在上面进行全屏显示,切换到下一张的时候,第二张会取代之前第一张的位置,之前第二章的位置被将要切换的第三张位置取代,而最开始的第一张则变为图片数组中的最后一位。依次类推,从而形成全面播放的效果
css
.item:nth-child(1),
.item:nth-child(2) {
/* 通过后续的js将不同的照片放到首位和第二位,从而实现更换照片的时候选中第一张和第二章
第一张放在下面当背景图片,第二章放在上面当全屏图片,通过两个图片叠加可以在更换图的时候显得自然 */
left: 0;
top: 0;
width: 100%;
height: 100%;
transform: translateY(0);
box-shadow: none;
border-radius: 0;
/* 第一张和第二章图片是为了铺满屏幕 */
}
补全:
css
/* 这里设置所有图片一律靠右排列开来*/
.item:nth-child(3) {
left: 65%;
}
.item:nth-child(4) {
left: calc(65% + 245px);
}
.item:nth-child(5) {
left: calc(65% + 490px);
}
.item:nth-child(6) {
/* 超出屏幕区域的暂时隐藏起来*/
left: calc(65% + 685px);
opacity: 0;
}
.item {
/* 设置阴影效果*/
box-shadow: 0 30px 50px #505050;
}
在设置一下按钮
js
.button {
width: 100%;
position: absolute;
bottom: 50px;
text-align: center;
display: flex;
justify-content: center;
}
.button div {
width: 120px;
height: 50px;
line-height: 50px;
text-align: center;
border-radius: 5px;
margin: 0 25px;
transition: .5s;
cursor: pointer;
user-select: none;
font-size: 20px;
color: #fff;
background-color: rgba(0, 0, 0, 0.4);
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.2);
}
至此,样式处理已经完毕,接下来针对按钮进行注册事件完成点击交互
js
<script>
// 防抖函数 做节流处理
const debounce = (fn, time = 1000) => {
let timer
return (...arges) => {
clearTimeout(timer)
timer = setTimeout(() => {
fn(...arges)
}, time)
}
}
//获取dom
const leftBtn = document.querySelector(".button .left")
const rightBtn = document.querySelector(".button .right")
const slide = document.querySelector(".slide")
//注册点击事件
function lfBtn(){
//获取所有的item,形成一个数组
const items = document.querySelectorAll(".item")
//prepend函数,将数组中最后一个元素添加到开头位置
slide.prepend(items[items.length - 1])
}
function rgBtn(){
//获取所有的item,形成一个数组
const items = document.querySelectorAll(".item")
// 将数组中第一个添加到slide之中,从而形成将下一张图片放到全屏的位置
slide.appendChild(items[0])
}
leftBtn.addEventListener("click", debounce(lfBtn, 300))
rightBtn.addEventListener("click", debounce(rgBtn, 300))
</script>
效果:注意右侧控制台img路径的变化
至此至此,完成了全部的三种轮播图
总结:大家掌握第一种即可,剩下两种当兴趣看看就行
针对上述三种轮播图,最常见的就是无缝轮播图,虽然现在无缝轮播图都可以通过一些第三方库进行快速搭建,但是针对初学者,去学习并了解搭建方式和核心思路是十分有必要的,其最主要的就是通过改变margin值来实现无缝轮播(具体可以见第一幕的描写)
第二中是针对html和css搭建出来的3d轮播图,仅作为观赏使用,暂时并没有添加什么交互,如有兴趣大家可以去试一下进行添加
第三种的全屏轮播图是我最喜欢的一种,当然也可以不是全屏的,通过html css和一些简单的js组成,核心思路是通过改变图片在图片数组的首尾位置,通过对首位位置进行样式设置,从而实现出来效果,如有兴趣大家也可以添加自动播放或者其他交互效果 针对第一种出来的两个辅助函数,如果有不明白的,后续会出一个详细的函数说明。。。。。
至此完成本文
已上传git gitee.com/wu-canhua/r...