- Часы (на CSS-анимации и JavaScript)
- HTML
- Циферблат
- Часовая стрелка
- Минутная стрелка
- Секундная стрелка
- Анимация
- Добавление «шагов»
- Установка правильного времени
- Установка положения секундной и минутной стрелок
- Добавление отскока
- Часы в стиле iOS 7
- Использование Moment.js
- Поддержка браузерами
- P.S. Это тоже может быть интересно:
- Аналоговые часы на JavaScript
- В нашем проекте нужны следующие файлы:
- index.html
- style.css
- script.js
- Рабочий результат часов на JavaScript
- Видео с пошаговой инструкцией как сделать рабочие аналоговые часы на JavaScript
Часы (на CSS-анимации и JavaScript)
Время пришло. В этой статье мы попробуем решить задачу по созданию и анимированию настенных часов, используя простые CSS-анимации и JavaScript для их запуска.
Перед вами часы, которые мы создадим с помощью HTML, CSS, SVG-фона и небольшого количества JavaScript. Мы будем использовать CSS-анимации или переходы для любых типов движений, а с помощью JavaScript мы будем задавать исходное время и добавим базовые CSS-трансформации.
HTML
Для начала нам понадобится немного HTML.
Изначально я хотел использовать три элемента (по одному для каждой из стрелок). Но затем передумал и поместил каждую стрелку в элемент-контейнер. Несмотря на то, что более простой HTML-код подошел бы для базовых CSS-анимаций, элементы-контейнеры понадобятся нам, если мы захотим анимировать и устанавливать положение стрелок.
Циферблат
Начнем с обычных часов с круглым циферблатом и простыми стрелками (часовой, минутной и секундной).
Вы можете скачать SVG-фон здесь. Кроме того, я добавил к нему псевдоэлемент для создания в центре сплошной черной окружности. После этого мы можем расположить стрелки за этим псевдоэлементом так, как нам будет необходимо.
В результате у нас должно получиться что-то вроде этого.
Перед добавлением стрелок нам нужно расположить контейнеры.
.minutes-container, .hours-container, .seconds-container
Таким образом мы расположим каждый из контейнеров над циферблатом. После этого мы создадим стрелки.
Часовая стрелка
Свойству «position» у каждой стрелки присваивается значение absolute , и она помещается в позицию «12 часов». Начнем с часовой стрелки.
Я использую значения в процентах, чтобы упростить задачу масштабирования часов. Для этого нужно потратить немного больше сил, но зато результат всегда легко подогнать под размеры области просмотра или уменьшить под экраны мобильных устройств. Мы также переносим точку вращения стрелки в нижнюю часть с помощью свойства transform-origin , что позволит нам поворачивать стрелку.
Минутная стрелка
Минутная стрелка похожа на часовую, но она длиннее и тоньше.
Секундная стрелка
Секундная стрелка еще тоньше. Кроме того, она находится ниже, выходя за пределы центра. Для этого мы задаем свойству transform-origin значение 80%. Теперь 20% стрелки выходят за пределы центра.
Анимация
Остановившиеся часы показывают правильное время лишь дважды в день. Давайте добавим немного анимации, чтобы наши часы больше походили на настоящие.
Некоторые часы подскакивают каждую секунду, издавая при этом тикающий звук. Некоторые часы тихо мурлычат, а их стрелки движутся очень плавно. Мы попробуем оба варианта. Для начала заставим стрелки двигаться плавно.
Мы можем задать один ключевой кадр с помощью свойства keyframes , чтобы заставить стрелки выполнять оборот в 360 градусов (их начальное положение при этом принимается за 0%).
Этот ключевой кадр сообщает элементу, что тот должен выполнить анимацию поворота на 360 градусов, если кадр был применен к элементу с помощью свойства animation . Мы применим к стрелкам временную функцию типа linear (линейная), чтобы заставить их двигаться плавно.
.hours-container < animation: rotate 43200s infinite linear; >.minutes-container < animation: rotate 3600s infinite linear; >.seconds-container
Часовая стрелка hours установлена на выполнение полного оборота за 12 часов (43 200 секунд). Минутная стрелка делает один оборот за час, а секундная — за одну минуту.
Соберем все вместе, и у нас готова анимация движения!
Если у вас очень острое зрение, то вы даже можете заметить, как движется минутная стрелка. Для полного оборота ей понадобится час, а часовой стрелке для полного оборота понадобится 12 часов.
Секундная стрелка делает оборот за 60 секунд, поэтому ее движение заметить проще.
Добавление «шагов»
Чтобы движение наших стрелок больше напоминало настоящие часы, мы можем заставить секундную стрелку делать полный оборот за 60 отдельных движений. Сделать это просто. Используем временную функцию steps (шаги). В этом случае свойство animation для каждой из стрелок будет выглядеть следующим образом:
.minutes-container < animation: rotate 3600s infinite steps(60); >.seconds-container
Теперь и минутная, и секундная стрелки выполняют полный оборот за 60 шагов. Браузер автоматически рассчитывает, насколько большим должен быть каждый из этих 60 шагов.
Установка правильного времени
Конечно, здорово, когда часы выглядят симпатично, но как заставить их показывать правильное время? Добавив немного JavaScript, мы можем показывать нашим пользователям корректное время. Вот нужный нам код.
/* * Устанавливает точку отсчета любых часов в соответствии с местным временем пользователя * С сайта: cssanimation.rocks/clocks */ function initLocalClocks() < // Узнать местное время с помощью JS var date = new Date; var seconds = date.getSeconds(); var minutes = date.getMinutes(); var hours = date.getHours(); // Создать объект, хранящий все стрелки и их углы в градусах var hands = [ < hand: 'hours', angle: (hours * 30) + (minutes / 2) >, < hand: 'minutes', angle: (minutes * 6) >, < hand: 'seconds', angle: (seconds * 6) >]; // С помощью цикла установить угол для каждой из стрелок for (var j = 0; j < hands.length; j++) < var elements = document.querySelectorAll('.' + hands[j].hand); for (var k = 0; k < elements.length; k++) < elements[k].style.webkitTransform = 'rotateZ('+ hands[j].angle +'deg)'; elements[k].style.transform = 'rotateZ('+ hands[j].angle +'deg)'; // Если это минутная стрелка, сохранить положение секундной стрелки (для дальнейшего расчета положения минутной стрелки) if (hands[j].hand === 'minutes') < elements[k].parentNode.setAttribute('data-second-angle', hands[j + 1].angle); >> > >
Данная функция преобразует время (часы, минуты и секунды) в соответствующий угол для каждой из стрелок. После этого мы в цикле устанавливаем каждой из стрелок нужную величину угла с помощью свойства style.transform со значением rotateZ .
Этот подход сработает в большинстве браузеров, кроме Сафари и тех браузеров, которые требуют использования браузерных префиксов. Для их поддержки мы используем свойство style.webkitTransform .
Таким образом мы устанавливаем часам текущее системное время.
Установка положения секундной и минутной стрелок
Нам нужно убедиться, что движение минутной стрелки происходит, когда секундная стрелка проходит отметку «12 часов».
Когда часы впервые отрисовываются на экране, время до следующего движения минутной стрелки меньше одной минуты. Для решения этой задачи мы можем рассчитать, сколько секунд осталось до конца этой минуты, и вручную передвинуть стрелку. Раз уж мы использовали JavaScript для первого движения стрелки, мы можем и дальше поворачивать ее на шесть градусов каждую минуту с помощью метода setInterval .
Перед тем, как мы передвинем минутную стрелку, нам нужно сообщить, сколько прошло секунд с начала текущей минуты. Вы могли обратить внимание на эти строки.
Они нужны для проверки, является ли стрелка «минутной», и если да, то ей устанавливается атрибут «data» с текущим углом секундной стрелки.
Установив атрибут «data», мы можем использовать эти данные, чтобы вычислить, когда нужно передвинуть минутную стрелку.
/* * Установить таймаут для первого движения минутной стрелки (меньше 1 минуты), после чего поворачивать ее каждую минуту */ function setUpMinuteHands() < // Вычислить, сколько секунд прошло с начала этой минуты var containers = document.querySelectorAll('.minutes-container'); var secondAngle = containers[0].getAttribute("data-second-angle"); if (secondAngle >0) < // Установить таймаут до конца текущей минуты, чтобы передвинуть стрелку var delay = (((360 - secondAngle) / 6) + 0.1) * 1000; setTimeout(function() < moveMinuteHands(containers); >, delay); > > /* * Выполнить первый поворот минутной стрелки */ function moveMinuteHands(containers) < for (var i = 0; i < containers.length; i++) < containers[i].style.webkitTransform = 'rotateZ(6deg)'; containers[i].style.transform = 'rotateZ(6deg)'; >// После этого продолжить с интервалом в 60 секунд setInterval(function() < for (var i = 0; i < containers.length; i++) < if (containers[i].angle === undefined) < containers[i].angle = 12; >else < containers[i].angle += 6; >containers[i].style.webkitTransform = 'rotateZ('+ containers[i].angle +'deg)'; containers[i].style.transform = 'rotateZ('+ containers[i].angle +'deg)'; > >, 60000); >
Добавление отскока
Поскольку для перемещения минутной стрелки мы теперь используем JavaScript, нам следует убрать свойство ‘animation’. Вместо того, чтобы просто его удалить, мы можем заменить его на ‘transition’. Это позволит нам добавить в анимацию немного оригинальности.
В момент установки стрелке нового угла с помощью JavaScript, CSS-переход элемента будет заставлять браузер анимировать его новое положение. Это значит, что JavaScript будет заниматься лишь простым изменением угла, а браузер займется его анимацией.
Перед тем как сделать это, нам нужно усовершенствовать код, чтобы начать использовать JavaScript и для перемещения секундной стрелки. Давайте используем этот код для анимации контейнера секундной стрелки 60 раз в минуту.
/* * Перемещение контейнера секундной стрелки */ function moveSecondHands() < var containers = document.querySelectorAll('.seconds-container'); setInterval(function() < for (var i = 0; i < containers.length; i++) < if (containers[i].angle === undefined) < containers[i].angle = 6; >else < containers[i].angle += 6; >containers[i].style.webkitTransform = 'rotateZ('+ containers[i].angle +'deg)'; containers[i].style.transform = 'rotateZ('+ containers[i].angle +'deg)'; > >, 1000); >
Теперь, когда секундной и минутной стрелкой занимается JavaScript, обновим CSS, заменив свойства animation на transition .
.minutes-container < transition: transform 0.3s cubic-bezier(.4,2.08,.55,.44); >.seconds-container
Эти переходы будут применяться к свойству transform и в них используется временная функция cubic-bezier (кубическая-Безье). Эта временная функция добавляет стрелке небольшой отскок.
Часы в стиле iOS 7
Я большой поклонник минимализма часов, использованных в iOS 7 у Apple. С тех пор они увеличили длину стрелок, но мне нравится более короткая версия.
Задав стиль стрелкам и добавив фон с цифрами, мы можем с легкостью воссоздать этот образ.
Сам по себе этот дизайн является эволюцией Швейцарских железнодорожных часов Ганса Хильфикера. Немного изменив стиль и добавив новое фоновое изображение, мы можем адаптировать наши часы под этот стиль.
Если вы придумаете другие варианты, дайте мне знать.
Использование Moment.js
Одной из идей, появившихся, когда я решил написать этот пост, было воссоздание образа часов в отеле, когда трое часов показывают разные временные пояса.
Самым простым способом настроить часы на разные временные пояса является использование великолепной библиотеки Moment.js Timezone .
Работу этого кода вы можете увидеть на Codepen.
Поддержка браузерами
Современные браузеры умеют работать с использованными в этой статье CSS-переходами и анимациями. IE10+, последние версии Chrome и Firefox поддерживают их без префиксов, а Safari требует префикса -webkit .
Не забывайте использовать свойства с префиксами и в JavaScript.
P.S. Это тоже может быть интересно:
Если вам понравилась статья, поделитесь ей!
Аналоговые часы на JavaScript
Всем привет! В этой статье я расскажу, как сделать рабочие аналоговые часы на JavaScript.
Научившись делать такие часы Вы сможете написать для себя аналоговые часы с любым дизайном.
В нашем проекте нужны следующие файлы:
Чтобы скачать нужный фаил нажмите на него.
- index.html – файл с необходимой разметкой
- style.css – файл стилей наших часиков
- script.js – файл с функционалом наших часов
- clock.png – циферблат
- js.png – картинка для оформление циферблата
index.html
style.css
* < margin: 0; padding: 0; box-sizing: border-box; >body < display: flex; justify-content: center; align-items: center; min-height: 100vh; background: #091921; >.clock < width: 350px; height: 350px; display: flex; justify-content: center; align-items: center; background: url(clock.png), url(js.png), radial-gradient(circle, rgb(37, 73, 90) 0%, rgb(25, 48, 60) 11%, rgba(9,25,33,1) 38%); background-size: cover; border-radius: 50%; box-shadow: 0 -15px 15px rgba(134, 134, 134, 0.35), inset 0 -15px 15px #191919, 0 15px 15px rgba(134, 134, 134, 0.35), inset 0 15px 15px #191919 ; >.clock:before < content: ''; position: absolute; width: 15px; height: 15px; background-color: #ffffff; border-radius: 50%; z-index: 999; >.clock .hour, .clock .min, .clock .sec < position: absolute; >.clock .hour, .hr < width: 160px; height: 160px; >.clock .min, .mn < width: 190px; height: 190px; >.clock .sec, .sc < width: 230px; height: 230px; >.hr, .mn, .sc < display: flex; justify-content: center; position: absolute; border-radius: 50%; >.hr:before < content: ''; position: absolute; width: 8px; height: 80px; background-color: #ffc600; z-index: 10; border-radius: 6px 6px 0 0; >.mn:before < content: ''; position: absolute; width: 4px; height: 90px; background-color: #fff; z-index: 11; border-radius: 6px 6px 0 0; >.sc:before
script.js
const deg = 6; const hr = document.querySelector('#hr'); const sc = document.querySelector('#sc'); setInterval(() => < let day = new Date(); let hh = day.getHours() * 30; let mm = day.getMinutes() * deg; let ss = day.getSeconds() * deg; hr.style.transform = `rotateZ($deg)`; mn.style.transform = `rotateZ($deg)`; sc.style.transform = `rotateZ($deg)`; >)
Рабочий результат часов на JavaScript
See the Pen vYOaqEr by AntonAniskovich (@AntonAniskovich) on CodePen.
Видео с пошаговой инструкцией как сделать рабочие аналоговые часы на JavaScript
Дорогие друзья если Вам понравилась статья и Вы хотите меня поддержать, то подписывайтесь на мой блог и канал на youtube. Это для меня самая лучшая благодарность. Всем до новых встреч.