您的位置 首页 技术

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

功能 默认情况无限循环向右移动 点击数字切换到对应图片 点击左右切换可切换图片 原理 首先说下原理。 在布局上所有的图片都是重叠的,即只要保证Y方向对齐即可,当前可见的图z-ind…

功能

5289b216dc4904aaaec181e12c2cc13.png

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

原理

首先说下原理。

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

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

动画的实现

  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的无限滚动效果的详细内容,更多请关注24课堂在线网其它相关文章!

本文来自网络,不代表24小时课堂在线立场,转载请注明出处:https://www.24ketang.cn/86422.html

为您推荐

返回顶部