作者:eleven
链接:https://www.zhihu.com/question/50603427/answer/122278093
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
芝麻的应该是用canvas实现的:放大下图片就可以看到刻度线上的小锯齿;右侧数字上方的刻度线的颜色明显淡了些。
CSS3或者CANVAS都可以实现,关键是要把 旋转中心 / 旋转角度 / 旋转方向 确定好了。具体实现方式可参考 @Jim Liu 的逻辑。(二楼的神作还没有理解呢,\汗)
旋转中心:多以圆心为准;
旋转角度:根据应用逻辑也容易计算;
旋转方向: -- 这个对我来说有点不好理解,导致走了长长的弯路。
以下是rotate的官方说明:
CSS3:
rotate( <angle>)
specifies a 2D rotation by the angle specified in the parameter about the origin of the element, as
defined by the transform-origin property. For example, rotate(90deg)
would cause elements to appear rotated one-quarter of a turn in the clockwise direction.
CANVAS:
The rotate(angle)
method must add the rotation transformation described by the argument to the transformation
matrix. The angle argument represents a clockwise rotation angle expressed in
radians.
参数的单位不一样,但都是以顺时针方向实现旋转的。如果参数值为负数,可表示以逆时针的方向旋转。
对于CSS3来说,所有的元素都是可变动的。旋转的物体是HMTL标签元素。旋转的方向是原始元素到目标位置。一般将元素集中绝对定位到特定的位置,比如正上方-Y轴的负方向(可随意指定,怎么方便怎么来),然后将各个元素旋转(拖拽)到目标位置上。
对于CANVAS来说,只有一次写的机会,一旦在画布上写了内容,都是不可修改和撤销的。旋转的物体是坐标系。旋转的方向就是坐标轴到目标位置。
只要参照物在坐标轴上, 两种方式的旋转方向和角度都一样,不用刻意区分,简单多了。
有区别的就是下一个元素: (顺序依次为:红色第一个;紫色第二个)
具体的实现为:
CSS3:
var total_count = el_sets.length,
per_degree = total_degrees / (total_count-1)
for(var i = 0i <total_counti++){
var degree = start_rotate_degree + i * per_degree
el_sets[i].style.transform = "rotate("+ degree +"deg)"
}
CANVAS:
ctx.rotate(setting.start_degree)
for(var i = 0i <setting.counti++){
var pos = getPosInCircle(0,setting.radius,Math.PI/-2,10)
ctx.fillText(sets[i],pos.x,pos.y)
ctx.rotate(setting.per_degree)
}
代码:var clock=document.getElementById("clock")
var cxt=clock.getContext("2d")
function drawNow(){
var now=new Date()
var hour=now.getHours()
var min=now.getMinutes()
var sec=now.getSeconds()
hour=hour>12?hour-12:hour
hour=hour+min/60
//表盘(蓝色)
cxt.lineWidth=10
cxt.strokeStyle="blue"
cxt.beginPath()
cxt.arc(250,250,200,0,360,false)
cxt.closePath()
cxt.stroke()
//刻度
//时刻度
for(var i=0i<12i++){
cxt.save()
cxt.lineWidth=7
cxt.strokeStyle="black"
cxt.translate(250,250)
cxt.rotate(i*30*Math.PI/180)//旋转角度 角度*Math.PI/180=弧度
cxt.beginPath()
cxt.moveTo(0,-170)
cxt.lineTo(0,-190)
cxt.closePath()
cxt.stroke()
cxt.restore()
}
//分刻度
for(var i=0i<60i++){
cxt.save()
//设置分刻度的粗细
cxt.lineWidth=5
//重置画布原点
cxt.translate(250,250)
//设置旋转角度
cxt.rotate(i*6*Math.PI/180)
//画分针刻度
cxt.strokeStyle="black"
cxt.beginPath()
cxt.moveTo(0,-180)
cxt.lineTo(0,-190)
cxt.closePath()
cxt.stroke()
cxt.restore()
}
//时针
cxt.save()
// 设置时针风格
cxt.lineWidth=7
cxt.strokeStyle="black"
cxt.translate(250,250)
cxt.rotate(hour*30*Math.PI/180)
cxt.beginPath()
cxt.moveTo(0,-140)
cxt.lineTo(0,10)
cxt.closePath()
cxt.stroke()
cxt.restore()
//分针
cxt.save()
cxt.lineWidth=5
cxt.strokeStyle="black"
//设置异次元空间分针画布的中心
cxt.translate(250,250)
cxt.rotate(min*6*Math.PI/180)
cxt.beginPath()
cxt.moveTo(0,-160)
cxt.lineTo(0,15)
cxt.closePath()
cxt.stroke()
cxt.restore()
//秒针
cxt.save()
//设置秒针的风格
//颜色:红色
cxt.strokeStyle="red"
cxt.lineWidth=3
//重置原点
cxt.translate(250,250)
//设置角度
//cxt.rotate(330*Math.PI/180)
cxt.rotate(sec*6*Math.PI/180)
cxt.beginPath()
cxt.moveTo(0,-170)
cxt.lineTo(0,20)
cxt.closePath()
cxt.stroke()
//画出时针,分针,秒针的交叉点
cxt.beginPath()
cxt.arc(0,0,5,0,360,false)
cxt.closePath()
//设置填充
cxt.fillStyle="gray"
cxt.fill()
//cxt.strokeStyle="red"
cxt.stroke()
//画出秒针的小圆点
cxt.beginPath()
cxt.arc(0,-140,5,0,360,false)
cxt.closePath()
//设置填充
cxt.fillStyle="gray"
cxt.fill()
//cxt.strokeStyle="red"
cxt.stroke()</p>
<p> cxt.restore()</p>
<p>}
function drawClock(){
cxt.clearRect(0,0,500,500)
drawNow()
}
drawNow()
setInterval(drawClock,1000)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)