时钟——CSS 动画
译者注:本文内容为 Clocks - CSS Animation 的译文
译者在编写文章过程中写了 一份最终效果(iOS7 风格)源代码 供大家参考
时钟
这是关于时间的。在本文中,我们将接受创建和设置时钟动画的挑战,使用简单的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 JSvar 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 degreesvar 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 anglefor (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 arevar 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 handvar 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 intervalsetInterval(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
本文如有错误之处,请留言,我会及时更正
觉得对您有帮助的话就点个赞或收藏吧!
欢迎转载或分享,转载时请注明出处
阅读原文
时钟——CSS 动画相关推荐
- CSS动画篇之炫酷时钟之时钟墙
通过CSS制作的时钟大家肯定看到的多了,但是像下面这样的时钟是不是很少见,整个时钟是有很多个小的时钟组合而成,每秒通过多个时钟的动画来切换时间,不得不说这个设计是非常的炫酷且有特色. 前言 看到这个动 ...
- 时钟插件-CSS动画+jQuery
使用HTML,CSS,SVG背景和一些jquery创建的时钟.使用CSS动画和过渡进行移动,使用jquery来设置初始时间并添加基本的CSS变换 最终效果展示 首先创建一个div用来展示生成的时钟 & ...
- 前端技术周刊 2019-01-07:CSS 动画
2019-01-07 前端快爆 Chrome 72 已经进入了 beta 阶段.新增:公有类成员的声明和初始化.一些 DevTools 新功能(可视化性能指标.高亮 text nodes.复制节点的 ...
- JavaScript(三十七)——移动端、多媒体、CSS动画
目录 移动端基础 手机浏览器的内核是什么? 四大浏览器内核优缺点 视口viewport rem 多媒体 视频格式 声音格式 CSS动画 CSS中的动画功能 移动端基础 大纲:视图.rem布局.媒体查询 ...
- 【前端知识点总结】CSS 基础六 - 常见的CSS动画
空间(3d)转换 tramsform: 值 ; 移动 tramsform:translate3d(x,y,z); 添加位移属性 transform: translate3d(x轴, y轴, z轴); ...
- css动画(详解带图)
css动画 过渡 过渡 (transition)的作用 常用属性 实例 动画 动画的简介 设置关键帧 动画常用属性 实例 变形 变形(transform)的简介 常用属性(transform) Z轴平 ...
- CSS动画效果无限循环放大缩小
效果图: CSS动画效果无限循环放大缩小 <image class="anima" mode="widthFix" @click="nav&qu ...
- 【译】CSS动画 vs JS动画
原文地址 目前有两个主流的方法在web上创建动画:使用CSS或JS.到底选择哪种方法来实现动画,完全取决于你的项目以及你想要达到的效果. tips: 对于简单的只出现一次的过渡效果,可以采用CSS动画 ...
- Vue 中 CSS 动画原理
下面这段代码,是点击按钮实现hello world显示与隐藏 <div id="root"><div v-if="show">hello ...
最新文章
- 物体检测丨从R-CNN到Mask R-CNN
- ntfs分配单元大小_万字长文图解 Go 内存管理分析:工具、分配和回收原理
- Bootstrap-组件-1
- mysql中如何将一个表中的部分记录合并,mysql - 如何从一个表中获取所有产品并从另一个包含多行的表中合并一行? - SO中文参考 - www.soinside.com...
- exawear能运行java_VirSCAN.org-多引擎在线病毒扫描网 v1.02,当前支持 47 款杀毒引擎...
- PIE工程师是做什么的
- 国家开放大学计算机网络技术毕业设计,精编国家开放大学毕业论文:购物网站设计...
- oracle用exp定时备份数据库,oracle exp备份数据库
- 解析大数据智能分析平台开发
- 文档在线翻译网站汇总
- io.fabric8.docker-maven-plugin插件使用
- 雷蛇公布2018年全年业绩:营收达7.1亿美元 净亏损9790万美元
- 老扎克伯格的四位儿女全是人生赢家,到底是怎么教的?
- 2023华为机考刷题指南:八周机考速通车
- 在 IDEA 中的各种调试技巧,轻松定位 Bug(超级全面)
- 《权力的游戏》Python探索性分析
- 包含第k元素LIS(dp)
- Apache服务器访问权限设置
- E+H雷达液位计做干扰抑制曲线(mapping)方法
- 不想打工了,手头上仅有5万元,想回农村做养殖,能养什么?
热门文章
- 降噪耳机哪个牌子好?2022年高性价比降噪蓝牙耳机
- 新法规下,化妆品生产厂商如何构建化妆品ERP系统?
- brk16_Linux进程分配内存的两种方式--brk() 和mmap()
- 学3D游戏建模真正需要掌握的美术基础,错过血亏!
- android中cmd环境怎么安装,如何在CMD中安装ADB命令
- 网上开具个人所得税纳税记录
- Android捷径接口,捷径接口
- myclub对阵计算机等级提示,TOPICS | PES - PRO EVOLUTION SOCCER 2019 Official Site
- 最新黄岛主·公众号流量主变现副业项目2.0全套课(完整版)
- 一文讲懂SQL分组子句GROUP BY