好看的轮播切换效果

微博上看到@过气网红一丝 发的,特地收集。
《好看的轮播切换效果》

预览

html

<div class="slides">
    <div class="slide 1th"></div>
    <div class="slide 2th"></div>
    <div class="slide 3th"></div>
    <div class="slide 4th"></div>
    <div class="slide 5th"></div>
</div>
<div class="nav">
    <div class="btn-group">
        <div class="btn active"></div>
        <div class="btn"></div>
        <div class="btn"></div>
        <div class="btn"></div>
        <div class="btn"></div>
    </div>
</div>

css

 .btn-group {
        position: relative;
        display: inline-block;
    }
    .btn-group .btn {
        cursor: pointer;
        float: left;
        height: 10px;
        width: 10px;
        border-radius: 50%;
        border: 2px solid rgba(255,255,255,0.3);
        margin-left: 6px;
        margin-top: 1px;
    }
    .btn-group .btn:first-child {
        margin-left: 3px;
    }
    .btn-group svg {
        z-index: -1;
        top: 0;
        left: 0;
        position: absolute;
        width: 100%;
        height: 100%;
        overflow: visible;
    }
    .btn-group path {
        fill: none;
        stroke: #eee;
        stroke-dasharray: 39, 99999;
        transition: all 1s ease-in-out;
        stroke-width: 2;
    }
    .slides {
        transition: left 1s ease-in-out;
        height: 100vh;
        position: absolute;
    }
    .slides .slide {
        height: 100vh;
        width: 100vw;
        float: left;
    }
    .slides .slide:nth-child(1) {
        background: #c66;
    }
    .slides .slide:nth-child(2) {
        background: #acac39;
    }
    .slides .slide:nth-child(3) {
        background: #39ac39;
    }
    .slides .slide:nth-child(4) {
        background: #40bfbf;
    }
    .slides .slide:nth-child(5) {
        background: #8c8cd9;
    }
    body {
        overflow: hidden;
        margin: 0;
        padding: 0;
    }
    .nav {
        text-align: center;
        position: absolute;
        width: 100%;
        bottom: 5%;
        transform: translateY(-50%);
    }

js

  const pathLength = 39;
    const BtnGroup = class BtnGroup {
        constructor(group) {
            this.buttonSpacing = 20;
            this.group = group;
            this.buttons = Array.prototype.slice.call(this.group.querySelectorAll('.btn'));
            this.slides = Array.prototype.slice.call(document.querySelectorAll('.slide'));
            this.slideContainer = document.querySelector('.slides');
            this.slideContainer.style.width = this.slides.length + '00vw';
            this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            this.svg.setAttribute('viewbox', '0 0 ' + (this.buttonSpacing * this.buttons.length) + ' 16');
            this.path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            this.path.classList.add('line');
            this.currentPath = 'M ' + (-this.buttonSpacing / 2) + ', 14';
            this.currentIndex = -1;
            this.activateIndex(this.buttons.indexOf(this.group.querySelector('.active')));
            this.group.appendChild(this.svg);
            this.svg.appendChild(this.path);
            this.refreshPath();
            this.initButtons();

            for (const button of this.buttons) {
                button.addEventListener('click', e => this.onClick(e));
            }
        }

        initButtons() {
            for (var i = 0; i < this.buttons.length; i++) {
                const center = this.center(i);
                const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                let pathStr = '';
                pathStr += 'M' + (center    ) + ', 14 ';
                pathStr += 'C' + (center + 3) + ', 14 ';
                pathStr +=       (center + 6) + ', 11 ';
                pathStr +=       (center + 6) + ',  8 ';
                pathStr += 'C' + (center + 6) + ',  5 ';
                pathStr +=       (center + 3) + ',  2 ';
                pathStr +=       (center    ) + ',  2 ';
                pathStr += 'C' + (center - 3) + ',  2 ';
                pathStr +=       (center - 6) + ',  5 ';
                pathStr +=       (center - 6) + ',  8 ';
                pathStr += 'C' + (center - 6) + ', 11 ';
                pathStr +=       (center - 3) + ', 14 ';
                pathStr +=       (center    ) + ', 14 ';
                path.setAttributeNS(null, 'd', pathStr);
                path.classList.add('circle');
            }
        }

        onClick(e) {
            const index = this.buttons.indexOf(e.srcElement || e.target);
            this.activateIndex(index);
        }

        refreshPath() {
            this.path.setAttributeNS(null, 'd', this.currentPath);
            this.path.style.strokeDashoffset = (-this.path.getTotalLength() + pathLength) * 0.9965;
        }

        center(index) {
            return index * this.buttonSpacing + (this.buttonSpacing / 2);
        }

        removeClass(str) {
            if (this.buttons[this.currentIndex]) {
                this.buttons[this.currentIndex].classList.remove(str);
            }
        }

        addClass(str) {
            if (this.buttons[this.currentIndex]) {
                this.buttons[this.currentIndex].classList.add(str);
            }
        }

        activateIndex(index) {
            this.slideContainer.style.left = -index + '00vw';
            const lastCenter = this.center(this.currentIndex);
            const nextCenter = this.center(index);
            const offset = 0;
            const sign = index < this.currentIndex ? -1 : 1;
            this.currentPath += 'C' + (lastCenter + sign * 3) + ', 14 ';
            this.currentPath +=       (lastCenter + sign * 6) + ', 11 ';
            this.currentPath +=       (lastCenter + sign * 6) + ',  8 ';
            this.currentPath += 'C' + (lastCenter + sign * 6) + ',  5 ';
            this.currentPath +=       (lastCenter + sign * 3) + ',  2 ';
            this.currentPath +=       (lastCenter           ) + ',  2 ';
            this.currentPath += 'C' + (lastCenter - sign * 3) + ',  2 ';
            this.currentPath +=       (lastCenter - sign * 6) + ',  5 ';
            this.currentPath +=       (lastCenter - sign * 6) + ',  8 ';
            this.currentPath += 'C' + (lastCenter - sign * 6) + ', 11 ';
            this.currentPath +=       (lastCenter - sign * 3) + ', 14 ';
            this.currentPath +=       (lastCenter           ) + ', 14 ';
            this.currentPath += 'L' + (nextCenter           ) + ', 14 ';
            this.currentPath += 'C' + (nextCenter + sign * 3) + ', 14 ';
            this.currentPath +=       (nextCenter + sign * 6) + ', 11 ';
            this.currentPath +=       (nextCenter + sign * 6) + ',  8 ';
            this.currentPath += 'C' + (nextCenter + sign * 6) + ',  5 ';
            this.currentPath +=       (nextCenter + sign * 3) + ',  2 ';
            this.currentPath +=       (nextCenter           ) + ',  2 ';
            this.currentPath += 'C' + (nextCenter - sign * 3) + ',  2 ';
            this.currentPath +=       (nextCenter - sign * 6) + ',  5 ';
            this.currentPath +=       (nextCenter - sign * 6) + ',  8 ';
            this.currentPath += 'C' + (nextCenter - sign * 6) + ', 11 ';
            this.currentPath +=       (nextCenter - sign * 3) + ', 14 ';
            this.currentPath +=       (nextCenter           ) + ', 14 ';
            this.removeClass('active');
            this.currentIndex = index;
            this.addClass('active');
            this.refreshPath();
        }
    }

    const groups = Array.prototype.slice.call(document.querySelectorAll('.btn-group'));

    for (const group of groups) {
        console.log(new BtnGroup(group));
    }
    原文作者:nexyme
    原文地址: https://segmentfault.com/a/1190000005000574
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