当前位置: 首页 > Web前端 > HTML5

用CSS画时钟

时间:2023-04-05 18:15:36 HTML5

欢迎关注微信公众号:前端侦探实战CSS画各种UI的好方法,比如这个时钟?你也可以访问这个CSS时钟来查看实际效果。用CSS绘制这样的布局有几个难点:刻度圈排列,数字分布在圈内,指针自动运行。让我们一一实施。CSS绘图和动画的Tips相信你能学到很多1.排列成圆圈的刻度一提到“圆”,就会想到圆锥形渐变的conic-gradient。假设有这样一个容器加上一个小小的锥形渐变时钟{width:300px;高度:300px;background:conic-gradient(#333015deg,#cddc390deg30deg);}你可以得到这样的东西如何制作交错效果?你可以试试repeating-conic-gradientclock{/**/background:repeating-conic-gradient(#333015deg,#cddc390deg30deg);}效果如下,还是看不出有什么用用秤做什么?没关系,我们把黑色部分的角度改成小一点的时钟{/**/background:repeating-conic-gradient(#33301deg,#cddc390deg30deg);}效果如下是的几条线这样画出来刚刚好?对应时钟的刻度?然后把整个形状变成一个圆环,可以用MASK实现,如下clock{/**/border-radius:50%;-webkit-mask:radial-gradient(transparent145px,red0);}效果如下,这里还有一个小细节,黑色部分没有居中,需要修正(可以改变起始角度,指定自)。然后,把草绿色改成透明就行了,完整代码如下边界半径:50%;-webkit-mask:radial-gradient(transparent145px,red0);}最后效果分钟的scale是一样的,因为一共有60个scale,所以最小角度是6度(360/60),实现下面的clock{/**/background:repeating-conic-gradient(#33301deg,#cddc390deg6deg);}利用CSS背景可以无限叠加的特性,两个背景可以绘制在同一个元素下,所以完整代码如下-.5deg,#ccc01deg,透明0deg6deg);边界半径:50%;-webkit-mask:radial-gradient(transparent145px,red0);}最终刻度盘刻度效果如下2.数字分布成一个圆圈看到这个布局,我的第一反应其实是textPath,这个SVG元素可以排列沿着指定路径的文本,比如下面MDN上的例子敏捷的棕色狐狸跳过懒狗。效果如下但是这个方法有一个缺陷,就是无法改变文字的角度,只能按照路径的垂直方向,而时钟的数字方向是正常的,那就是offset-path!下面是MDN上的一个演示效果那么它和数字循环排列有什么关系呢假设有这样一个布局1然后Assignthisnumbertoacircularpath(目前只支持path)num{offset-path:path('M250125c069.036-55.964125-125125S0194.036012555.96401250s12555.964125125z');}效果如下(startingpointfollowsthepathpath)那么元素在路径上的位置可以通过offset-distance改变,百分比num{offset-path:path('M250125c069.036-55.964125-125125S0194.036012555.96401250s12555.964125125z');offset-distance:100%}下面是从0到100%的变化。默认情况下,元素的角度也是自适应的,垂直于路径,类似于textPath。但是我们可以手动指定一个固定的角??度,需要offset-rotate,指定0degnum{offset-path:path('M250125c069.036-55.964125-125125S0194.036012555.96401250s12555.964125offsetz');-旋转:0度;offset-distance:100%}效果如下,角度已经完全矫正。如果你有类似的布局需求,可以参考这个案例吗?接下来,我们使用CSS变量自动将12个数字返回到指定位置123456789101112带calc计算,完整代码如下num{position:absolute;偏移路径:路径('M250125c069.036-55.964125-125125S0194.036012555.96401250s12555.964125125z');偏移距离:calc(var(--i)*1.2%20-%/);offset-rotate:0deg;}效果如下3.自动运行指针三个指针的绘制应该不会太难,假设结构如下sec>/sec>需要注意旋转中心hour{position:absolute;宽度:4px;高度:60px;背景:#333;变换原点:中心底部;transform:translateY(-50%)rotate(30deg);}min{position:absolute;宽度:4px;高度:90px;背景:#333;变换原点:中心底部;变换:translateY(-50%)rotate(60deg);}sec{position:absolute;宽度:2px;:120px;背景:红色;变换原点:中心底部;转换:translateY(-50%)rotate(90deg);}sec::after{content:'';位置:绝对;宽度:10px;高度:10px;边界半径:50%;左:50%;底部:0;背景:#fff;边框:4px实心#333;transform:translate(-50%,50%);}效果如果静态布局到这一步就完成了,如何运行呢?这篇文章之前还在使用定时器?CSS也可以实现电子时钟。已经详细解释过了,不用定时器也可以用CSS动画实现!回到这里,操作原理很简单,就是一个无限循环的CSS动画,如下@keyframesclock{to{transform:translateY(-50%)rotate(360deg);}}不同的是时针和分针,秒针的周期不同。时针旋转12小时,分针为60分钟,秒针为60秒。每个都需要转换成秒(CSS单位只支持秒和毫秒)。为了测试方便,这里调整了速度。60s→6s代码实现为(--step为一分钟)小时{/**/transform:translateY(-50%)rotate(0);animation:clockcalc(var(--step)*60*12)infinite;}min{/**/transform:translateY(-50%)rotate(0);animation:clockcalc(var(--step)*60)infinite;}sec{/**/transform:translateY(-50%)rotate(0);animation:clockvar(--step)infinite;}效果如下是不是有点奇怪?秒针转动时,先是慢慢变快,然后又慢慢变慢。这是因为默认的动画函数是ease,所以需要改成linearsec{/**/animation:clockvar(--step)infinitelinear;}这样就好多了,但是我们平时看到的时钟,第二个手平时一动一停,有“滴答滴答”的节奏感,不是天衣无缝。在CSS动画中,是不是有点像梯子?是的,你可以使用CSS的steps功能。不知道的可以参考张老师的这篇文章:深入介绍CSS3动画属性中的steps功能,实现如下sec{/**/animation:clockvar(--step)infinitesteps(60);}效果如下接下来需要通过JS初始化时间,仅此而已。需要注意的是获取的时候加上了偏移量,比如12:30,分针实际是12.5等等。代码实现如下constd=newDate()consth=d.getHours();constm=d.getMinutes();consts=d.getSeconds();clock.style.setProperty('--ds',s)clock.style.setProperty('--dm',m+s/60)clock.style.setProperty('--dh',h+m/60+s/3600)而CSS可以通过animation-delay来指定动画小时的起始位置{/**/animation:clockcalc(var(--step)*60*12)infinitelinear;animation-delay:calc(-1*var(--step)*var(--dh)*60);}min{/**/animation:clockcalc(var(--step)*60)无限线性;animation-delay:calc(-1*var(--step)*var(--dm));}sec{/**/animation:clockvar(--step)infinitesteps(60);animation-delay:calc(-1*var(--step)*var(--ds)/60);}然后添加一些轮廓修饰,实现文章开头的效果。完整代码可以查看CSS时钟4.小结以上就是CSS绘制时钟的全过程。这篇文章更侧重于绘制过程,尤其是圆形布局技巧,这里简单总结一下圆形图案,可以想到conic-gradient圆形刻度绘制的原理是conic-gradient和MASK沿路径切割文字可以使用textPathtextPath不支持改变文字角度offset-path可以让元素按照指定的路径布局offset-path可以设置元素在路径中的偏移量和角度。时钟自动运行的原理是CSS动画。钟、分、秒的区别在于动画时长不同。“滴答滴答”效果可以分步实现。动画片ationdelay的实现当然,本文的重点不只是实现一个时钟,而是积累和掌握CSS绘图技巧。有了相关的积累,以后遇到类似的布局,在脑海里过滤一下,马上就能找到。解决方案。最后,如果觉得对你有好处和帮助,欢迎点赞、收藏、转发???欢迎关注微信公众号:前端大侦探