原生JS使用transform实现banner的无限滚动效果

互联网 20-6-20

功能

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

原理

首先说下原理。

  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代码

<header>     <p class="box">         <img src="imgs/banner1.jpg">         <img src="imgs/banner2.jpg">         <img src="imgs/banner3.jpg">         <img src="imgs/banner4.jpg">     </p>     <p class="buttons">         <p class="active">1</p>         <p>2</p>         <p>3</p>         <p>4</p>     </p>     <p class="left">         <p class="arrow"></p>     </p>     <p class="right">         <p class="arrow"></p>     </p> </header>

JS代码

var timeout = null; window.onload = function () {     var oLeft = document.querySelector('.left');     var oRight = document.querySelector('.right');     var oButton = document.querySelector('.buttons');     var oButtons = document.querySelectorAll('.buttons p');     var oImgs = document.querySelectorAll('.box img');     var imgWidth = oImgs[0].width;     var gIndex = 0;     begainAnimate();      // 绑定左右点击事件     oLeft.onclick = function () {         clearTimeout(timeout);         leftMove();         begainAnimate();     };     oRight.onclick = function () {         clearTimeout(timeout);         rightMove();         begainAnimate();     };     // 绑定数字序号事件     oButton.onclick = function (event) {         clearTimeout(timeout);         var targetEl = event.target;         var nextIndex = (+targetEl.innerText) - 1;         console.log(nextIndex);         rightMove(nextIndex);         begainAnimate();     }     // 默认初始动画朝右边     function begainAnimate() {         clearTimeout(timeout);         timeout = setTimeout(function () {             rightMove();             begainAnimate();         }, 3000);     }     // 向左移动动画     function leftMove() {         var nextIndex = (gIndex - 1 < 0) ? oImgs.length - 1 : gIndex - 1;         animateSteps(nextIndex, -50);     }     // 向右移动动画     function rightMove(nextIndex) {         if (nextIndex == undefined) {             nextIndex = (gIndex + 1 >= oImgs.length) ? 0 : gIndex + 1;         }         animateSteps(nextIndex, 50);     }     // 一次动画     function animateSteps(nextIndex, timestamp) {         var currentImg = oImgs[gIndex];         var nextImg = oImgs[nextIndex];         nextImg.style.zIndex = 10;         var step = 0;         requestAnimationFrame(goStep);         // 走一帧的动画,移动timestamp         function goStep() {             var moveWidth = timestamp * step++;             if (Math.abs(moveWidth) < imgWidth) {                 currentImg.style.transform = `translate(${moveWidth}px)`;                 nextImg.style.transform = `translate(${moveWidth > 0 ? (moveWidth - imgWidth) : (imgWidth + moveWidth)}px)`;                 requestAnimationFrame(goStep);             } else {                 currentImg.style.zIndex = 1;                 currentImg.style.transform = `translate(0px)`;                 nextImg.style.transform = `translate(0px)`;                 oButtons[gIndex].setAttribute('class', '');                 oButtons[nextIndex].setAttribute('class', 'active');                 gIndex = nextIndex;             }         }     } } window.onclose = function () {     clearTimeout(timeout); }

css布局样式

<style>     /* 首先设置图片box的区域,将图片重叠在一起  */     header {         width: 100%;         position: relative;         overflow: hidden;     }     .box {         width: 100%;         height: 300px;     }     .box img {         width: 100%;         height: 100%;         position: absolute;         transform: translateX(0);         z-index: 1;     }     .box img:first-child {         z-index: 10;     }          /* 数字序列按钮 */     .buttons {         position: absolute;         right: 10%;         bottom: 5%;         display: flex;         z-index: 100;     }      .buttons p {         width: 30px;         height: 30px;         background-color: #aaa;         border: 1px solid #aaa;         text-align: center;         margin: 10px;         cursor: pointer;         opacity: .7;         border-radius: 15px;         line-height: 30px;     }      .buttons p.active {         background-color: white;     }      /* 左右切换按钮 */     .left,     .right {         position: absolute;         width: 80px;         height: 80px;         background-color: #ccc;         z-index: 100;         top: 110px;         border-radius: 40px;         opacity: .5;         cursor: pointer;     }      .left {         left: 2%;     }      .right {         right: 2%;     }      .left .arrow {         width: 30px;         height: 30px;         border-left: solid 5px #666;         border-top: solid 5px #666;         transform: translate(-5px, 25px) rotate(-45deg) translate(25px, 25px);     }      .right .arrow {         width: 30px;         height: 30px;         border-left: solid 5px #666;         border-top: solid 5px #666;         transform: translate(50px, 25px) rotate(135deg) translate(25px, 25px);     } </style>

推荐教程: 《js教程》

以上就是原生JS使用transform实现banner的无限滚动效果的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
标签: transform
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:分享 10 个提高 JavaScript 技能的测验问答

相关资讯