Страницы

Поиск по вопросам

суббота, 7 декабря 2019 г.

Как правильно внести изменения в скрипт таймера обратного отсчета времени

#javascript #jquery #дата #время #таймер


Всех приветствую! Прошу помощи. Есть скрипт таймера обратного отсчета времени до
определенной даты. Помогите, пожалуйста, внести в него изменения. Есть несколько моментов:


Необходимо добавить в скрипт таймера количество месяцев и количество лет.
Второй момент, не могу разобраться, когда таймер заканчивает отсчет, блок становится
пустым. Как сделать так, чтобы по окончании таймера, в этом блоке появлялся другой блок?
И еще один момент: скрипт ориентирован не на нашего брата, АМ и РМ, не совсем это
удобно, возможно ли это изменить, а также поменять местами в первой строке скрипта
число и месяц? Очень буду благодарен всем за любую помощь!


скрипт:

var end = new Date('12/01/2018 12:00 AM');

var _second = 1000;
var _minute = _second * 60;
var _hour = _minute * 60;
var _day = _hour * 24;
var timer;

function showRemaining() {
  var now = new Date();
  var distance = end - now;
  if (distance < 0) {
    clearInterval(timer);
    return;
  }
  var days = Math.floor(distance / _day);
  var hours = Math.floor((distance % _day) / _hour);
  var minutes = Math.floor((distance % _hour) / _minute);
  var seconds = Math.floor((distance % _minute) / _second);

  var daysLabel = pluralize(days, 'Дней');
  var hoursLabel = pluralize(hours, 'Часов');
  var minutesLabel = pluralize(minutes, 'Минут');
  var secondsLabel = pluralize(seconds, 'Секунд');

  var days = leadingZero(days);
  var hours = leadingZero(hours);
  var minutes = leadingZero(minutes);
  var seconds = leadingZero(seconds);

  function pluralize(number, text) {
    if(number === 1) {
      return text;
    } else {
      return text+''
    }
  }

  function leadingZero(number) {
    if(number < 10) {
      return '0'+number;
    } else {
      return number;
    }
  }

  $('.chart__bar--days .chart__bar-number').html(days);
  $('.chart__bar--days').css('height', ((days/360)*100)+'%');
  $('.chart__bar--days .chart__bar-label').html(daysLabel);

  $('.chart__bar--hours .chart__bar-number').html(hours);
  $('.chart__bar--hours').css('height', ((hours/24)*100)+'%');
  $('.chart__bar--hours .chart__bar-label').html(hoursLabel);

  $('.chart__bar--minutes .chart__bar-number').html(minutes);
  $('.chart__bar--minutes').css('height', ((minutes/60)*100)+'%');
  $('.chart__bar--minutes .chart__bar-label').html(minutesLabel);

  $('.chart__bar--seconds .chart__bar-number').html(seconds);
  $('.chart__bar--seconds').css('height', ((seconds/60)*100)+'%');
  $('.chart__bar--seconds .chart__bar-label').html(secondsLabel);
}

timer = setInterval(showRemaining, 1000);


html:

