Compared to the JavaScript digital clock I demonstrated in the previous article, this SVG analog clock uses fewer lines of code, and has the advantage of being infinitely scalable.
与我在上一篇文章中演示JavaScript数字时钟相比,此SVG模拟时钟使用较少的代码行,并且具有可无限扩展的优点。
I’ve always admired the elegance of the code, expressed earlier by Felix Gnass. First, there’s my version of the SVG, which consists of just four elements: the dial, and three rectangular hands (hours, minutes, and seconds):
我一直都很欣赏Felix Gnass先前表达的代码的优雅。 首先,是我的SVG版本,它仅包含四个元素:表盘和三个矩形指针(时,分和秒):
<svg id="clock" viewBox="0 0 100 100">
<circle id="face" cx="50" cy="50" r="45"/>
<g id="hands">
<rect id="hour" x="48.5" y="12.5" width="5" height="40" rx="2.5" ry="2.55" />
<rect id="min" x="48" y="12.5" width="3" height="40" rx="2" ry="2"/>
<line id="sec" x1="50" y1="50" x2="50" y2="16" />
</g>
</svg>
The markup is, I hope, fairly self-explanatory: the <circle>
element has a radius of 45 units, with its center 50 units from the top left corner of the SVG element; the hour
, min
and sec
elements are positioned similarly. The hour and minute hands are rectangles 40 units long, and have a border-radius
(in SVG, applied as rx
and ry
).
我希望标记是不言自明的: <circle>
元素的半径为45个单位,其中心距SVG元素的左上角50个单位; hour
, min
和sec
元素的位置类似。 时针和分针是长40个单位的矩形,并具有border-radius
(在SVG中,用作rx
和ry
)。
Rather than trying to style the elements inline, I’ll do that in CSS:
与其尝试内联样式化元素,不如在CSS中进行 :
#face {
stroke-width: 2px; stroke: #fff;
}
#hour, #min, #sec {
stroke-width: 1px; fill: #333; stroke: #555;
}
#sec { stroke: #f55; }
At this point, the clock has all hands pointing to 12. The JavaScript, written at the bottom of the page, changes all that:
此时,时钟的所有指针都指向12。写在页面底部的JavaScript改变了所有这些:
setInterval(function() {
function r(el, deg) {
el.setAttribute('transform', 'rotate('+ deg +' 50 50)')
}
var d = new Date()
r(sec, 6*d.getSeconds())
r(min, 6*d.getMinutes())
r(hour, 30*(d.getHours()%12) + d.getMinutes()/2)
}, 1000)
This differs from the previous script in several significant ways:
这与以前的脚本有很多不同之处:
First, it uses a setInterval
that encompasses the entire script. The function inside runs every second, due to the 1000
passed to setInterval
as an argument in milliseconds.
首先,它使用包含整个脚本的setInterval
。 内部函数每秒运行一次,这是因为将1000
作为参数传递给setInterval
是毫秒。
d
is a variable based on the Date()
object, just like the previous example. For brevity, the script takes advantage of the fact that elements with an id
attribute automatically become references in scripts. While this isn’t a recommended practice, it’s certainly doable, making the use of sec
, min
and hour
in the script direct references to the matching SVG elements.
d
是一个基于Date()
对象的变量,就像前面的示例一样。 为简便起见,脚本利用了具有id
属性的元素自动成为脚本中引用的事实。 虽然这不是推荐的做法,但肯定可以做到,在脚本中使用sec
, min
和hour
直接引用匹配的SVG元素。
The r
function takes two arguments: the element to change, and the amount of rotation. Note that we’re taking about SVG rotation, not CSS, so there’s no need for vendor prefixes.
r
函数有两个参数:要更改的元素和旋转量。 请注意,我们是在考虑SVG轮换,而不是CSS,因此不需要供应商前缀。
For sec
, r
is passed the id
of the element, and 6 × the number of seconds in the current time. If it’s 0 seconds, deg
will be 0
, meaning that the element won’t rotate at all. If it’s 30 seconds, 30 × 6 = 180° of rotation. (The 50 50
value ensures that the element always rotates from the center of the SVG). min
takes gets the same treatment, while hour
is a little tricker: it uses the remainder of dividing the current hour by 12, multiplied by 30, and adds the number of minutes divided by 2. In other words, if it is 15 minutes past midnight, the calculation becomes:
对于sec
,将传递r
的元素id
和6×当前时间的秒数。 如果为0秒,则deg
将为0
,表示元素完全不会旋转。 如果是30秒,则30×6 = 180°旋转。 (值50 50
确保元素始终从SVG中心旋转)。 min
采取相同的处理方式,而hour
则有些麻烦:它使用将当前小时除以12的余数乘以30,再加上分钟数除以2。换句话说,如果过去15分钟午夜,计算结果为:
r(hour, 30 * 0 + (15 / 2))
> 7.5
It if it is 3.45pm (remembering that JavaScript uses 24 hour time by default, so the hour division will be 15 % 12
. The calculation is:
如果它是3.45pm(请记住,JavaScript默认使用24小时制,那么时分将为15 % 12
。计算公式为:
r(hour, 30 * 3 + (45 / 2))
> 112.5
All told, it’s a very nice little piece of code, which I hope will find its uses in your projects.
总而言之,这是一段非常漂亮的小代码,我希望它将在您的项目中找到它的用途。
翻译自: https://thenewcode.com/943/An-SVG-Analog-Clock-In-6-Lines-of-JavaScript