svg/js обратный отсчет

226
22 ноября 2017, 01:13

Как изменить js код так, чтобы по истечении 59 секунд счетчик не замирал на 0 секунде, а начинал заново?

(function ( $ ) { 
    $.fn.svgTimer = function(options) { 
        var opts = $.extend({}, $.fn.svgTimer.defaults, options); 
 
        var template = "<div class='svg-hexagonal-counter'>" 
            + "<div class='hint'><span class='hint-count'></span><br><span class='hint-text'></span></div>" 
            + "<svg class='counter' x='0px' y='0px' viewBox='0 0 776 628'>" 
            + "<path class='track' d='M723 314L543 625.77 183 625.77 3 314 183 2.23 543 2.23 723 314z'></path>" 
            + "<path class='fill' d='M723 314L543 625.77 183 625.77 3 314 183 2.23 543 2.23 723 314z'></path>" 
            + "</svg>" 
            + "</div>"; 
 
        return this.each(function() { 
            // Build dom for svg countdown 
            var parentEl = $(this); 
            parentEl.append(template); 
 
            //define dom elements 
            var track = parentEl.find('.track'); 
            var fill = parentEl.find('.fill'); 
            var hintCount = parentEl.find('.hint-count'); 
            var hintText = parentEl.find('.hint-text').text(opts.hint); 
 
 
            //set time and offset 
            var time = opts.time; /* how long the timer runs for */ 
            var initialOffset = 2160; 
            var i = 1; 
 
            if(opts.direction === 'forward'){ 
                hintCount.text(i); 
            } else if (opts.direction === 'backwards') { 
                var count = opts.time - i; 
                hintCount.text(count); 
            } else { 
                hintCount.text(i); 
            } 
 
            //draw initial hexagon 
            track.css('stroke', opts.track); 
             
 
            //run timer 
            var interval = setInterval(function() { 
                //track.css('stroke', opts.track); 
                fill.css({ 
                    'stroke': opts.fill, 
                    'stroke-dashoffset': initialOffset-(i*(initialOffset/time)) + 'px', 
                    'transition': 'stroke-dashoffset 1s ' +  opts.transition 
                }); 
                if(opts.direction === 'forward'){ 
                    hintCount.text(i); 
                } else if (opts.direction === 'backwards') { 
                    var count = opts.time - i; 
                    hintCount.text(count); 
                } else { 
                    hintCount.text(i); 
                } 
 
                if (i == time) { 
                    clearInterval(interval); 
                } 
                i++; 
            }, opts.interval); 
        }); 
    }; 
 
    $.fn.svgTimer.defaults = { 
        time: 60, 
        interval: 1000, 
        direction: 'forward', 
        track: 'rgb(56, 71, 83)', 
        fill: 'rgb(104, 214, 198)', 
        transition: 'linear', 
        hint: 'seconds' 
 
    } 
}( jQuery )); 
 
//initialize plugin  
$(function () { 
    $('.timer-days').svgTimer({ 
        direction: 'backwards', 
        time: 35, 
        interval: 86400000, 
        hint: 'days' 
    }); 
 
    $('.timer-hours').svgTimer({ 
        direction: 'backwards', 
        time: 18, 
        interval: 3600000, 
        hint: 'hours' 
    }); 
 
    $('.timer-minutes').svgTimer({ 
        direction: 'backwards', 
        time: 54, 
        interval: 60000, 
        hint: 'minutes' 
    }); 
 
    $('.timer-seconds').svgTimer({ 
        direction: 'backwards', 
        time: 60, 
        interval: 1000, 
        hint: 'seconds' 
    }); 
});
.svg-hexagonal-counter { 
    position: relative; 
    float: left; 
} 
 
.svg-hexagonal-counter .hint { 
    text-align:center; 
    position: absolute; 
    /*line-height: 200px;*/ 
    top: 40%; 
    width: 100%; 
    font-size: 1.5em; 
    font-weight: 700; 
} 
 
/*svg { 
    -webkit-transform: rotate(-90deg); 
    transform: rotate(-90deg); 
}*/ 
 
 
.svg-hexagonal-counter .counter{ 
    width: 200px; 
    height: 240px; 
    -webkit-touch-callout: none; 
    -webkit-user-select: none; 
    -khtml-user-select: none; 
    -moz-user-select: none; 
    -ms-user-select: none; 
    user-select: none; 
    cursor: default; 
} 
.svg-hexagonal-counter .counter .track, 
.svg-hexagonal-counter .counter .fill { 
    fill: rgba(0, 0, 0, 0); 
    stroke-width: 30; 
    transform: translate(290px, 800px)rotate(-120deg); 
} 
 