css: .widget { position: absolute; top: 0; bottom: 0; left: 0; right: 0; height: 100%; width: 100%; } .widget__foreground { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; } .widget--countdown__main { position: absolute; width: 50%; left: 50px; top: 120px; font-family: PT Serif Caption,Georgia,Times New Roman,Times,serif; color: #000000; text-shadow: #fff 1px 0px, #fff 1px 1px, #fff 0px 1px, #fff -1px 1px, #fff -1px 0px, #fff -1px -1px, #fff 0px -1px, #fff 1px -1px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px; } .widget--countdown__title { font-size: 36px; line-height: 42px; font-weight: 700; margin: 0 50px 20px 0; } .widget--countdown__supporting-text { margin-bottom: 25px; line-height: 17px; width: 50%; } .widget--countdown__chart { height: 100%; width: 50%; max-width: 470px; position: absolute; right: 50px; } .chart { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; display: flex; justify-content: space-between; } .chart__bar { width: 23%; position: relative; display: inline-block; align-self: flex-end; -webkit-transition: all linear .2s; -moz-transition: all linear .2s; -ms-transition: all linear .2s; -o-transition: all linear .2s; transition: all linear .2s; } .chart__bar-content { position: absolute; bottom: 20px; width: 100%; text-align: center; } .chart__bar-number { font-size: 36px; font-weight: 300; } .chart__bar-label { text-transform: uppercase; } .chart__bar--days { background-color: rgba(0, 191, 228, .90); box-shadow: 0px 0px 40px -5px rgba(0, 191, 228, .90); } .chart__bar--hours { background-color: rgba(249, 108, 207, .90); box-shadow: 0px 0px 40px -5px rgba(249, 108, 207, .90); } .chart__bar--minutes { background-color: rgba(0, 207, 167, .90); box-shadow: 0px 0px 40px -5px rgba(0, 207, 167, .90); } .chart__bar--seconds { background-color: rgba(238, 138, 56, .90); box-shadow: 0px 0px 40px -5px rgba(238, 138, 56, .90); } .chart__bar--days,.chart__bar--hours,.chart__bar--minutes,.chart__bar--seconds { background-image: url(pattern-timer.png); background-position: bottom right; background-repeat: repeat; }


Ответы

Ответ 1



upd.2 обновил ф-ю calendiff, чтобы правильно считала случаи, когда надо «отмотать» назад не один, а два месяца, для компенсации смещения в днях. Напр. чтобы компенсировать -31 день, добавить дни предыдущего одного месяца (30 дней) не достаточно, нужно заехать в пред-предыдущий месяц. upd. Как выяснилось, надо всё-таки считать точную «календарную» дистанцию между двух дат: и от 28 января до 28 февраля (31 день), и от 28 февраля до 28 марта (28 дней) – в обоих случаях ровно 1 месяц. Поэтому написал функцию для такого «человеческого» подсчёта разницы между двумя датами. Поскольку разметка повторяется, отличается лишь названием класса, вынес её генерацию в функцию. jQuery элементы достаточно найти один раз, и затем обращаться к сохранённым, вместо того, чтобы при каждом вызове заново искать в DOM-дереве. Добавил функцию для склонения существительных, в зависимости от числа (День, Дня, Дней). В стили добавил цвета для колонок года и месяца. // допустимые форматы времени: // https://tools.ietf.org/html/rfc2822#page-14 // https://www.w3.org/TR/NOTE-datetime // Напр. 1 декабря 2018, полдень по Москве: var end = new Date('2018-12-01T12:00+03:00') ,offset = (new Date().getTimezoneOffset())*6E4 ,timer ,$el ,key ,html = '' ; // generate markup html = ['years','months','days','hours','minutes','seconds'] .reduce( function(p,c){ return p += makeHtml(c);}, ''); $('.widget--countdown__chart > .chart').html(html); $el = { // найти один раз и запомнить Y: { n: $('.chart__bar--years .chart__bar-number'), l: $('.chart__bar--years .chart__bar-label'), b: $('.chart__bar--years') } ,M: { n: $('.chart__bar--months .chart__bar-number'), l: $('.chart__bar--months .chart__bar-label'), b: $('.chart__bar--months') } ,D: { n: $('.chart__bar--days .chart__bar-number'), l: $('.chart__bar--days .chart__bar-label'), b: $('.chart__bar--days') } ,h: { n: $('.chart__bar--hours .chart__bar-number'), l: $('.chart__bar--hours .chart__bar-label'), b: $('.chart__bar--hours') } ,m: { n: $('.chart__bar--minutes .chart__bar-number'), l: $('.chart__bar--minutes .chart__bar-label'), b: $('.chart__bar--minutes') } ,s: { n: $('.chart__bar--seconds .chart__bar-number'), l: $('.chart__bar--seconds .chart__bar-label'), b: $('.chart__bar--seconds') } } /** * генерирует html одного блока */ function makeHtml(key) { return [ '
', '
', '
', '
', '
', '
', ].join("\n").replace(/%KEY%/g, key); } function showRemaining() { var start = new Date(), r; if( end - start < 0) return timeHasCome(); r = calendiff( start, end); render( 'Y', r.years, ['Год','Года','Лет'], 3); // сколько максимум лет может быть? render( 'M', r.months, ['Месяц','Месяца','Месяцев'], 12); render( 'D', r.days, ['День','Дня','Дней'], 31); render( 'h', r.hours, ['Час','Часа','Часов'], 24); render( 'm', r.minutes, ['Минута','Минуты','Минут'], 60); render( 's', r.seconds, ['Секунда','Секунды','Секунд'], 60); } /** * Когда отсчёт закончился, или время уже прошло */ function timeHasCome() { if(timer) { window.clearInterval( timer); timer = undefined; } $('.widget.widget--countdown').html('
Баста, карапузики!
'); } function render( key, n, s, max) { $el[key].n.text( ('0' + n).slice(-2)); $el[key].l.text( getNumEnding(n, s)); $el[key].b.css('height', ((n / max) * 100) + '%'); } /** * Calendar difference between two dates * @param Date object dateIn start date * @param Date object dateOut end date * @return object with int properties * "years", "months", "days", "hours", "minutes" and "seconds" * * https://github.com/sergiks/calendiff.js * * @author Sergei Sokolov */ function calendiff( dateIn, dateOut) { var out = { years : 0 ,months : 0 ,days : 0 ,hours : 0 ,minutes : 0 ,seconds : 0 } ,sign = 1 ,diff = 0 ,proto ,monthsShift ,prop ; // check input proto = Object.prototype.toString.call(dateIn); if( proto !== '[object Date]') { dateIn = new Date( dateIn); if( isNaN( dateIn.getTime())) throw 'Incorrect "In" date format'; } proto = Object.prototype.toString.call(dateOut); if( proto !== '[object Date]') { dateOut = new Date( dateOut); if( isNaN( dateOut.getTime())) throw 'Incorrect "Out" date format'; } // check numeric difference diff = dateOut.getTime() - dateIn.getTime(); if( diff === 0) { return out; } else if( diff < 0) { sign = -1; dateOut = [dateIn, dateIn = dateOut][0]; // swap the dates } // calculate human-readable difference out.seconds += dateOut.getSeconds() - dateIn.getSeconds(); if( out.seconds < 0) { out.seconds += 60; out.minutes--; } out.minutes += dateOut.getMinutes() - dateIn.getMinutes(); if( out.minutes < 0) { out.minutes += 60; out.hours--; } out.hours += dateOut.getHours() - dateIn.getHours(); if( out.hours < 0) { out.hours += 24; out.days--; } // complex part: a month can have various number of days // when entering with a negative number of days, up to -31, // it might take up to two months shift back // should the preceding month only have 28, 29 or 30 days. out.days += dateOut.getDate() - dateIn.getDate(); while( out.days < 0) { monthsShift = 0; out.days += new Date( dateOut.getFullYear(), dateOut.getMonth() - monthsShift, 0).getDate(); monthsShift++; out.months--; } out.months += dateOut.getMonth() - dateIn.getMonth(); if( out.months < 0) { out.months += 12; out.years--; } out.years += dateOut.getFullYear() - dateIn.getFullYear(); // negative difference case if( sign < 0) for( prop in out) if( out[prop]) out[prop] *= -1; // avoid -0 values return out; } /** * Функция возвращает окончание для множественного числа слова на основании числа и массива окончаний * param iNumber Integer Число на основе которого нужно сформировать окончание * param aEndings Array Массив слов или окончаний для чисел (1, 4, 5), * например ['яблоко', 'яблока', 'яблок'] * return String */ function getNumEnding(iNumber, aEndings) { var sEnding, i; iNumber = iNumber % 100; if (iNumber>=11 && iNumber<=19) { sEnding=aEndings[2]; } else { i = iNumber % 10; switch (i) { case (1): sEnding = aEndings[0]; break; case (2): case (3): case (4): sEnding = aEndings[1]; break; default: sEnding = aEndings[2]; } } return sEnding; } timer = setInterval(showRemaining, 200); .widget { position: absolute; top: 0; bottom: 0; left: 0; right: 0; height: 100%; width: 100%; } .widget__foreground { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; } .widget--countdown__main { position: absolute; width: 50%; left: 50px; top: 120px; font-family: PT Serif Caption,Georgia,Times New Roman,Times,serif; color: #000000; text-shadow: #fff 1px 0px, #fff 1px 1px, #fff 0px 1px, #fff -1px 1px, #fff -1px 0px, #fff -1px -1px, #fff 0px -1px, #fff 1px -1px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px; } .widget--countdown__title { font-size: 36px; line-height: 42px; font-weight: 700; margin: 0 50px 20px 0; } .widget--countdown__supporting-text { margin-bottom: 25px; line-height: 17px; width: 50%; } .widget--countdown__chart { height: 100%; width: 50%; max-width: 470px; position: absolute; right: 50px; } .chart { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; display: flex; justify-content: space-between; } .chart__bar { width: 23%; position: relative; display: inline-block; align-self: flex-end; -webkit-transition: all linear .2s; -moz-transition: all linear .2s; -ms-transition: all linear .2s; -o-transition: all linear .2s; transition: all linear .2s; } .chart__bar-content { position: absolute; bottom: 20px; width: 100%; text-align: center; } .chart__bar-number { font-size: 36px; font-weight: 300; } .chart__bar-label { text-transform: uppercase; } .chart__bar--years { background-color: rgba(228, 191, 0, .90); box-shadow: 0px 0px 40px -5px rgba(228, 191, 0, .90); } .chart__bar--months { background-color: rgba(207, 108, 249, .90); box-shadow: 0px 0px 40px -5px rgba(207, 108, 249, .90); } .chart__bar--days { background-color: rgba(0, 191, 228, .90); box-shadow: 0px 0px 40px -5px rgba(0, 191, 228, .90); } .chart__bar--hours { background-color: rgba(249, 108, 207, .90); box-shadow: 0px 0px 40px -5px rgba(249, 108, 207, .90); } .chart__bar--minutes { background-color: rgba(0, 207, 167, .90); box-shadow: 0px 0px 40px -5px rgba(0, 207, 167, .90); } .chart__bar--seconds { background-color: rgba(238, 138, 56, .90); box-shadow: 0px 0px 40px -5px rgba(238, 138, 56, .90); } .chart__bar--days,.chart__bar--hours,.chart__bar--minutes,.chart__bar--seconds { background-image: url(pattern-timer.png); background-position: bottom right; background-repeat: repeat; }


Ответ 2



Сначала разберемся с терминологией. Терминология Полный год - двенадцать полных месяцев. Полный месяц - количество полных дней, равное количеству календарных дней этого месяца с учетом високосного года. Полный день - 24 полных часа. Полный час - 60 полных минут. Полная минута - 60 полных секунд. Полная секунда - 1000 миллисекунд. Алгоритм Рассмотрим алгоритм вычисления значений счетчика на примере. Допустим сегодня 2 января 2015 года время 00:01. Событие наступит 15 апреля 2016 года в 00:01. Мы выбрали одинаковое время для упрощения понимания алгоритма. Посчитаем количество полных месяцев. Начиная с февраля 2015 до марта 2016 включительно будет 14 полных месецев. Мы не стали учитывать январь 2015 и апрель 2016, так как эти месяцы не полные. Вычислим количество полных дней в этих месяцах. В январе 2015 29 полных дней и 1 неполный подолжительностью 23:59, в апреле 2016 - 14 полных и 1 неполный подолжительностью 00:01. В сумме за два месяца 44 полных дня 29 + 14 + 1. Это много, здесь, наверняка, есть еще один полный месяц. Но как определить сколько в нем должно быть полных дней? А столько, сколько в текущем месяце календарных дней. И это, пожалуй, самое сложное для понимания. Почему именно количество дней в текущем месяце? Дело в нашем восприятии месяца. Если сегодня 12-е, то для нас "через месяц" это 12-е следующего месяца. Если в текущем месяце N дней, то количество дней с 12-го до 12-го следующего месяца будет (N - 12) + 12, где (N - 12) количество дней до окончания текущего месяца, а 12 - количество дней до 12-го числа следующего месяца. Рассмотрим пару примеров (во всех примерах считаем что время 00:00): Если сегодня 31-е января, то до 28-го февраля осталось 28 дней. 1 день в январе, 27 дней в феврале. В текущем месяце 31 день. До 28 февраля 0 месяцев 28 дней. А если до 1-го марта? Тогда февраль является полным месяцем. Нам надо подсчитать количество дней между январем и мартом, как будто за январем сразу идет март. Получается 1 день в январе и 0 дней в марте. До 1-го марта 1 месяц и 1 день. Похоже на правду? Если же сегодня 1-е февраля (не високосный год), то до 31-го марта 28 дней в феврале и 30 в марте, итого 58 дней. Вычитаем февраль 58 - 28, получаем 1 месяц и 30 дней. Если же сегодня 1-е февраля (високосный год), то до 31-го марта 29 дней в феврале и 30 в марте, итого 59 дней. Вычитаем февраль 59 - 29, получаем 1 месяц и 30 дней. В последних примерах получается интересная ситуация, когда один месяц меньше, чем оставшееся количесвто дней. Но это нормально, так мы воспринимаем месяцы. Итак у нас 44 полных дня. Сейчас январь. В январе 31 день. Извлекаем еще один полный месяц 44 - 31, и остается 13 полных дней. Итого полных месяцев у нас 14 + 1 = 15, а это 1 полный год и 3 полных месяца. А общий результат 1 год 3 месяца 13 дней (время по нулям, так как оно одинаковое) Время Со временем есть проблема, которая называется Daylight saving time DST сложная тема, не будем ее касаться в рамках этой задачи. Попытаемся обойти DST, выдав локальное время за UTC. Тогда будет необходим механизм синхронизации времени, при котором возможны ситуации, когда счетчик при отсчете обратного времени по завершению последней секунды последней минуты часа либо не изменит час, либо уменьшит его на 2. Примечания к коду Я вставил в код комментария, призванные помочь пониманию алгоритма. Код не оптимизирован. Где-то производительность была проигнорирована в угоду ясности. Не стал заниматься падежами, чтобы не усложнять код. Создал функцию timeOver(), которая вызовется по окончанию времени. Но она пока только выводит alert, так как не понятно, что должно быть по истечении времени. Надо додумать отображение высоты счетчиков и их стили. Код JSFiddle и здесь: // Дата и время собятия var end = new Date(Date.parse("2017-02-21 22:45")); end = moveToUTC(end); var now = moveToUTC(new Date()); // Вынес поиск элементов HTML, чтобы не искать их в DOM в каждой итерации var $years = $('.chart__bar--years'), $yearsLabel = $years.find('.chart__bar-label'), $yearsNumber = $years.find('.chart__bar-number'), $months = $('.chart__bar--months'), $monthsLabel = $months.find('.chart__bar-label'), $monthsNumber = $months.find('.chart__bar-number'), $days = $('.chart__bar--days'), $daysLabel = $days.find('.chart__bar-label'), $daysNumber = $days.find('.chart__bar-number'), $hours = $('.chart__bar--hours'), $hoursLabel = $hours.find('.chart__bar-label'), $hoursNumber = $hours.find('.chart__bar-number'), $minutes = $('.chart__bar--minutes'), $minutesLabel = $minutes.find('.chart__bar-label'), $minutesNumber = $minutes.find('.chart__bar-number'), $seconds = $('.chart__bar--seconds'), $secondsLabel = $seconds.find('.chart__bar-label'), $secondsNumber = $seconds.find('.chart__bar-number'); var timer; function showRemaining() { if (now.getTime() >= end.getTime()) { clearInterval(timer); timeOver(); return; } now.setSeconds(now.getUTCSeconds() + 1); if (now.getUTCSeconds() % (60 * 60)) { // каждый час синхронизация времени now = moveToUTC(new Date()) } var counters = calcDistance(end, now); var years = counters['years']; var months = counters['months']; var days = counters['days']; var hours = counters['hours']; var minutes = counters['minutes']; var seconds = counters['seconds']; var yearsLabel = pluralize(years, 'Лет'); var monthsLabel = pluralize(days, 'Месяцев'); var daysLabel = pluralize(days, 'Дней'); var hoursLabel = pluralize(hours, 'Часов'); var minutesLabel = pluralize(minutes, 'Минут'); var secondsLabel = pluralize(seconds, 'Секунд'); var months = leadingZero(months); var days = leadingZero(days); var hours = leadingZero(hours); var minutes = leadingZero(minutes); var seconds = leadingZero(seconds); function pluralize(number, text) { if (number === 1) { return text; } else { return text + '' } } function leadingZero(number) { if (number < 10) { return '0' + number; } else { return number; } } $yearsNumber.html(years); //$years.css('height', ((years / ???) * 100) + '%'); // не понятно на что делить $years.css('height', 0); // пусть будет 0 $yearsLabel.html(yearsLabel); $monthsNumber.html(months); $months.css('height', ((months / 12) * 100) + '%'); $monthsLabel.html(monthsLabel); $daysNumber.html(days); $days.css('height', ((days / 30) * 100) + '%'); // примерно 30, хотя и не правильно $daysLabel.html(daysLabel); $hoursNumber.html(hours); $hours.css('height', ((hours / 24) * 100) + '%'); $hoursLabel.html(hoursLabel); $minutesNumber.html(minutes); $minutes.css('height', ((minutes / 60) * 100) + '%'); $minutesLabel.html(minutesLabel); $secondsNumber.html(seconds); $seconds.css('height', ((seconds / 60) * 100) + '%'); $secondsLabel.html(secondsLabel); } function timeOver() { alert('Время вышло'); } // Вернет количество дней в казанном месяце указанного года function daysInMonth(date) { return new Date(date.getUTCFullYear(), date.getUTCMonth(), 0).getUTCDate(); } // Вернет количество секунд прошедших с начала дня function secondsFromDayStart(date) { return date.getUTCSeconds() + 60 * date.getUTCMinutes() + 60 * 60 * date.getUTCHours(); } // Возвращает дату, смещенную в UTC // Например, на входе 2015-02-15 00:00 в локальном времени, на выходе 2015-02-15 00:00 в UTC function moveToUTC(date) { return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds())); } function calcDistance(end, now) { var secondsInDay = 60 * 60 * 24; // 60 секунд в 60 минутах в 24 часах var yearsCount = 0, monthsCount = 0, daysCount = 0, // количество полных дней hoursCount = 0, minutesCount = 0, secondsCount = 0; // Сначала разберемся со временем // Вычисляем общее количиство секунд до назначенной даты. secondsCount = secondsFromDayStart(end) - secondsFromDayStart(now); // (1) secondsFromDayStart(end) - количество секунд с начала дня события до наступления события // (2) secondsFromDayStart(now) - количество секунд, прошедших сначала сегодняшнего дня // Если secondsCount имеет отрицательное значение, // то это тот случай, когда сегодня мы уже завершили полный день и перешли к отсчету очередного дня if (secondsCount < 0) { // тогда нам нужно забрать один день, // так как дальнейшая логика основывается на том, что (1) больше либо равно (2) daysCount -= 1; // и добавить количество секунд в дне // (так как secondsCount имеет отрицательное значение, то secondsCount + secondsInDay будет всегда меньше полного дня) secondsCount += secondsInDay; } // В secondsCount сейчас находится общее количество секунд. // Разабьем это значение на компоненты: hoursCount = secondsCount / 3600 >> 0; minutesCount = (secondsCount / 60 >> 0) % 60; secondsCount = secondsCount % 60 // Займемся годом // Определим количество полных лет, в которых мы точно будем уверены yearsCount = end.getUTCFullYear() - now.getUTCFullYear() - 1; // Если окончание в 2017-м, а сегодня 2015-й, то между датами точно есть один полный год. // Если окончание в 2016-м, а сегодня 2015-й, то между датами может и не быть полного года. // Если года одинаковые, то yearsCount будет равен -1. Мы восстановим справедливость позже. // yearsCount посчитан, но не до конца // Определим количество полных месяцев monthCount = 11 - now.getUTCMonth() + end.getUTCMonth(); // Так как в js месяцы начинаются с нуля (январь = 0, февраль = 1, ...), // то end.getMonth() вернет количество прошедших полных месяцев с начала года, // а выражение 11 - now.getMonth() вернет количество полных месяцев до завершения года. // monthCount посчитан, но тоже не до конца // Займемся количеством дней // Запомним в переменной количество дней в текущем месяце, оно пригодится несколько раз var daysInCurrentMonth = daysInMonth(now); daysCount += daysInCurrentMonth - now.getUTCDate() + end.getUTCDate(); // daysInCurrentMonth - now.getDate() - количество дней до конца текущего месяца // end.getDate() - количество дней с начала месяца до дня события // Минимальное значение daysCount равняется 0, если сегодня 31-е, дата события 1-е число, // и при вычислении времени мы одолжили один день // Максимальное значени daysCount равняется 61, // в случае если сегодня 1-е число, в этом месяце 31 день, дата события 31-е число, // и при вычислении времени мы не брали один день // Извлекаем еще один полный месяц, если он есть monthCount += daysCount / daysInCurrentMonth >> 0; daysCount = daysCount % daysInCurrentMonth; // Извлекаем еще один полный год, если он есть yearsCount += monthCount / 12 >> 0; monthCount = monthCount % 12; return { years: yearsCount, months: monthCount, days: daysCount, hours: hoursCount, minutes: minutesCount, seconds: secondsCount }; } timer = setInterval(showRemaining, 1000); .widget { position: absolute; top: 0; bottom: 0; left: 0; right: 0; height: 100%; width: 100%; } .widget__foreground { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; } .widget--countdown__main { position: absolute; width: 50%; left: 50px; top: 120px; font-family: PT Serif Caption, Georgia, Times New Roman, Times, serif; color: #000000; text-shadow: #fff 1px 0px, #fff 1px 1px, #fff 0px 1px, #fff -1px 1px, #fff -1px 0px, #fff -1px -1px, #fff 0px -1px, #fff 1px -1px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px, #fff 0 0 3px; } .widget--countdown__title { font-size: 36px; line-height: 42px; font-weight: 700; margin: 0 50px 20px 0; } .widget--countdown__supporting-text { margin-bottom: 25px; line-height: 17px; width: 50%; } .widget--countdown__chart { height: 100%; width: 50%; max-width: 470px; position: absolute; right: 50px; } .chart { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; display: flex; justify-content: space-between; } .chart__bar { width: 23%; position: relative; display: inline-block; align-self: flex-end; -webkit-transition: all linear .2s; -moz-transition: all linear .2s; -ms-transition: all linear .2s; -o-transition: all linear .2s; transition: all linear .2s; } .chart__bar-content { position: absolute; bottom: 20px; width: 100%; text-align: center; } .chart__bar-number { font-size: 36px; font-weight: 300; } .chart__bar-label { text-transform: uppercase; } .chart__bar--months { background-color: red; box-shadow: 0px 0px 40px -5px rgba(0, 191, 228, .90); } .chart__bar--days { background-color: rgba(0, 191, 228, .90); box-shadow: 0px 0px 40px -5px rgba(0, 191, 228, .90); } .chart__bar--hours { background-color: rgba(249, 108, 207, .90); box-shadow: 0px 0px 40px -5px rgba(249, 108, 207, .90); } .chart__bar--minutes { background-color: rgba(0, 207, 167, .90); box-shadow: 0px 0px 40px -5px rgba(0, 207, 167, .90); } .chart__bar--seconds { background-color: rgba(238, 138, 56, .90); box-shadow: 0px 0px 40px -5px rgba(238, 138, 56, .90); } .chart__bar--days, .chart__bar--hours, .chart__bar--minutes, .chart__bar--seconds { background-image: url(pattern-timer.png); background-position: bottom right; background-repeat: repeat; }


Ответ 3



Описал в комментариях как работает скрипт и дополнил его. //Устанавливаем дату окончания var end = new Date('12/01/2018 12:00 AM'); //Задаём константы var _second = 1000; var _minute = _second * 60; var _hour = _minute * 60; var _day = _hour * 24; var _month = _day * 30; var _year = _month * 12; //Для того что бы вывести диаграмму остатка количества лет нужно общее количество — в данно случае ставлю 2 var _year_all = 2; var timer; //Функция которая вызывается при окончании отсчёта function eventStopTimer(){ return false; } function showRemaining() { var now = new Date(); var distance = end - now; if (distance < 0) { eventStopTimer(); clearInterval(timer); return; } // Находим количество var years = Math.floor(distance / _year); var months = Math.floor((distance % _year) / _month); var days = Math.floor((distance % _months) / _day); var hours = Math.floor((distance % _day) / _hour); var minutes = Math.floor((distance % _hour) / _minute); var seconds = Math.floor((distance % _minute) / _second); // В английской версии тут склоняли добавлением «S» var yearsLabel = pluralize(years, 'Дней'); var monthsLabel = pluralize(months, 'Часов'); var daysLabel = pluralize(days, 'Дней'); var hoursLabel = pluralize(hours, 'Часов'); var minutesLabel = pluralize(minutes, 'Минут'); var secondsLabel = pluralize(seconds, 'Секунд'); //Добавляем лидирующий ноль var days = leadingZero(days); var hours = leadingZero(hours); var minutes = leadingZero(minutes); var seconds = leadingZero(seconds); //Функция для склонения (неправильная) function pluralize(number, text) { if(number === 1) { return text; } else { return text+'' } } //Функция добавления лидирующего нуля function leadingZero(number) { if(number < 10) { return '0'+number; } else { return number; } } $('.chart__bar--years .chart__bar-number').html(years); $('.chart__bar--years').css('height', ((years/_year_all)*100)+'%'); $('.chart__bar--years .chart__bar-label').html(yearsLabel); $('.chart__bar--months .chart__bar-number').html(months); $('.chart__bar--months').css('height', ((months/12)*100)+'%'); $('.chart__bar--months .chart__bar-label').html(monthsLabel); $('.chart__bar--days .chart__bar-number').html(days); $('.chart__bar--days').css('height', ((days/360)*100)+'%'); $('.chart__bar--days .chart__bar-label').html(daysLabel); $('.chart__bar--hours .chart__bar-number').html(hours); $('.chart__bar--hours').css('height', ((hours/24)*100)+'%'); $('.chart__bar--hours .chart__bar-label').html(hoursLabel); $('.chart__bar--minutes .chart__bar-number').html(minutes); $('.chart__bar--minutes').css('height', ((minutes/60)*100)+'%'); $('.chart__bar--minutes .chart__bar-label').html(minutesLabel); $('.chart__bar--seconds .chart__bar-number').html(seconds); $('.chart__bar--seconds').css('height', ((seconds/60)*100)+'%'); $('.chart__bar--seconds .chart__bar-label').html(secondsLabel); } timer = setInterval(showRemaining, 1000); В html нужно добавить блоки


Комментариев нет:

Отправить комментарий