Делаем собственный таймер для спорта
vk f t

Делаем собственный таймер для спорта

Без рекламы и встроенных покупок

Те, кто занимается спортом, знают: часто нужен таймер. Кому-то надо отмерять интервалы по минуте, кому-то — сколько работаешь, столько отдыхаешь; кому-то нужны сложные интервалы и круги; кому-то просто секундомер. На всё это, конечно, в интернете полно готовых программ, но почему бы не сделать свою?

Если вы пропустили наш первый урок по созданию полноценных программ, где мы рассказываем про инструменты и основные моменты, прочитайте его сейчас. Без этого вам будет сложнее разобраться, что здесь происходит, и что это всё вообще такое.

Как устроен интервальный таймер

Наш сценарий работы такой: пользователь задаёт время одного упражнения и перерыва после него, а потом указывает, сколько раз он хочет выполнить это упражнение с перерывом. Например, стоять в планке на протяжении минуты, потом отдыхать 45 секунд, повторить восемь раз. Получается, что основных параметров у нас три: время тренировки, время отдыха, количество подходов.

Чтобы во время тренировки можно было не смотреть на экран, надо предусмотреть звуковое оповещение. Оно подскажет, что закончился очередной интервал, и нужно отдохнуть или снова приступить к упражнению.

Основа страницы

Возьмём стандартный шаблон страницы:

    
language: HTML
<!DOCTYPE html>

<html>
<head>
</head>
<body>
</body>
</html>


Скопировать код

Код скопирован

Теперь поработаем со служебным разделом <head>..</head> и наполним его нужными командами:

    
language: HTML
<!-- Это название страницы, выводится в табе браузера-->

<title>Интервальный таймер</title>

<!-- это служебная информация для браузера, пока можно не вникать -->

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1">


Скопировать код

Код скопирован

Подключаем там же фреймворк jQuery, который упростит нам работу с таймером и его компонентами:

    
language: HTML
<!-- подключаем фреймворк jQuery -->

<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js" type="text/javascript"></script>


Скопировать код

Код скопирован

Теперь разместим все элементы интерфейса на странице. Начнём с общего блока, где будет наш таймер:

    
language: HTML
<div class="app_form_block app_main app_timer ">

<!-- внутри этого блока мы и будем размещать все элементы -->

</div>


Скопировать код

Код скопирован

Теперь будем размещать внутри этого блока интерфейс программы. Сразу подключим звуковые уведомления, за них отвечает тег <audio>

    
language: HTML
<!-- подключаем звуковые уведомления -->

   <audio id="audio_beep">

      <source src="s.mp3" type="audio/mp3" >

   </audio>


Скопировать код

Код скопирован

Звук мы взяли где-то из интернета и положили в ту же папку, что и наша программа.

Чтобы мы могли менять время и параметры тренировки, сделаем форму и разместим все наши компоненты на ней.

    
language: HTML
<!-- делаем форму на сайте, где будем выводить наши элементы -->

<form name="timer_form" id="timer_form">

<!-- тут будут наш таймер и блок с настройками -->

</form>


Скопировать код

Код скопирован

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

    
language: HTML
<!-- пишем специальный заголовок страницы -->

<div class="block_row timer_types ">

<span class="timer_types_btn active" id="Secret">Интервальный таймер

</span>

</div>


Скопировать код

Код скопирован

Тег <span> — это контейнер, как бы прозрачная обёртка для своего содержимого. С его помощью мы можем отдельно настроить внешний вид и поведение нашего текста. Теперь у нашего заголовка есть внутреннее имя "Secret" и класс "timer_types_btn", который пока ещё нигде не прописан.

На этом этапе у нас будет пустая страница с надписью «Интервальный таймер». Пока что ничего интересного.

Интерфейс

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

    
language: HTML
<div class="block_row  app_console">

<!-- основной блок со всеми цифрами -->

</div>


Скопировать код

Код скопирован

Первое, что мы в него добавим — интерфейс настроек тренировки, где можно будет выбрать время и количество повторений. Сначала добавим в него настройку времени на упражнения:

    
language: HTML
<!-- блок, который отвечает за время тренировки -->

<span class="timer_interval_work">

 

   <!-- по умолчанию ставим время одного подхода 00 минут… -->

   <span class="timer_interval_nums minutes green" contenteditable="true">00

   </span>

   <!-- разделитель — двоеточие -->

   <span class="timer_sep">:

   </span>

 

   <!-- …и 25 секунд -->

   <span class="timer_interval_nums seconds green" contenteditable="true">25

   </span>

</span>


Скопировать код

Код скопирован

Внутри этого блока у нас три раздела: один отвечает за минуты, второй — за двоеточие, третий — за секунды. Свойство contenteditable="true" означает, что этот контент можно изменять, щёлкая мышкой и вводя свои значения.

Так же добавим блоки количества подходов и времени отдыха:

    
language: HTML
<!-- блок, который отвечает за количество подходов -->

<span class="timer_interval_count">

 

   <!-- какой сейчас идёт подход -->

   <span class="timer_interval_nums times">1

   </span>

 

   <!-- разделитель — косая черта -->

   <span class="timer_sep">/

   </span>

 

   <!-- и сколько подходов у нас всего -->

   <span class="timer_interval_nums all_times" contenteditable="true">10

   </span>

</span>

 

<!-- блок, который отвечает за время отдыха -->

<span class="timer_interval_rest">

 

   <!-- по умолчанию ставим время отдыха 0 минут… -->

   <span class="timer_interval_nums minutes red" contenteditable="true">00

   </span>

 

   <!-- разделитель — двоеточие -->

   <span class="timer_sep">:

   </span>

 

   <!-- …и 5 секунд -->

   <span class="timer_interval_nums seconds red" contenteditable="true">5

   </span>

</span>


Скопировать код

Код скопирован

Вставляем это всё в нашу панель настроек и смотрим, что получилось:


Табло для отсчёта времени и кнопки

Для большого табло используем тот же код, что и для панели настроек, только применим потом другой класс оформления:

    
language: HTML
<!-- большая цифровая панель -->

<div class="timer_panel_nums">

 

   <!-- минуты… -->

   <span class="timer_nums minutes" >00</span>

   <span >:</span>

 

   <!-- …и секунды -->

   <span class="timer_nums seconds" >00</span>

</div>


Скопировать код

Код скопирован

Кнопки сделаем с помощью стандартного тега <input>. Каждой кнопке присвоим своё имя и идентификатор, чтобы можно было с ними работать из скрипта:

    
language: HTML
<!-- блок кнопок -->

<div class="block_row">

 

   <!-- Кнопка «Сброс» -->

   <input value="Сброс" name="timer_clear" id="timer_clear" class="timer_btn" type="button" />

 

   <!-- Кнопка «Старт» -->

   <input value="Старт" name="timer_run" id="timer_run" class="timer_btn run" type="button" />

 

   <!-- Кнопка «Пауза», в самом начале она скрыта -->

   <input value="Пауза" name="timer_pause" id="timer_pause" class="timer_btn pause hide" type="button" />

 

<!-- закончился блок кнопок -->

</div>


Скопировать код

Код скопирован

Вот наш интерфейс. Ставим его в форму на странице и смотрим на результат:


Настраиваем внешний вид

Очевидно, что таймер наш выглядит скромновато. Нужно его оформить. Для этого используем CSS — стили оформления элементов на странице.

Как вы помните, CSS-стили можно выносить в отдельный файл, а можно писать в разделе <head> с помощью тега <script>. Выберем второй способ и определим все стили прямо в этом же документе:

    
language: CSS
<style type="text/css">

 

   /*задаём общие параметры для всей страницы: шрифт и отступы*/

   body{

     text-align: center;

     margin: 10;

     font-family: Verdana, Arial, sans-serif;

     font-size: 16px;

   }

   /*настраиваем отступы в полях ввода цифр, там, где задаётся время тренировки, отдыха, и количество повторов*/

   .app_form_block input[type="number"] {

     padding: 4px 4px;

   }

 

   /*задаём отступы у элементов*/

   .app_main .block_row {

      padding: 1em 0.5em;

   }

   /*устанавливаем размер цифр для количества повторов, времени тренировки и отдыха */

   .app_timer .app_console .timer_panel_info {

      font-size: 1.6em;

      line-height: 1.2em;

      letter-spacing: 0;

   }

 

   /*зелёный цвет*/

   .green {

      color: #BFF08E;

   }

 

   /*красный цвет*/

   .red {

      color: #E56655;

   }

 

   /*задаём размер таймера*/

   .app_timer .app_console .timer_panel_nums {

      font-size: 4.8em;

      line-height: 1.2em;

      margin-top: 50px;

   }

 

   /*учим браузер скрывать временно ненужные кнопки*/

   .app_timer .timer_btn.hide,

   .app_timer .timer_nums.hide,

   .app_timer .timer_sep.hide {

      display: none;

   }

 

   /*задаём размер кнопок*/

   .app_timer .timer_btn {

      border-color: #777;

      color: #777;

      font-size: 1.2em;

      font-weight: 400;

      line-height: 1.8em;

      padding: 8px 12px;

      margin: 0 2px;

      min-width: 180px;

   }

 

   /*настраиваем, как изменится цвет кнопки, если провести по ней мышкой*/

   .app_timer .timer_btn:hover {

      background-color: #777;

      color: #FFF;

   }

 

   /*задаём размер кнопок*/

   .app_timer .timer_btn.run,

   .app_timer .timer_btn.pause {

      border-color: #5594E5;

      color: #5594E5;

      font-weight: 600;

   }

 

   /*настраиваем, как изменится цвет АКТИВНОЙ кнопки, если провести по ней мышкой*/

   .app_timer .timer_btn.run:hover,

   .app_timer .timer_btn.pause:hover {

      background-color: #5594E5;

      color: #FFF;

   }

 

   </style>


Скопировать код

Код скопирован

Сохраняем код, обновляем страницу в браузере:


Класс! Время тренировки у нас выделено зелёным цветом, отдыха — красным. Благодаря этому мы не перепутаем числа. А ещё появилось большое табло отсчёта времени и две кнопки вместо трёх — «Пауза» автоматически исчезла после загрузки.

Собираем скрипт

Пока при нажатии на кнопки ничего не происходит — у нас нет скрипта, который бы это обрабатывал. В прошлый раз мы его писали там же, внутри страницы, теперь давайте вынесем его в отдельный файл. Так будет удобнее читать код: команд уже много, и если туда же добавить скрипт, будет совсем большая простыня текста. Поэтому создадим отдельный файл interval_timer_script.js и подключим его на нашей странице с таймером такой командой:

    
language: HTML
<!-- подключаем наш код, который отвечает за правильную работу таймера -->

<script type="text/javascript" src="interval_timer_script.js" defer></script>


Скопировать код

Код скопирован

Смотрите, у нас появилась новая команда в теге скрипта: defer. Она запрещает скрипту выполняться, пока страница полностью не загрузится. Это позволяет нам сначала подготовить страницу целиком, а только потом запускать таймер.

Мы назвали наш скрипт interval_timer_script.js, но название у него может быть каким угодно, лишь бы из английских букв, цифр и без пробелов. Расширение .js должно остаться таким же в любом случае. Меняете имя файла — не забудьте прописать его название в src="….js", чтобы страница знала, как называется нужный скрипт.

Теперь наполним наш скрипт. Начнём с переменных:

    
language: JavaScript
// переменная, которая отслеживает, сколько секунд прошло

var now_seconds = 0;

// var now_times = 0;

// тренировка начинается с отсчёта рабочего времени, сразу ставим этот режим

var interval_type = 'work';

// переменная для отсчёта интервалов

var intervalVariable;

// переменная, которая следит за количеством секунд в таймерах

var seconds_1 = 0;

// ставим начальные значения счётчиков минут и секунд

var timer_minutes = 0;

var timer_seconds = 0;


Скопировать код

Код скопирован

Теперь напишем функцию, которая будет постоянно готовить к запуску наше звуковое оповещение. Она будет брать нужные нам файлы ogg и mp3 и подключать их к нашей странице:

    
language: JavaScript
// подготовка звукового оповещения

function audio_change() {

   

   // находим аудиоэлемент на странице

   var audio = $('#audio_beep');

   

   // подключаем нужный файл со звуком. Файлов два, потому что разные браузеры играют разные форматы

   $('#audio_beep source[type="audio/ogg"]').attr('src', 's.ogg');

   $('#audio_beep source[type="audio/mp3"]').attr('src', 's.mp3');

   

   // ставим звук на паузу и подгружаем его

   audio[0].pause();

   audio[0].load();

}


Скопировать код

Код скопирован

Перед тем, как работать с таймером и интервалами, давайте напишем маленькую функцию, которая переводит наше время из просто секунд в секунды, минуты и часы. Мало ли, вдруг кто-то фанат долгих упражнений:

    
language: JavaScript
// разбиваем секунды на часы, минуты и секунды

function secondsToTime(seconds) {

   var h = parseInt(seconds / 3600 % 24);

   var m = parseInt(seconds /  60 % 60);

   var s = parseInt(seconds % 60);

   return {'hours': leadZero(parseInt(h)), 'minutes': leadZero(parseInt(m)), 'seconds': leadZero(parseInt(s))};

}


Скопировать код

Код скопирован

Ну и добавим эстетики в программу — для красоты будем ставить первым ноль, если число минут или секунд меньше девяти:

    
language: JavaScript
function leadZero(num) {

   var s = "" + num;

   if (s.length < 2) {

       s = "0" + s ;

   }

   return s;

}


Скопировать код

Код скопирован

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

    
language: JavaScript
// отображение времени на табло

function renderTimerNums(seconds) {

   var timer_nums = secondsToTime(seconds)

   $('.timer_nums.minutes').text(timer_nums.minutes);

   $('.timer_nums.seconds').text(timer_nums.seconds);

}


Скопировать код

Код скопирован

Теперь предусмотрим смену времени каждую секунду, пока работает таймер. Для этого будем отдельно обрабатывать два режима: тренировки и отдыха. Не забудем про красоту — время тренировки сделаем зелёным, как на панели настроек, а время отдыха — красным:

    
language: JavaScript

// функция, которая отвечает за смену времени на таймере

function timerTick(type, timer_params) {

   

   // увеличиваем количество прошедших секунд на единицу

   now_seconds++;

   

   // если идёт время тренировки

   if(interval_type == 'work') {

       

       // и ещё осталось время на тренировку

       if(timer_params.time_work - now_seconds > 0) {

           

           // показываем, сколько осталось времени

           renderTimerNums(timer_params.time_work - now_seconds);

       }

           

           // иначе, если тренировка закончилась

       else {

           

           // обнуляем табло

           renderTimerNums(0);

           

           // проигрываем звук уведомления

           $('#audio_beep')[0].play();

           

           // обнуляем секунды тренировки

           now_seconds = 0;

           

           // ставим режим «Отдых»

           interval_type = 'rest';

           

           // меняем цвет цифр на таймере

           $('.timer_panel_nums .timer_nums').removeClass('green');

           $('.timer_panel_nums .timer_nums').addClass('red');

       }

   }

       

       // если началось время отдыха

   else if(interval_type == 'rest') {

       

       // и оно ещё не закончилось

       if(timer_params.time_rest - now_seconds > 0) {

           

           // показываем оставшееся время

           renderTimerNums(timer_params.time_rest - now_seconds);

       }

           

           // а если всё-таки время отдыха закончилось

       else {

           

           // обнуляем табло

           renderTimerNums(0);

           

           // проигрываем звук уведомления

           $('#audio_beep')[0].play();

           

           // обнуляем секунды

           now_seconds = 0;

           

           // увеличиваем счётчик повторов на единицу

           now_times++;

           

           // если мы выполнили все повторы

           if(now_times > timer_params.interval_count) {

               

               // обновляем информацию на панели настроек

               $('.timer_interval_nums.times').text(timer_params.interval_count);

               $('#timer_pause').trigger('click');

               now_seconds = 0;

               $('.timer_panel_nums .timer_nums').removeClass('red');

           }

               

               // иначе, если количество пройденных повторов меньше, чем было задано

           else {

               

               // обновляем информацию на панели настроек

               $('.timer_interval_nums.times').text(now_times);

               $('.timer_panel_nums .timer_nums').removeClass('red');

               $('.timer_panel_nums .timer_nums').addClass('green');

           }

           

           // ставим после отдыха снова режим тренировки

           interval_type = 'work';

       }

   }

}

 


Скопировать код

Код скопирован

Продолжение скрипта: обрабатываем нажатия на кнопки

Начнём с кнопки «Старт». Логика работы такая: следим за тем, в каком режиме работает таймер, не забывая скрывать «Старт» и показывать «Паузу» после запуска. Как только перешли к отдыху или снова к тренировке — включаем звуковой сигнал. Если все тренировки прошли, но мы снова нажали «Старт», начнём всё сначала:

    
language: JavaScript
// обрабатываем нажатие на кнопку «Старт»

$('#timer_run').click(function() {

   

   // настраиваем аудио

   audio_change();

   

   // делаем кнопку «Старт» невидимой

   $(this).addClass('hide');

   

   // а кнопку «Пауза», наоборот, видимой

   $('#timer_pause').removeClass('hide');

   

   // записываем установленные минуты и секунды

   timer_minutes = $('.timer_nums.minutes').text();

   timer_seconds = $('.timer_nums.seconds').text();

   

   // переменная, которая будет хранить параметры интервального цикла

   var timer_params = {};

   

   // запускаем звуковое оповещение

   $('#audio_beep')[0].play();

   

   // устанавливаем размер тренировки...

   timer_params.time_work = $('.timer_interval_work .minutes').text()*60 + $('.timer_interval_work .seconds').text()*1;

   

   // ...отдыха,

   timer_params.time_rest = $('.timer_interval_rest .minutes').text()*60 + $('.timer_interval_rest .seconds').text()*1;

   // ...и количество повторений

   timer_params.interval_count = $('.timer_interval_count .all_times').text()*1;

   

   // обновляем информацию о том, сколько подходов уже сделано

   now_times = $('.timer_interval_count .times').text()*1;

   

   // если все тренировки прошли — начнём сначала

   if(now_times >= timer_params.interval_count) {

       now_times = 1;

       $('.timer_interval_count .times').text(now_times);

   }

   

   // если сейчас режим тренировки, то делаем табло зелёным и запоминаем количество секунд

   if(interval_type == 'work') {

       $('.timer_panel_nums .timer_nums').addClass('green');

       seconds_1 = timer_params.time_work;

   }

       

       // если сейчас режим отдыха, то делаем табло красным и запоминаем количество секунд

   else if(interval_type = 'rest') {

       $('.timer_panel_nums .timer_nums').addClass('red');

       seconds_1 = timer_params.time_rest;

   }

   

   // задаём интервал обновления — одна секунда

   intervalVariable = setInterval(timerTick, 1000, 'interval', timer_params);

   // выходим из функции

   return false;

   });


Скопировать код

Код скопирован

Теперь очередь кнопки «Пауза». Она появляется в тот момент, когда мы нажимаем на кнопку «Старт», которая сразу исчезает. Логика чуть другая: при каждом нажатии мы просто останавливаем интервал и тоже включаем звук, чтобы обозначить смену режима:

    
language: JavaScript
// что будет, если мы нажмём на кнопку «Пауза»

$('#timer_pause').click(function(event, params) {

   

   // если кнопка сработала нормально

   if(params !== undefined) {

       

       // но аудиопараметры ещё не задавались

       if(params.audio === undefined) {

           

           // задаём параметры оповещения

           params.audio = 1;

       }

   }

       

       // иначе сразу задаём параметры звука

   else {

       params = {audio: 1};

   }

   

   // после нажатия на кнопку «Пауза» делаем её невидимой

   $(this).addClass('hide');

   

   // а кнопку «Старт» — наоборот, видимой

   $('#timer_run').removeClass('hide');

   

   // останавливаем таймер

   clearInterval(intervalVariable);

   

   // если со звуком всё в порядке

   if(params.audio) {

       

       // проигрываем звуковое оповещение

       $('#audio_beep')[0].play();

   }

   

   // выходим из функции

   return false;

   });


Скопировать код

Код скопирован

Последнее, что осталось — запрограммировать реакцию на нажатие кнопки «Сброс». Порядок действий будет такой: виртуально щёлкаем по кнопке «Пауза», обнуляем табло, и выставляем стартовые значения по умолчанию в нашу панель настроек:

    
language: JavaScript
// что будет, если нажмём на кнопку «Сброс»

$('#timer_clear').click(function() {

   

   // имитируем нажатие на кнопку «Пауза», чтобы остановить таймер

   $('#timer_pause').trigger('click', {audio: 0});

   

   // ставим режим тренировки

   interval_type = 'work';

   

   // убираем красный цвет на табло, которое там осталось от включения паузы

   $('.timer_panel_nums .timer_nums').removeClass('green red');

   

   // обнуляем табло

   renderTimerNums(0);

   

   // обнуляем значения служебных переменных

   now_seconds = 0;

   now_times = 0;

   

   // задаём начальное значение первого блока секунд

   seconds_1 = 25;

   

   // устанавливаем начальные значения времени тренировки, отдыха и количества повторов

   $('.timer_interval_work .minutes').text('00');

   $('.timer_interval_work .seconds').text('25');

   $('.timer_interval_rest .minutes').text('00');

   $('.timer_interval_rest .seconds').text('05');

   $('.timer_interval_count .times').text('1');

   $('.timer_interval_count .all_times').text('10');

   

   // выходим из функции

   return false;

   });


Скопировать код

Код скопирован

Теперь собираем скрипт в один файл, сохраняем, обновляем нашу страницу и нажимаем на «Старт». Всё, успех — таймер начал отсчёт:


Если у вас не получилось всё правильно собрать в один файл и запустить — ничего страшного. Мы сами уже сделали это за вас и упаковали все нужные файлы в один архив. Вам нужно его скачать, распаковать и запустить файл int.html.

Ещё по теме