原生JS利用transform实现banner的无限滚动

开发 前端
原生JS怎样利用transform实现banner的无限滚动及其功能原理。一起来看看吧。

 功能

[[330208]]

  •  默认情况无限循环向右移动
  •  点击数字切换到对应图片
  •  点击左右切换可切换图片

原理

首先说下原理。

  1.  在布局上所有的图片都是重叠的,即只要保证Y方向对齐即可,当前可见的图z-index层级最高。
  2.  每隔3s中更换一张图片,使用setTimeout定时。
  3.  使用gIndex记录当前可视区域的展示的是哪张图片下标,每次更换,计算下一张图片的下标。
  4.  通过requestAnimationFrame实现一次图片切换的动画。

这种方法也可以做到整个页面始终只有2个img标签,而不必把所有的img节点全部创建出来,要点是每次更换不可见img的src。

动画的实现

  1.  首先定义一个timestap,这个值记录每个帧移动多少距离。定义初始step=0,记录移动的步数。
  2.  每次移动的距离moveWidth是timestamp*step,图片1向右移动增加moveWidth,图片2从左侧进入moveWidth。因此,图片1的transform是translate(moveWidth), 而图片2的transform则是translate(moveWidth-图片宽度)。

      3.  step+1

      4.  如果moveWidth>图片宽度,步骤5,否则requestAnimationFrame请求下一次执行,继续2-4.

      5.  图片1和2都将位置放置在起始位置,图片2的z-index设置为最高。

这样就完成了一次移动的动画。

html代码 

  1. <header>  
  2.     <div class="box">  
  3.         <img src="imgs/banner1.jpg">  
  4.         <img src="imgs/banner2.jpg">  
  5.         <img src="imgs/banner3.jpg">  
  6.         <img src="imgs/banner4.jpg">  
  7.     </div>  
  8.     <div class="buttons">  
  9.         <div class="active">1</div>  
  10.         <div>2</div>  
  11.         <div>3</div>  
  12.         <div>4</div>  
  13.     </div>  
  14.     <div class="left">  
  15.         <div class="arrow"></div>  
  16.     </div>  
  17.     <div class="right">  
  18.         <div class="arrow"></div>  
  19.     </div>  
  20. </header> 