.svg-hexagonal-counter .counter .fill { 
    stroke: rgb(255, 255, 255); 
    stroke-linecap: round; 
    stroke-dasharray: 2160; 
    stroke-dashoffset: 2160; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 
<div class="timer-days"></div> 
<div class="timer-hours"></div> 
<div class="timer-minutes"></div> 
<div class="timer-seconds"></div>

Answer 1

Как изменить js код так, чтобы по истечении 59 секунд счетчик не замирал на 0 секунде, а начинал заново?

За отсчет отвечает таймер, установленный с помощью setInterval который под достижению нужного числа срабатываний (time == i) очищается, используя clearTimeout. Отсюда следует, что для решения задачи, необходимо сделать две вещи:

  1. сбросить i в начальное значение
  2. не останавливать таймер

Для удобства, можно внести свойство repeat в настройки таймера.

То есть в вашем коде будут следующий изменения:

if (i == time) {
    if(opts.repeat){
        i = -1;
    } 
    else clearInterval(interval);
}

и

$.fn.svgTimer.defaults = {
     ....
     repeat: false,
}
....
    $('.timer-seconds').svgTimer({
        ....
        repeat: true,           
    });

Это отвечает на вопрос, как сделать чтобы таймер перезапускался. Однако есть один арфетфакт, при достижении конечного значения транзишен анимации будет срабатывать обратно к нулю. Его также следует модифцировать, если надо.

(function ( $ ) { 
    $.fn.svgTimer = function(options) { 
        var opts = $.extend({}, $.fn.svgTimer.defaults, options); 
 
        var template = "<div class='svg-hexagonal-counter'>" 
            + "<div class='hint'><span class='hint-count'></span><br><span class='hint-text'></span></div>" 
            + "<svg class='counter' x='0px' y='0px' viewBox='0 0 776 628'>" 
            + "<path class='track' d='M723 314L543 625.77 183 625.77 3 314 183 2.23 543 2.23 723 314z'></path>" 
            + "<path class='fill' d='M723 314L543 625.77 183 625.77 3 314 183 2.23 543 2.23 723 314z'></path>" 
            + "</svg>" 
            + "</div>"; 
 
        return this.each(function() { 
            // Build dom for svg countdown 
            var parentEl = $(this); 
            parentEl.append(template); 
 
            //define dom elements 
            var track = parentEl.find('.track'); 
            var fill = parentEl.find('.fill'); 
            var hintCount = parentEl.find('.hint-count'); 
            var hintText = parentEl.find('.hint-text').text(opts.hint); 
 
 
            //set time and offset 
            var time = opts.time; /* how long the timer runs for */ 
            var initialOffset = 2160; 
            var i = 1; 
 
            if(opts.direction === 'forward'){ 
                hintCount.text(i); 
            } else if (opts.direction === 'backwards') { 
                var count = opts.time - i; 
                hintCount.text(count); 
            } else { 
                hintCount.text(i); 
            } 
 
            //draw initial hexagon 
            track.css('stroke', opts.track); 
             
 
            //run timer 
            var interval = setInterval(function() { 
                //track.css('stroke', opts.track); 
                fill.css({ 
                    'stroke': opts.fill, 
                    'stroke-dashoffset': initialOffset-(i*(initialOffset/time)) + 'px', 
                    'transition': 'stroke-dashoffset 1s ' +  opts.transition 
                }); 
                if(opts.direction === 'forward'){ 
                    hintCount.text(i); 
                } else if (opts.direction === 'backwards') { 
                    var count = opts.time - i; 
                    hintCount.text(count); 
                } else { 
                    hintCount.text(i); 
                } 
 
                if (i == time) { 
                    if(opts.repeat){ 
                      i = -1; 
                    }  
                    else clearInterval(interval); 
                } 
                i++; 
            }, opts.interval); 
        }); 
    }; 
 
    $.fn.svgTimer.defaults = { 
        time: 60, 
        interval: 1000, 
        direction: 'forward', 
        track: 'rgb(56, 71, 83)', 
        fill: 'rgb(104, 214, 198)', 
        transition: 'linear', 
        hint: 'seconds', 
        repeat: false, 
 
    } 
}( jQuery )); 
 
//initialize plugin  
$(function () { 
 
 
    $('.timer-seconds').svgTimer({ 
        direction: 'backwards', 
        time: 10, 
        interval: 1000, 
        hint: 'seconds', 
        repeat: true, 
        
    }); 
});
.svg-hexagonal-counter { 
    position: relative; 
    float: left; 
} 
 
.svg-hexagonal-counter .hint { 
    text-align:center; 
    position: absolute; 
    /*line-height: 200px;*/ 
    top: 40%; 
    width: 100%; 
    font-size: 1.5em; 
    font-weight: 700; 
} 
 
/*svg { 
    -webkit-transform: rotate(-90deg); 
    transform: rotate(-90deg); 
}*/ 
 
 
.svg-hexagonal-counter .counter{ 
    width: 200px; 
    height: 240px; 
    -webkit-touch-callout: none; 
    -webkit-user-select: none; 
    -khtml-user-select: none; 
    -moz-user-select: none; 
    -ms-user-select: none; 
    user-select: none; 
    cursor: default; 
} 
.svg-hexagonal-counter .counter .track, 
.svg-hexagonal-counter .counter .fill { 
    fill: rgba(0, 0, 0, 0); 
    stroke-width: 30; 
    transform: translate(290px, 800px)rotate(-120deg); 
} 
 
.svg-hexagonal-counter .counter .fill { 
    stroke: rgb(255, 255, 255); 
    stroke-linecap: round; 
    stroke-dasharray: 2160; 
    stroke-dashoffset: 2160; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 
 
<div class="timer-seconds"></div>

READ ALSO
Unexpected string

Unexpected string

ЗдравствуйтеНе могу понять, в чем заключается ошибка? Ошибка:

177
VueJS в Chrome Extension

VueJS в Chrome Extension

Привет всемЕсть проект (Chrome Extension)

220