# Canvas应用
# Canvas API
# 属性
width
在canvas标签中,声明属性width=1000(px)与应用样式width:1000px都是设置画布宽度,但是有一点区别需要注意,前者实质是应用了aspect-ratio (opens new window)媒体属性,表示视口宽高比,在使用canvas api时传入的数值参数单位是px,而后者应用画布API时传入的数值单位是百分比,超过100%按100%显示。一般建议采用属性声明的方式。
height
同width
# 方法
getContext(contextId)
返回CanvasRenderingContext2D对象
toDataURL([type][,level])
指定画布要转化为图片类型,返回图片url。若类型为image/jpeg,还可指定质量等级,值在0到1之间
# CanvasRenderingContext2D API
# 属性
fillStyle
表示填充风格,值支持hex、rgba、hsla这三种表示方式
strokeStyle
表示轮廓风格
globalAlpha
设置图像透明度
globalCompositeOperation
设置重叠图像的覆盖方式,可取值如下,
- source-over:默认值,显示源和汇的差集、源的交集
- destination-over:显示源和汇的差集、汇的交集
- source-in:只显示源的交集
- destination-in:只显示汇的交集
- source-out:只显示源的差集
- destination-out:只显示汇的差集
- lighter:显示源和汇的差集、交集混合颜色变淡
- darker:显示源和汇的差集、交集混合颜色变深
- xor:显示源和汇的差集
- source-atop:只显示源的差集
- destination-atop:显示汇的交集和源的差集
- copy:显示源
lineCap
表示线段的箭头样式,可取值为butt、round、square,默认值为butt,表示头尾为长方形,round表示头尾为半圆形,square表示头尾增加一个长方形,其长为线宽的一半,高为线宽
lineJoin
表示线段的连接方式,可取值为miter、round、bevel,默认值为miter,线段在连接处外侧延伸直至交于一点,若外延交点距离大于限制值是表现为bevel风格,其连接处为斜角,round连接处为一个圆角,半径为线宽
lineWidth
表示线段的线宽
miterLimit
表示线段连接处的斜率
shadowBlur
阴影模糊等级,值范围为不小于0
shadowColor
阴影颜色
shadowOffsetX
阴影X偏移量
shadowOffsetY
阴影Y偏移量
font
textAlign
textBaseline
# 方法
restore()
恢复至上次保存的绘图状态,包括所有属性和transform、clip两个方法
save()
保存当前绘图状态
scale(x,y)
分别在x和y轴方向上按指定比例缩放
translate(x,y)
分别在x和y轴方向上按指定值偏移,实质上是可以看做是画布参考坐标系上的原点的移动
rotate(angle)
顺时针旋转angle度
transform(m11,m12,m21,m22,dx,dy)
乘上如下矩阵进行变换,
m11 m21 dx m21 m22 dy 0 0 1
setTransform(m11,m12,m21,m22,dx,dy)
重设变换矩阵
createLinearGradient(x0,y0,x1,y1)
线性渐变
createRadialGradient(x0,y0,r0,x1,y1,r1)
径向渐变,返回一个渐变对象,有如下方法,
addColorStop(point,color)
用于添加渐变颜色点,point值在0至1之间
createPattern(image,repetition)
指定图像和重复方向创建画布图案对象,repetition可取值为repeat、repeat-x、repeat-y和no-repeat
arc(x,y,r,a0,a1[,direction])
画弧,参数分别表示圆心X坐标,圆心Y坐标,圆心半径,起始角度,结束角度,绘制方向(为true表示逆时针,为false表示顺时针)
arcTo(x1,y1,x2,y2,radius)
绘制路径终点分别与点(x1,y1)、(x2,y2)构成的两条直线间半径为radius的弧长
rect(x,y,w,h)
画矩形
bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y)
三次贝塞尔曲线
quadraticCurveTo(cpx,cpy,x,y)
二次贝塞尔曲线
clearRect(x,y,w,h)
清除矩形内的像素,参数分别表示起始X轴偏移量,起始Y轴偏移量,矩形宽度,矩形高度
fillRect(x,y,w,h)
绘制填充矩形,参数同clearRect
strokeRect(x,y,w,h)
绘制轮廓矩形,参数同strokeRect
moveTo(x,y)
移动到指定位置
lineTo(x,y)
画线到指定位置
beginPath()
开始新的子路径
closePath()
关闭子路径
isPointInPath(x,y)
判断点(x,y)是否在当前路径
fill()
填充方式绘制
stroke()
轮廓方式绘制
clip()
裁切路径,只显示裁切区域的内容
fillText(text,x,y[,maxWidth])
strokeText(text,x,y[,maxWidth])
drawImage(image[,sx,sy,sw,sh],dx,dy[,dw,dh])
绘图,参数分别表示图片的起始X偏移量,图片的起始Y偏移量,图片的指定宽度,图片的指定高度,图片相对浏览器窗口的起始X偏移量,图片相对浏览器窗口的起始Y偏移量,图片在浏览器窗口设置的宽度,图片在浏览器窗口设置的高度
createImageData(sw,sh)/createImageData(image)
指定宽高或明确宽高的图像,创建ImageData对象
getImageData(sx,sy,sw,sh)
获取画布指定区域的ImageData对象
putImageData(imageData,dx,dy[,dirtyX,dirtyY,dirtyWidth,dirtyHeight])
绘制指定的ImageData对象
# 应用
# 碰撞球
效果如下,
贴上与canvas相关的代码,
//画线
function drawLine(context, x0, y0, x1, y1, color) {
context.save();
context.beginPath();
if (color == null) {
context.strokeStyle = "#A7AEB0";
} else {
context.strokeStyle = color;
}
context.moveTo(x0, y0);
context.lineTo(x1, y1);
context.stroke();
context.closePath();
context.restore();
}
//画球
function draw3DBall(context, x0, y0, c0, c1) {
context.save();
context.beginPath();
context.translate(x0, y0);
var gradient = context.createRadialGradient(3, 3, 0, 0, 0, 10);
if (c0 == null) {
gradient.addColorStop(0, "#eee");
} else {
gradient.addColorStop(0, c0);
}
if (c1 == null) {
gradient.addColorStop(1, "#57BADA");
} else {
gradient.addColorStop(0, c1);
}
context.fillStyle = gradient;
context.arc(0, 0, 10, 0, 2 * Math.PI);
context.fill();
context.closePath();
context.restore();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 旗帜
效果如下,
贴上与canvas相关的代码,
//画旗帜
function drawFlag(x0, y0, x1, y1, offsetX) {
con.beginPath();
con.moveTo(x0, y0 + 50 * Math.sin(offsetX * Math.PI * 2 / (x1 - x0)));
for (var i = 1; i <= x1 - x0; i++) {
con.lineTo(x0 + i, y0 + 50 * Math.sin((offsetX + i) * Math.PI * 2 / (x1 - x0)));
}
con.lineTo(x1, y1 + 50 * Math.sin(offsetX * Math.PI * 2 / (x1 - x0)));
for (var j = 1; j <= x1 - x0; j++) {
con.lineTo(x1 - j, y1 + 50 * Math.sin((offsetX + x1 - x0 - j) * Math.PI * 2 / (x1 - x0)));
}
con.lineTo(x0, y0 + 50 * Math.sin(offsetX * Math.PI * 2 / (x1 - x0)));
con.closePath();
con.fillStyle = "#1890ff";
con.fill();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 放大镜
放大镜已封装成一个模块,具体使用可访问下面链接,
https://github.com/muzhidong/frontend-demo/tree/master/magnify (opens new window)