Home  >  Article  >  Web Front-end  >  Native JS uses transform to achieve infinite scrolling effect of banner

Native JS uses transform to achieve infinite scrolling effect of banner

hzc
hzcforward
2020-06-20 09:15:252382browse

Function

Native JS uses transform to achieve infinite scrolling effect of banner

  • By default, infinite loop moves to the right
  • Click the number to switch to the corresponding picture
  • Click left and right to switch pictures

Principle

First let’s talk about the principle.

  1. All pictures overlap in the layout, that is, as long as they are aligned in the Y direction, the z-index level of the currently visible picture is the highest.
  2. Change a picture every 3s and use setTimeout for timing.
  3. Use gIndex to record which picture subscript is displayed in the current visible area, and calculate the subscript of the next picture every time it is changed.
  4. Achieve an animation of image switching through requestAnimationFrame.

This method can also ensure that the entire page always has only 2 img tags, without having to create all img nodes. The key point is to replace the src of the invisible img every time.
Native JS uses transform to achieve infinite scrolling effect of banner

Animation implementation

  1. First define a timestap, this value records how far each frame moves. Define initial step=0 and record the number of moving steps.
  2. The distance moveWidth of each movement is timestamp*step. Picture 1 moves to the right to increase moveWidth, and picture 2 enters moveWidth from the left. Therefore, the transform of picture 1 is translate(moveWidth), and the transform of picture 2 is translate(moveWidth-picture width).
  3. step 1
  4. If moveWidth>picture width, step 5, otherwise requestAnimationFrame requests the next execution, continue 2-4.
  5. Pictures 1 and 2 will be positioned at Starting position, the z-index of picture 2 is set to the highest.

This completes a moving animation.

html code

<header>
    <p>
        <img  alt="Native JS uses transform to achieve infinite scrolling effect of banner" >
        <img  alt="Native JS uses transform to achieve infinite scrolling effect of banner" >
        <img  alt="Native JS uses transform to achieve infinite scrolling effect of banner" >
        <img  alt="Native JS uses transform to achieve infinite scrolling effect of banner" >
    </p>
    <p>
        </p>
<p>1</p>
        <p>2</p>
        <p>3</p>
        <p>4</p>
    
    <p>
        </p>
<p></p>
    
    <p>
        </p>
<p></p>
    
</header>

JS code

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 = 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)  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 layout style

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

Recommended tutorial: "js tutorial"

The above is the detailed content of Native JS uses transform to achieve infinite scrolling effect of banner. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete