Главная->Уроки по css->Секундомер на чистом CSS3
Секундомер на чистом CSS3
В данном уроке мы сделаем секундомер с использованием только CSS3. Для реализации идеи будут применяться кадры анимации CSS3 и свойство управления состоянием анимации (для функционирования кнопок управления секундомером). Изображение будет использоваться только в качестве фона (исключительно с эстетическими целями). А JavaScript применяется в виде плагина prefixfree - для уменьшения размера кода и повышения наглядности за счет исключения префиксов браузеров. Для логики и вывода секундомера не задействовано ни каких изображений и ни строчки JavaScript. Построение основы В основе логики работы нашего примера лежит простой элемент div, который содержит цифры, сменяющиеся с помощью анимации. Между цифрами имеются пробелы, так что их легко выровнять по вертикали уменьшив ширину контейнера. 1 <div">0 1 2 3 4 5 6 7 8 9</div> Затем обернем наш простой элемент в дополнительный контейнер, чтобы выводить только одну цифру: 1 <div class="cell"> 2 <div class="numbers">0 1 2 3 4 5 6 7 8 9</div> 3 </div> Для вывода нашей цифры используем следующие стили: 01 .cell { 02 /*Нужно выводить только одну цифру. Поэтому высота = высоте строки в классе .numbers 03 а ширина = ширине .numbers*/ 04 width: 0.60em; 05 height: 40px; 06 border: 1px solid #000; 07 font-size: 50px; 08 overflow: hidden; 09 } 10 11 .numbers { 12 width: 0.6em; 13 line-height: 40px; 14 font-family: digital, arial, verdana; 15 text-align: center; 16 } 17 18 19 20 /* Используем шрифт с более подходящим моменту начертанием*/ 21 @font-face { 22 font-family: 'digital'; 23 src: url('../fonts/DS-DIGI.TTF'); 24 25 } Теперь добавим анимации к нашей цифре. Логика работы заключается в изменении значения свойства top для абсолютно позиционируемого класса numbers. Также для анимации нужно установить шаги с длительностью 1 секунда, чтобы цифры сменяли друг друга. 01 .cell { 02 /*Нужно выводить только одну цифру. Поэтому высота = высоте строки в классе .numbers 03 а ширина = ширине .numbers*/ 04 width: 0.60em; 05 height: 40px; 06 border: 1px solid #000; 07 font-size: 50px; 08 overflow: hidden; 09 position: relative; 10 } 11 12 .numbers { 13 width: 0.6em; 14 line-height: 40px; 15 font-family: digital, arial, verdana; 16 text-align: center; 17 18 position: absolute; 19 top: 0; 20 left: 0; 21 /* Используем шаги для анимации, чтобы обеспечить смену цифр. 22 10 цифр = 10 шагов*/ 23 animation: move 1s steps(10, end) infinite; 24 25 } 26 27 /* Логика работы заключается в смене значения свойства top */ 28 @keyframes move { 29 0% {top: 0;} 30 100% {top: -400px;} 31 /*height = 40. digits = 10. hence -400 to move it completely to the top*/ 32 } Создаем секундомер Теперь просто копируем столько цифр для секундомера, сколько нужно. Для соответствующих позиций присваиваем классы секунд, минут, часов. Добавляем разделитель между группами цифр. Также все цифры заключаем в один контейнер и устанавливаем смещение цифр влево, для выравнивания их по горизонтали. 01 <div class="timer"> 02 <div class="cell"> 03 <div class="numbers tenhour">0 1 2 3 4 5 6 7 8 9</div> 04 </div> 05 <div class="cell"> 06 <div class="numbers hour">0 1 2 3 4 5 6 7 8 9</div> 07 </div> 08 <div class="cell divider"><div class="numbers">:</div></div> 09 <div class="cell"> 10 <div class="numbers tenminute">0 1 2 3 4 5 6 7 8 9</div> 11 </div> 12 <div class="cell"> 13 <div class="numbers minute">0 1 2 3 4 5 6 7 8 9</div> 14 </div> 15 <div class="cell divider"><div class="numbers">:</div></div> 16 <div class="cell"> 17 <div class="numbers tensecond">0 1 2 3 4 5 6 7 8 9</div> 18 </div> 19 <div class="cell"> 20 <div class="numbers second">0 1 2 3 4 5 6 7 8 9</div> 21 </div> 22 <div class="cell divider"><div class="numbers">:</div></div> 23 <div class="cell"> 24 <div class="numbers hundredmilisecond">0 1 2 3 4 5 6 7 8 9</div> 25 </div> 26 <div class="cell"> 27 <div class="numbers tenmilisecond">0 1 2 3 4 5 6 7 8 9</div> 28 </div> 29 <div class="cell"> 30 <div class="numbers milisecond">0 1 2 3 4 5 6 7 8 9</div> 31 </div> 32 </div> Минут и секунд всего 60. Поэтому надо сделать два вида анимаций - с 10 цифрами и 10 шагами и с 6 цифрами и 6 шагами. 01 .moveten { 02 animation: moveten 1s steps(10, end) infinite; 03 } 04 05 .movesix { 06 animation: movesix 1s steps(6, end) infinite; 07 } 08 09 @keyframes moveten { 10 0% {top: 0;} 11 100% {top: -400px;} 12 /*Высота = 40. Цифр = 10. Полное смещение до верха -400 */ 13 } 14 15 @keyframes movesix { 16 0% {top: 0;} 17 100% {top: -240px;} 18 /*Высота = 40. Цифр = 6. Полное смещение до верха -240 */ 19 } Соответственно изменяем набор классов у цифр в структуре нашего секундомера: 01 <div class="timer"> 02 <div class="cell"> 03 <div class="numbers tenhour moveten">0 1 2 3 4 5 6 7 8 9</div> 04 </div> 05 <div class="cell"> 06 <div class="numbers hour moveten">0 1 2 3 4 5 6 7 8 9</div> 07 </div> 08 <div class="cell divider"><div class="numbers">:</div></div> 09 <div class="cell"> 10 <div class="numbers tenminute movesix">0 1 2 3 4 5 6</div> 11 </div> 12 <div class="cell"> 13 <div class="numbers minute moveten">0 1 2 3 4 5 6 7 8 9</div> 14 </div> 15 <div class="cell divider"><div class="numbers">:</div></div> 16 <div class="cell"> 17 <div class="numbers tensecond movesix">0 1 2 3 4 5 6</div> 18 </div> 19 <div class="cell"> 20 <div class="numbers second moveten">0 1 2 3 4 5 6 7 8 9</div> 21 </div> 22 <div class="cell divider"><div class="numbers">:</div></div> 23 <div class="cell"> 24 <div class="numbers hundredmilisecond moveten">0 1 2 3 4 5 6 7 8 9</div> 25 </div> 26 <div class="cell"> 27 <div class="numbers tenmilisecond moveten">0 1 2 3 4 5 6 7 8 9</div> 28 </div> 29 <div class="cell"> 30 <div class="numbers milisecond moveten">0 1 2 3 4 5 6 7 8 9</div> 31 </div> 32 </div> Теперь нужно синхронизировать вывод цифр по времени. Логика здесь простая. На одну цифру тратиться столько времени, сколько соответствует ее положению в секундомере, а в счетчике имеется 10 или 6 цифр. Соответственно длительность соответствующей анимации вычисляется по формуле ПОЛОЖЕНИЕ ЦИФРЫ * КОЛИЧЕСТВО ЦИФР В СЧЕТЧИКЕ. 01 .second {animation-duration: 10s;} 02 .tensecond {animation-duration: 60s;} /*60 раз.second*/ 03 04 .milisecond {animation-duration: 1s;} /*1/10 от .second*/ 05 .tenmilisecond {animation-duration: 0.1s;} 06 .hundredmilisecond {animation-duration: 0.01s;} 07 08 .minute {animation-duration: 600s;} /*60 раз .second*/ 09 .tenminute {animation-duration: 3600s;} /*60 раз .minute*/ 10 11 .hour {animation-duration: 36000s;} /*60 раз .minute*/ 12 .tenhour {animation-duration: 360000s;} /*10 раз .hour*/ Добавляем элементы управления Для управления секундомером будем использовать радио кнопки. Добавляем в структуру разметки кнопки и метки для них: 01 <div class="container"> 02 <!-- Элементы управления --> 03 <input id="start" name="controls" type="radio" /> 04 <input id="stop" name="controls" type="radio" /> 05 <input id="reset" name="controls" type="radio" /> 06 <div class="timer"> 07 <div class="cell"> 08 <div class="numbers tenhour moveten">0 1 2 3 4 5 6 7 8 9</div> 09 </div> 10 <div class="cell"> 11 <div class="numbers hour moveten">0 1 2 3 4 5 6 7 8 9</div> 12 </div> 13 <div class="cell divider"><div class="numbers">:</div></div> 14 <div class="cell"> 15 <div class="numbers tenminute movesix">0 1 2 3 4 5 6</div> 16 </div> 17 <div class="cell"> 18 <div class="numbers minute moveten">0 1 2 3 4 5 6 7 8 9</div> 19 </div> 20 <div class="cell divider"><div class="numbers">:</div></div> 21 <div class="cell"> 22 <div class="numbers tensecond movesix">0 1 2 3 4 5 6</div> 23 </div> 24 <div class="cell"> 25 <div class="numbers second moveten">0 1 2 3 4 5 6 7 8 9</div> 26 </div> 27 <div class="cell divider"><div class="numbers">:</div></div> 28 <div class="cell"> 29 <div class="numbers milisecond moveten">0 1 2 3 4 5 6 7 8 9</div> 30 </div> 31 <div class="cell"> 32 <div class="numbers tenmilisecond moveten">0 1 2 3 4 5 6 7 8 9</div> 33 </div> 34 <div class="cell"> 35 <div class="numbers hundredmilisecond moveten">0 1 2 3 4 5 6 7 8 9</div> 36 </div> 37 </div> 38 <!-- Метки для кнопок элементов управления --> 39 <div id="timer_controls"> 40 <label for="start">Start</label> 41 <label for="stop">Stop</label> 42 <label for="reset">Reset</label> 43 </div> 44 </div> Задаем стили для кнопок и меток и определяем функционал с помощью свойства animation-play-state. Также по умолчанию нужно остановить анимацию. 01 #timer_controls { 02 margin-top: -5px; 03 } 04 #timer_controls label { 05 cursor: pointer; 06 padding: 5px 10px; 07 background: #efefef; 08 font-family: arial, verdana, tahoma; 09 font-size: 11px; 10 border-radius: 0 0 3px 3px; 11 } 12 input[name="controls"] {display: none;} 13 14 /* Функционал элементов управления */ 15 #stop:checked~.timer .numbers {animation-play-state: paused;} 16 #start:checked~.timer .numbers {animation-play-state: running;} 17 #reset:checked~.timer .numbers {animation: none;} 18 19 .moveten { 20 animation: moveten 1s steps(10, end) infinite; 21 /* По умолчанию анимация остановлена */ 22 animation-play-state: paused; 23 } 24 .movesix { 25 animation: movesix 1s steps(6, end) infinite; 26 /* По умолчанию анимация остановлена */ 27 animation-play-state: paused; 28 }