内容简介:这是关于时间的。在本文中,我们将接受创建和设置时钟动画的挑战,使用简单的CSS动画和JavaScript来触发它们。这是我们使用HTML,CSS,SVG背景和一些JavaScript创建的时钟。我们将使用CSS动画或过渡进行任何移动,并依靠JavaScript来设置初始时间并添加基本的CSS变换。要开始使用,我们需要一些HTML。
这是关于时间的。在本文中,我们将接受创建和设置时钟动画的挑战,使用简单的CSS动画和JavaScript来触发它们。
这是我们使用HTML,CSS,SVG背景和一些JavaScript创建的时钟。我们将使用CSS动画或过渡进行任何移动,并依靠JavaScript来设置初始时间并添加基本的CSS变换。
HTML
要开始使用,我们需要一些HTML。
<article class="clock"> <div class="hours-container"> <div class="hours"></div> </div> <div class="minutes-container"> <div class="minutes"></div> </div> <div class="seconds-container"> <div class="seconds"></div> </div> </article> 复制代码
我最初的方法是为每只指针使用三个元素。然后我回去把每个包装在一个容器元素中。虽然简单的HTML可以用于基本的CSS动画,但是当我们想要定位指针并为它们制作动画时,我们还需要包含元素。
钟面
我们将从一个基本的时钟设计开始,圆脸,简单的小时,分钟和秒针。
.clock { border-radius: 50%; background: #fff url(/images/posts/clocks/ios_clock.svg) no-repeat center; background-size: 88%; height: 20em; padding-bottom: 31%; position: relative; width: 20em; } .clock.simple:after { background: #000; border-radius: 50%; content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 5%; height: 5%; z-index: 10; } 复制代码
你可以在这里获得SVG背景。我还添加了一个伪元素来向中心添加一个纯黑色圆圈。然后可以根据需要将时钟的指针放在该伪元素后面。
我们现在应该有这样的结果。
在添加指针之前,我们需要放置容器。
.minutes-container, .hours-container, .seconds-container { position: absolute; top: 0; right: 0; bottom: 0; left: 0; } 复制代码
这会将每个容器堆叠在时钟之上。接下来我们创造指针。
时针
每只指针都被赋予 absolute
属性值并放置在十二点钟位置。我们将从时针开始。
.hours { background: #000; height: 20%; left: 48.75%; position: absolute; top: 30%; transform-origin: 50% 100%; width: 2.5%; } 复制代码
我正在使用百分比来简化时钟缩放。这是一项复杂的工作,但能让它们更容易适应视图或缩小手机。我们还将 transform-origin
属性设置为指针的底部,以便以后可以旋转。
分针
分针跟时针类似,但更长更细。
.minutes { background: #000; height: 40%; left: 49%; position: absolute; top: 10%; transform-origin: 50% 100%; width: 2%; } 复制代码
秒针
秒针再次变细,但也进一步向下设置,使其比中心延伸得更远。为此, transform-origin
为80%。这使得20%的手伸出中心。
.seconds { background: #000; height: 45%; left: 49.5%; position: absolute; top: 14%; transform-origin: 50% 80%; width: 1%; z-index: 8; } 复制代码
动画
停止的时钟每天只能正确两次。让我们添加一些动画来让时钟表现得更像真实的东西。
有些时钟会随着每秒跳跃,通常会产生滴答声。有些时钟会随着手的平稳移动而发出呜呜声。我们两个都试试。首先,我们会让双手平稳移动。
我们可以使用一个 keyframe
来指示手在360度左右移动(暗示0%的起始位置)。
@keyframes rotate { 100% { transform: rotateZ(360deg); } } 复制代码
如果使用 animation
属性应用于元素,则此关键帧会告诉元素在360度左右设置动画。我们将在指针上使用 linear
计时功能,使指针平稳移动。
.hours-container { animation: rotate 43200s infinite linear; } .minutes-container { animation: rotate 3600s infinite linear; } .seconds-container { animation: rotate 60s infinite linear; } 复制代码
时针设置为每12小时(43,400秒)旋转一次。分针每小时旋转一次,秒针每分钟旋转一次。
把它放在一起,我们现在有运动!
如果你的眼睛非常敏锐,你甚至可以让分针移动。它需要一个小时才能完成一个旋转,十二个小时的时间来完成它的循环。
秒针需要60秒,因此更容易注意到。
添加停顿
通过让秒针在60个单独的动作中全天候移动,我们可以让指针更像普通时钟。实现此目的的一种简单方法是使用 steps
计时功能。然后每只指针的 animation
属性变为:
.minutes-container { animation: rotate 3600s infinite steps(60); } .seconds-container { animation: rotate 60s infinite steps(60); } 复制代码
分针和秒针现在分六步走动。浏览器会自动计算这60个步骤中的每个步骤移动的距离。
正确的时间
一切都很好,时间看起来不错,但准确度如何呢?使用一点JavaScript,我们可以让时间对我们的访问者来说是正确的。这是代码:
/* * Starts any clocks using the user's local time * From: cssanimation.rocks/clocks */ function initLocalClocks() { // Get the local time using JS var date = new Date; var seconds = date.getSeconds(); var minutes = date.getMinutes(); var hours = date.getHours(); // Create an object with each hand and it's angle in degrees var hands = [ { hand: 'hours', angle: (hours * 30) + (minutes / 2) }, { hand: 'minutes', angle: (minutes * 6) }, { hand: 'seconds', angle: (seconds * 6) } ]; // Loop through each of these hands to set their angle 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 this is a minute hand, note the seconds position (to calculate minute position later) if (hands[j].hand === 'minutes') { elements[k].parentNode.setAttribute('data-second-angle', hands[j + 1].angle); } } } } 复制代码
此功能将时间(小时,分钟和秒)转换为每只指针的相应角度。然后循环遍历每只手并使用 rotateZ
的 style.transform
属性应用该角度。
这适用于除Safari或其他需要前缀的浏览器之外的大多数浏览器。为此,我们还使用了 style.webkitTransform
属性。
然后,将时钟设置为当前系统时间。
对齐秒针和分针
当首次在屏幕上绘制时钟时,在分针需要移动之前不到一分钟。为了实现这一点,我们可以计算出第一分钟结束的时间并手动轻推分针。由于我们使用JavaScript进行第一次移动,我们可以使用 setInterval
每分钟继续旋转6度。
在我们移动分针之前,我们需要告知我们当前的分钟数。您可能已经注意到这些线条。
if (hands[j].hand === 'minutes') { elements[k].parentNode.setAttribute('data-second-angle', hands[j + 1].angle); } 复制代码
这些额外的行检查指针是否是“分钟”指针,如果是,则使用秒针的当前角度设置数据属性。
使用此数据属性集,我们可以使用此数据计算何时移动分针。
/* * Set a timeout for the first minute hand movement (less than 1 minute), then rotate it every minute after that */ function setUpMinuteHands() { // Find out how far into the minute we are var containers = document.querySelectorAll('.minutes-container'); var secondAngle = containers[0].getAttribute("data-second-angle"); if (secondAngle > 0) { // Set a timeout until the end of the current minute, to move the hand var delay = (((360 - secondAngle) / 6) + 0.1) * 1000; setTimeout(function() { moveMinuteHands(containers); }, delay); } } /* * Do the first minute's rotation */ function moveMinuteHands(containers) { for (var i = 0; i < containers.length; i++) { containers[i].style.webkitTransform = 'rotateZ(6deg)'; containers[i].style.transform = 'rotateZ(6deg)'; } // Then continue with a 60 second interval 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来移动分针,我们应该删除动画属性。我们可以用过渡替换它,而不是简单地删除它。这是一个为动画添加更多角色的机会。
当JavaScript为手设置新角度时,元素上的CSS转换将告诉浏览器为此新位置设置动画。这意味着JavaScript只处理简单的角度变化,浏览器可以处理它的动画。
在我们这样做之前,我们应该更新代码以使用JavaScript来移动秒针。让我们使用此代码为秒针容器设置动画,每分钟动画60次。
/* * Move the second containers */ 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以使用 transitions
替换 animation
属性。
.minutes-container { transition: transform 0.3s cubic-bezier(.4,2.08,.55,.44); } .seconds-container { transition: transform 0.2s cubic-bezier(.4,2.08,.55,.44); } 复制代码
这些转换适用于 transform
属性并使用 cubic-bezier
定时函数。这个计时功能让秒针有些反弹。
iOS7 风格
我非常喜欢Apple iOS 7中使用的时钟的简单性。他们已经伸长了指针,但我更喜欢较短的版本。
通过设计针部样式并添加带有数字的背景图像,我们可以轻松创建此外观。
这种设计本身就是Hans Hilfiker对瑞士铁路时钟的演变。通过改变一些样式并添加新的背景图像,我们可以使我们的时钟适应这种风格。
如果您想出其他设计,请告诉我。
使用 Moment.js
我计划这篇文章的第一个想法之一是重建酒店钟表场景,三个时钟显示不同的时区。
调整不同时区的最简单方法是使用令人惊叹的Moment.js 时区库。
您可以在此Codepen上查看代码。
浏览器兼容性
现代浏览器可以处理所涉及的CSS过渡和动画。 IE10 +,最近的Chrome和Firefox支持它们没有前缀,Safari需要 -webkit
前缀。
不要忘记在JavaScript中使用前缀属性。
(完)
本文作者 Thinker
本文如有错误之处,请留言,我会及时更正
觉得对您有帮助的话就 点个赞 或 收藏 吧!
欢迎转载或分享,转载时请注明出处
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- JavaScript牛刀小试,结合CSS3动画属性来做一个系统时间同步的时钟
- 分布式系统:向量时钟
- 分布式系统:向量时钟
- 电子纸时钟的一些后续
- 分布式系统:Lamport 逻辑时钟
- Canvas案例-炫酷的数字时钟
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Pro CSS Techniques
Jeff Croft、Ian Lloyd、Dan Rubin / Apress / 2009-5-4 / GBP 31.49
Web Standards Creativity: Innovations in Web Design with CSS, DOM Scripting, and XHTML一起来看看 《Pro CSS Techniques》 这本书的介绍吧!