JS代码 

  1. var timeout = null 
  2. window.onload = function () {  
  3.     var oLeft = document.querySelector('.left');  
  4.     var oRight = document.querySelector('.right');  
  5.     var oButton = document.querySelector('.buttons');  
  6.     var oButtons = document.querySelectorAll('.buttons div');  
  7.     var oImgs = document.querySelectorAll('.box img');  
  8.     var imgWidth = oImgs[0].width;  
  9.     var gIndex = 0 
  10.     begainAnimate();  
  11.     // 绑定左右点击事件  
  12.     oLeft.onclick = function () {  
  13.         clearTimeout(timeout);  
  14.         leftMove();  
  15.         begainAnimate();  
  16.     };  
  17.     oRight.onclick = function () {  
  18.         clearTimeout(timeout);  
  19.         rightMove();  
  20.         begainAnimate();  
  21.     };  
  22.     // 绑定数字序号事件  
  23.     oButton.onclick = function (event) {  
  24.         clearTimeout(timeout);  
  25.         var targetEl = event.target;  
  26.         var nextIndex = (+targetEl.innerText) - 1;  
  27.         console.log(nextIndex);  
  28.         rightMove(nextIndex);  
  29.         begainAnimate();  
  30.     }  
  31.     // 默认初始动画朝右边  
  32.     function begainAnimate() {  
  33.         clearTimeout(timeout);  
  34.         timeout = setTimeout(function () {  
  35.             rightMove();  
  36.             begainAnimate();  
  37.         }, 3000);  
  38.     }  
  39.     // 向左移动动画  
  40.     function leftMove() {  
  41.         var nextIndex = (gIndex - 1 < 0) ? oImgs.length - 1 : gIndex - 1;  
  42.         animateSteps(nextIndex, -50);  
  43.     }  
  44.     // 向右移动动画  
  45.     function rightMove(nextIndex) {  
  46.         if (nextIndex == undefined) {  
  47.             nextIndex = (gIndex + 1 >= oImgs.length) ? 0 : gIndex + 1;  
  48.         }  
  49.         animateSteps(nextIndex, 50);  
  50.     }  
  51.     // 一次动画  
  52.     function animateSteps(nextIndex, timestamp) {  
  53.         var currentImg = oImgs[gIndex];  
  54.         var nextImg = oImgs[nextIndex];  
  55.         nextImg.style.zIndex = 10 
  56.         var step = 0 
  57.         requestAnimationFrame(goStep);  
  58.         // 走一帧的动画,移动timestamp  
  59.         function goStep() {  
  60.             var moveWidth = timestamp * step++;  
  61.             if (Math.abs(moveWidth) < imgWidth) {  
  62.                 currentImg.style.transform = `translate(${moveWidth}px)`;  
  63.                 nextImg.style.transform = `translate(${moveWidth > 0 ? (moveWidth - imgWidth) : (imgWidth + moveWidth)}px)`;  
  64.                 requestAnimationFrame(goStep);  
  65.             } else {  
  66.                 currentImg.style.zIndex = 1 
  67.                 currentImg.style.transform = `translate(0px)`;  
  68.                 nextImg.style.transform = `translate(0px)`;  
  69.                 oButtons[gIndex].setAttribute('class', '');  
  70.                 oButtons[nextIndex].setAttribute('class', 'active');  
  71.                 gIndex = nextIndex 
  72.             }  
  73.         }  
  74.     }  
  75.  
  76. window.onclose = function () {  
  77.     clearTimeout(timeout);  

css布局样式 

  1. <style>  
  2.     /* 首先设置图片box的区域,将图片重叠在一起  */  
  3.     header {  
  4.         width: 100%;  
  5.         position: relative;  
  6.         overflow: hidden;  
  7.     }  
  8.     .box {  
  9.         width: 100%;  
  10.         height: 300px;  
  11.     }  
  12.     .box img {  
  13.         width: 100%;  
  14.         height: 100%;  
  15.         position: absolute;  
  16.         transform: translateX(0);  
  17.         z-index: 1; 
  18.      }  
  19.     .box img:first-child {  
  20.         z-index: 10;  
  21.     }    
  22.     /* 数字序列按钮 */  
  23.     .buttons {  
  24.         position: absolute;  
  25.         right: 10%;  
  26.         bottom: 5%;  
  27.         display: flex;  
  28.         z-index: 100;  
  29.     }  
  30.     .buttons div {  
  31.         width: 30px;  
  32.         height: 30px;  
  33.         background-color: #aaa;  
  34.         border: 1px solid #aaa;  
  35.         text-align: center;  
  36.         margin: 10px;  
  37.         cursor: pointer;  
  38.         opacity: .7;  
  39.         border-radius: 15px;  
  40.         line-height: 30px;  
  41.     }  
  42.     .buttons div.active {  
  43.         background-color: white;  
  44.     }  
  45.     /* 左右切换按钮 */  
  46.     .left,  
  47.     .right {  
  48.         position: absolute;  
  49.         width: 80px;  
  50.         height: 80px;  
  51.         background-color: #ccc;  
  52.         z-index: 100;  
  53.         top: 110px;  
  54.         border-radius: 40px;  
  55.         opacity: .5;  
  56.         cursor: pointer;  
  57.     }  
  58.     .left {  
  59.         left: 2%;  
  60.     } 
  61.     .right {  
  62.         right: 2%;  
  63.     }  
  64.     .left .arrow {  
  65.         width: 30px;  
  66.         height: 30px;  
  67.         border-left: solid 5px #666;  
  68.         border-top: solid 5px #666;  
  69.         transform: translate(-5px, 25px) rotate(-45deg) translate(25px, 25px); 
  70.      }  
  71.     .right .arrow {  
  72.         width: 30px;  
  73.         height: 30px;  
  74.         border-left: solid 5px #666;  
  75.         border-top: solid 5px #666;  
  76.         transform: translate(50px, 25px) rotate(135deg) translate(25px, 25px);  
  77.     }  
  78. </style>  

 

责任编辑:庞桂玉 来源: segmentfault
相关推荐

2012-05-10 14:02:46

jQuery

2015-07-17 13:15:40

Swift版幻灯无限滚动

2023-09-07 07:35:59

JS操作网页

2012-05-02 13:53:00

JavaScript

2024-06-20 08:42:45

2015-05-28 10:20:34

js相册翻页

2015-05-07 15:13:22

JS实现JQueryJQuery

2022-09-20 11:00:14

Vue3滚动组件

2021-06-18 10:12:09

JS代码前端

2019-12-11 10:50:06

JS图片前端

2013-04-02 13:04:07

ListView平滑滚

2011-09-02 10:14:10

JQuery滚动Xslider

2012-08-10 09:46:53

jQuery

2022-07-12 08:32:17

transition跑马灯

2021-02-11 13:56:21

JSweb插件

2022-04-06 18:29:58

CSSJS输入框

2023-11-22 07:47:34

2022-07-28 14:26:11

AI作诗应用开发

2009-11-10 14:13:44

VB.NET图片框

2010-06-23 09:08:42

点赞
收藏

51CTO技术栈公众号