arc(cx,cy,radius,start_angle,end_angle,direction)
cx 水平坐标
cy 垂直坐标
radius 圆心
start-angel 圆周起始位置 (以圆心为参考点,不是以坐标原点为参考点。下面配图详细解释)
end_angle 圆周结束位置 Math.PI是半圆 Math.PI*2是整个圆 0.5为四分之一
direction 顺、逆时针 false为顺时针,true为逆时针(决定了圆弧的方向)
例:(点击查看效果)
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<script>
function draw(id) {
var canvas = document.getElementById(id)
if (canvas == null) return false
var context = canvas.getContext('2d')
context.fillStyle = "#EEEEFF"
context.fillRect(0, 0, 400, 300)
var n = 0
for (var i = 0i <10i++) {
context.beginPath()
context.arc(i * 25, i * 25, i * 10, 0, Math.PI * 2, true)
context.closePath()
context.fillStyle = 'rgba(255, 0, 0, 0.25)'
context.fill()
}
}
</script>
</head>
<body onLoad="draw('canvas')">
<canvas id="canvas" width="400" height="300"/>
</body>
</html>
context.beginPath()
该方法不使用参数,通过调用该方法,开始路径的绘制。在几次循环的创建路径的过程中,每次开始创建是都要调用beginPath函数。
context.arc(x,y,radius,startAngle,endAngle,anticlockwise)
该方法使用六个参数,x为绘制圆形的起点横坐标,y为绘制圆形图形的起点坐标,radius为绘制圆形半径,
starAngle为开始角度(以圆心为参考点,绕圆心旋转,不是以坐标原点为参考点),endAngle为结束角度,anticlockwise为是否按顺时针方向进行绘制。
arc方法不仅可以用来绘制圆形,也可以用来绘制圆弧。
context.closePath()
将路径关闭后,路径的创建工作就完成了,但还没有真正绘制任何图形。
context.fillStyle = 'rgba(255, 0, 0, 0.25)'
context.fill()
使用创建好的路径绘制图形。
Html5 Canvas 画椭圆有锯齿:因为在Canvas中整数坐标值对应的位置恰巧是屏幕象素点中间的夹缝,那么当按这样的坐标进行线条渲染时所要用到的就是夹缝两边的象素点,这样即便设置了lineWidth为1也将看到两个象素效果的线条,解决方法原象素点+0.5进行偏移。
下面是处理前后的效果比较:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html>
<head>
<meta http-equiv="Content-Type" content="text/html charset=utf-8">
<title>canvasTest</title>
<script type="text/javascript" src="http://www.pyzy.net/Demo/html5_cancas_js/excanvas.js"></script>
<script type="text/javascript">
var MyCanvas = function(boxObj, width, height) {
//序号、计数
this.index = arguments.callee.prototype.Count = (arguments.callee.prototype.Count || 0) + 1
var cvs = document.createElement("canvas")
cvs.id = "myCanvas" + this.index
cvs.width = width || 800
cvs.height = height || 600
(boxObj || document.body).appendChild(cvs)
//excanvas框架中针对ie加载canvas延时问题手动初始化对象
if (typeof G_vmlCanvasManager != "undefined") G_vmlCanvasManager.initElement(cvs)
//2D画布对象
this.ctx = cvs.getContext("2d")
/* * 绘制线条
* @ops JSON对象,可按实际支持属性扩展,示例: { lineWidth:1,strokeStyle:'rgb(255,255,255)' }
* @dotXY:{ x:0, y:0 } ||[{ x:0, y:0 },{ x:0, y:0 }]
*/
this.drawLine = function(dotXY, ops) {
this.ctx.beginPath()
for (var att in ops) this.ctx[att] = ops[att]
dotXY = dotXY.constructor == Object ? [dotXY || { x: 0, y: 0}] : dotXY
this.ctx.moveTo(dotXY[0].x, dotXY[0].y)
for (var i = 1, len = dotXY.length i < len i++) this.ctx.lineTo(dotXY[i].x, dotXY[i].y)
this.ctx.stroke()
}
}
window.onload=function(){
var c1 = new MyCanvas()
c1.drawLine([{ x: 10, y: 10 }, { x: 10, y: 200 }],{lineWidth:2,strokeStyle:'rgb(0,0,0)'})
c1.drawLine([{ x: 11, y: 10 }, { x: 11, y: 200 }],{lineWidth:2,strokeStyle:'rgb(255,255,255)'})
c1.drawLine([{ x: 100, y: 10 }, { x: 100, y: 200 }],{lineWidth:1,strokeStyle:'rgb(0,0,0)'}) //普通线
c1.drawLine([{ x: 200.5, y: 10 }, { x: 200.5, y: 200 }],{lineWidth:1,strokeStyle:'rgb(0,0,0)'}) //+0.5偏移
}
</script>
</head>
<body>
↓ 处理的↓ 普通的↓ +0.5偏移的<br />
</body>
</html>
作者: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)
}