1. Efeitos de rolagem contínua sem costura
1. O princípio da rolagem contínua contínua
Por exemplo, existem 6 fotos, o pedido é 0~5
Em seguida, costure as mesmas 0 ~ 5 fotos na parte de trás para rolar
Quando a 0ª imagem do segundo grupo de imagens é movida para o lado esquerdo da área de rolagem (ou seja, o primeiro grupo de imagens foi movido), a imagem pode ser movida do início imediatamente.
2. Implementação de código de rolagem contínua contínua
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 1000px;
height: 130px;
border: 1px solid #000;
margin: 50px auto;
overflow: hidden;
}
.box ul {
list-style: none;
/* 设置大一点,这样li才能浮动 */
width: 5000px;
position: relative;
}
.box ul li {
float: left;
margin-right: 10px;
}
</style>
</head>
<body>
<div id="box" class="box">
<ul id="list">
<li><img src="images/number/0.png" alt=""></li>
<li><img src="images/number/1.png" alt=""></li>
<li><img src="images/number/2.png" alt=""></li>
<li><img src="images/number/3.png" alt=""></li>
<li><img src="images/number/4.png" alt=""></li>
<li><img src="images/number/5.png" alt=""></li>
</ul>
</div>
<script>
var box = document.getElementById('box');
var list = document.getElementById('list');
// 复制多一遍所有的li
list.innerHTML += list.innerHTML;
// 全局变量,表示当前list的left值
var left = 0;
// 定时器,全局变量
var timer;
move();
// 动画封装成函数
function move() {
// 设表先关,防止动画积累
clearInterval(timer);
timer = setInterval(function () {
left -= 4;
// 每张图宽200px,加上缝隙为1260px
if (left <= - 1260) {
left = 0;
}
list.style.left = left + 'px';
}, 20);
}
// 鼠标进入停止定时器
box.onmouseenter = function () {
clearInterval(timer);
};
// 鼠标离开继续定时器
box.onmouseleave = function () {
move();
};
</script>
</body>
</html>
复制代码
2. O efeito especial do carrossel de letreiros
2-1. Princípio de implementação e precauções
Assumindo que 5 imagens devem ser giradas, clique com o botão direito para reproduzir a próxima imagem e clique com o botão esquerdo para reproduzir a imagem anterior.
2-1-1. Carrossel de layout, clique no botão direito para mudar para a próxima imagem
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.carousel {
width: 650px;
height: 360px;
border: 1px solid #000;
margin: 50px auto;
position: relative;
overflow: hidden;
}
.carousel ul {
list-style: none;
width: 6000px;
position: relative;
left: 0px;
transition: left .5s ease 0s;
}
.carousel ul li {
float: left;
}
.carousel .leftbtn {
position: absolute;
left: 20px;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
background-color: rgb(226, 68, 28);
border-radius: 50%;
}
.carousel .rightbtn {
position: absolute;
right: 20px;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
background-color: rgb(226, 68, 28);
border-radius: 50%;
}
</style>
</head>
<body>
<div class="carousel">
<ul id="list">
<li><img src="images/beijing/0.jpg" alt=""></li>
<li><img src="images/beijing/1.jpg" alt=""></li>
<li><img src="images/beijing/2.jpg" alt=""></li>
<li><img src="images/beijing/3.jpg" alt=""></li>
<li><img src="images/beijing/4.jpg" alt=""></li>
</ul>
<!-- href写成空的javascript以防止页面刷新 -->
<a href="javascript:;" class="leftbtn" id="leftbtn"></a>
<a href="javascript:;" class="rightbtn" id="rightbtn"></a>
</div>
<script>
// 得到按钮和ul,ul整体进行运动
var leftbtn = document.getElementById('leftbtn');
var rightbtn = document.getElementById('rightbtn');
var list = document.getElementById('list');
var idx = 0; // 表示此时处于第几张图
rightbtn.onclick = function () {
idx++; // 点击一次图片序号+1
list.style.left = -idx * 650 + 'px'; // 表示向左移动的位置,每张图宽度为650
}
</script>
</body>
</html>
复制代码
- Deve-se notar que cada imagem é organizada de forma flutuante, e a largura ul deve ser grande o suficiente para organizar o li
- Podemos adicionar um efeito de transição à propriedade left de ul para torná-lo mais suave ao mover
Neste ponto, descobriremos que, quando continuamos a clicar, clique com o botão direito novamente após girar para a quinta imagem e a imagem fica em branco, então como podemos implementar a rotação para a última imagem e começar da primeira imagem E o carrossel?
2-1-2. Perceba o efeito carrossel de conectar a última imagem e a primeira imagem
Princípio de implementação:
- Anexe um clone da primeira foto ao verso da última foto, para que depois de girar para a última foto, clique novamente para ver a primeira foto
- Para se tornar a segunda imagem quando o botão for clicado novamente, podemos definir rapidamente a esquerda do elemento ul para 0 depois de passar para a imagem clonada
- Aqui adicionamos uma animação de transição ao ul, e a duração da animação é de 0,5s, então temos que esperar a duração da animação para definir rapidamente a esquerda do ul para 0
- Quando a esquerda de ul é rapidamente definida como 0, ela não precisa ser percebida a olho nu, portanto, o efeito de transição deve ser removido aqui.
// 得到按钮和ul,ul整体进行运动
var leftbtn = document.getElementById('leftbtn');
var rightbtn = document.getElementById('rightbtn');
var list = document.getElementById('list');
// 克隆第一张图片,追加到后面
var cloneli = list.firstElementChild.cloneNode(true);
list.appendChild(cloneli);
var idx = 0; // 表示此时处于第几张图
rightbtn.onclick = function () {
// 为了防止重置ul时将transition置为了'none',这里还原一下
list.style.transition = 'left .5s ease 0s';
idx++; // 点击一次图片序号+1
if (idx > 4) {
// 在动画时长过后将ul快速重置回去
setTimeout(function () {
list.style.transition = 'none';
list.style.left = 0;
idx = 0;
}, 500);
}
list.style.left = -idx * 650 + 'px'; // 表示向左移动的位置,每张图宽度为650
}
复制代码
2-1-3. Otimização: adicione uma trava do acelerador para evitar a reprodução anormal da imagem do carrossel quando clicada rapidamente
Como a animação de transição reproduzida pelo carrossel aqui é de 500 milissegundos, podemos definir um bloqueio do acelerador
var idx = 0; // 表示此时处于第几张图
var lock = true;
rightbtn.onclick = function () {
if (!lock) { return }
lock = false; // 锁住
// 为了防止重置ul时将transition置为了'none',这里还原一下
list.style.transition = 'left .5s ease 0s';
idx++; // 点击一次图片序号+1
if (idx > 4) {
// 在动画时长过后将ul快速重置回去
setTimeout(function () {
list.style.transition = 'none';
list.style.left = 0;
idx = 0;
}, 500);
}
list.style.left = -idx * 650 + 'px'; // 表示向左移动的位置,每张图宽度为650
setTimeout(function () {
lock = true;
}, 500);
}
复制代码
2-1-4. Clique no botão esquerdo para alternar para o carrossel anterior
- Se já for a primeira imagem do carrossel, clique no botão esquerdo para mudar para a última imagem, então você precisa mover instantaneamente para a imagem clonada emendada para trás (remover o efeito de transição); em seguida, adicione o efeito de transição superior para O carrossel se move para a última imagem real
- Se não for a primeira imagem do carrossel, então idx -- mova normalmente
leftbtn.onclick = function () {
if (!lock) return;
lock = false;
// 判断是不是第0张,如果是,就要瞬间用假的替换真的
if (idx == 0) {
// 取消掉过渡,因为要的是瞬间移动,不是“咕噜”过去
list.style.transition = 'none';
// 直接瞬间移动到最后的假图片上
list.style.left = -5 * 650 + 'px';
// 设置一个延时器,这个延时器的延时时间可以是0毫秒,虽然是0毫秒,但是可以让我们过渡先是瞬间取消,然后再加上
setTimeout(function () {
// 加过渡
list.style.transition = 'left .5s ease 0s';
// idx改为真正的最后一张
idx = 4;
list.style.left = -idx * 650 + 'px';
}, 0);
} else {
idx--;
list.style.left = -idx * 650 + 'px';
}
// 函数节流
setTimeout(function () {
lock = true;
}, 500);
}
复制代码
需要注意的是,如果已经是第一张图,那么点击左按钮时要取消过渡然后瞬间移动到克隆图片上,然后再加上过渡移动到真正的最后一张图片上,这里恢复过渡时利用了setTimeout是为了让取消过渡的瞬移起效果,不然瞬间移动还是会有过渡效果。
2-2、完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.carousel {
width: 650px;
height: 360px;
border: 1px solid #000;
margin: 50px auto;
position: relative;
overflow: hidden;
}
.carousel ul {
list-style: none;
width: 6000px;
position: relative;
left: 0px;
transition: left .5s ease 0s;
}
.carousel ul li {
float: left;
}
.carousel .leftbtn {
position: absolute;
left: 20px;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
background-color: rgb(226, 68, 28);
border-radius: 50%;
}
.carousel .rightbtn {
position: absolute;
right: 20px;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
background-color: rgb(226, 68, 28);
border-radius: 50%;
}
</style>
</head>
<body>
<div class="carousel">
<ul id="list">
<li><img src="images/beijing/0.jpg" alt=""></li>
<li><img src="images/beijing/1.jpg" alt=""></li>
<li><img src="images/beijing/2.jpg" alt=""></li>
<li><img src="images/beijing/3.jpg" alt=""></li>
<li><img src="images/beijing/4.jpg" alt=""></li>
</ul>
<!-- href写成空的javascript以防止页面刷新 -->
<a href="javascript:;" class="leftbtn" id="leftbtn"></a>
<a href="javascript:;" class="rightbtn" id="rightbtn"></a>
</div>
<script>
// 得到按钮和ul,ul整体进行运动
var leftbtn = document.getElementById('leftbtn');
var rightbtn = document.getElementById('rightbtn');
var list = document.getElementById('list');
// 克隆第一张图片追加到list中
var cloneLi = list.firstElementChild.cloneNode(true);
list.appendChild(cloneLi);
// 表示滚动到了第几个图片
var idx = 0;
// 设置一个节流锁,防止快速点击
var lock = true;
rightbtn.onclick = function () {
if (!lock) { return }
lock = false;
// 为了防止滚动到最后最后一张图后快速移动图片置第一张后去除掉了动画,要在点击时添加一遍
list.style.transition = 'left .5s ease 0s';
idx++;
if (idx > 4) {
// 在动画0.5s执行完毕后瞬间将list的left值置为0
setTimeout(() => {
list.style.transition = 'none';
list.style.left = 0;
idx = 0;
}, 500)
}
// 这里每张图片宽度是650px
list.style.left = -idx * 650 + 'px';
setTimeout(() => {
lock = true
}, 500);
}
leftbtn.onclick = function () {
if (!lock) { return }
lock = false;
if (idx == 0) {
list.style.transition = 'none';
// 直接瞬间移动到最后的假图片上
list.style.left = -5 * 650 + 'px';
// 设置一个延时器,这个延时器的延时时间可以是0毫秒,虽然是0毫秒,但是可以让我们过渡先是瞬间取消,然后再加上
setTimeout(function () {
// 加过渡
list.style.transition = 'left .5s ease 0s';
// idx改为真正的最后一张
idx = 4;
list.style.left = -idx * 650 + 'px';
}, 0);
} else {
idx--;
list.style.left = -idx * 650 + 'px';
}
setTimeout(() => {
lock = true
}, 500)
}
</script>
</body>
</html>
复制代码
总结:跑马灯轮播图的要点是,所有的图片以浮动的方式排成一排,父元素改变left值进行移动;此外为了能够起到轮播的效果,要克隆第一张图片拼接到最后:
- 在移动到最后一张图片再次向后移动时,先移动到克隆图片上,然后再瞬间让left变为0再进行移动(如果有过渡动画需要注意需要设置延时器,在动画效果结束后再重置回去)
- 在移动到第一张图片再次先前移动时,需要先瞬移到克隆图片上,然后再移动到真正的最后一张图片上
三、呼吸灯轮播图特效
3-1、实现原理
与跑马灯轮播图特效不同的是,呼吸灯特效需要各个轮播图堆叠在一起,以上一张“淡出”下一张“淡入”的方式来实现效果,也不需要克隆第一张图拼接到最后。
- 首先使用定位的方式,让各个轮播图堆叠展示,将第一张轮播图的opacity置为1,其余轮播图置为0,为了实现淡出淡入效果,可为ul添加opacity的过渡动画
- 当点击左/右按钮时,让当前轮播图的opacity变为0,上一张/下一张轮播图的opacity变为1即可
- 同样需要节流锁的使用,比如过渡动画时间为1s则锁打开的时长也设置为1s
3-2、代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.carousel {
width: 650px;
height: 360px;
border: 1px solid #000;
margin: 50px auto;
position: relative;
}
.carousel ul {
list-style: none;
}
.carousel ul li {
position: absolute;
top: 0;
left: 0;
/* 透明度都是0 */
opacity: 0;
transition: opacity 1s ease 0s;
}
/* 只有第一张透明度是1 */
.carousel ul li:first-child {
opacity: 1;
}
.carousel .leftbtn {
position: absolute;
left: 20px;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
background-color: rgb(28, 180, 226);
border-radius: 50%;
}
.carousel .rightbtn {
position: absolute;
right: 20px;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
background-color: rgb(28, 180, 226);
border-radius: 50%;
}
</style>
</head>
<body>
<div class="carousel">
<ul id="list">
<li><img src="images/beijing/0.jpg" alt=""></li>
<li><img src="images/beijing/1.jpg" alt=""></li>
<li><img src="images/beijing/2.jpg" alt=""></li>
<li><img src="images/beijing/3.jpg" alt=""></li>
<li><img src="images/beijing/4.jpg" alt=""></li>
</ul>
<a href="javascript:;" class="leftbtn" id="leftbtn"></a>
<a href="javascript:;" class="rightbtn" id="rightbtn"></a>
</div>
<script>
// 得到按钮和ul,ul整体进行运动
var leftbtn = document.getElementById('leftbtn');
var rightbtn = document.getElementById('rightbtn');
var list = document.getElementById('list');
var lis = list.getElementsByTagName('li');
// 当前是第几张图显示
var idx = 0;
// 节流
var lock = true;
// 右按钮
rightbtn.onclick = function () {
// 判断节流
if (!lock) return;
lock = false;
// 还没有改idx,此时的idx这个图片就是老图,老图淡出
lis[idx].style.opacity = 0;
idx++;
if (idx > 4) idx = 0;
// 改了idx,此时的idx这个图片就是新图,新图淡入
lis[idx].style.opacity = 1;
// 动画结束之后,开锁
setTimeout(function () {
lock = true;
}, 1000);
}
// 左按钮
leftbtn.onclick = function () {
// 判断节流
if (!lock) return;
lock = false;
// 还没有改idx,此时的idx这个图片就是老图,老图淡出
lis[idx].style.opacity = 0;
idx--;
if (idx < 0) idx = 4;
// 改了idx,此时的idx这个图片就是新图,新图淡入
lis[idx].style.opacity = 1;
// 动画结束之后,开锁
setTimeout(function () {
lock = true;
}, 1000);
}
</script>
</body>
</html>
复制代码