canvas定义
Canvas 对象是 HTML5 中新增的。
HTML5 <canvas> 标签用于绘制图像(通过脚本,通常是 JavaScript)
参考文档: MDN, API中文网
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
canvas{
background: #000;
}
</style>
</head>
<body>
<canvas></canvas>
</body>
</html>
canvas默认大小为
300*150
,我们可以通过canvas标签的width,height
属性来设置其宽高,不可通过css
属性样式来设置,css样式会导致canvas内的图像按照300*150的比例进行放大或者缩小。注意:canvas默认为透明,不设置其背景色时,可以显示其下方遮盖内容
getContext()
canvas元素本身并没有绘制能力(它仅仅是图形的容器) - 您必须使用脚本来完成实际的绘图任务。
getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
1. 颜色,样式和阴影
属性 | 描述 |
---|---|
fillStyle | 设置或返回用于填充绘画的颜色、渐变或模式 |
strokeStyle | 设置或返回用于笔触的颜色、渐变或模式 |
shadowColor | 设置或返回用于阴影的颜色 |
shadowBlur | 设置或返回用于阴影的模糊级别 |
shadowOffsetX | 设置或返回阴影与形状的水平距离 |
shadowOffsetY | 设置或返回阴影与形状的垂直距离 |
方法 | 描述 |
---|---|
createLinearGradient() | 创建线性渐变(用在画布内容上) |
createPattern() | 在指定方向上重复指定的元素 |
createRadialGradient() | 创建放射状/环形的渐变(用在画布内容上) |
addColorStop() | 规定渐变对象中的颜色和停止位置 |
2.线条样式
属性 | 描述 |
---|---|
linecap | 设置或返回线条的结束端点样式 |
lineJoin | 设置或返回两条线相交时,所创建的拐角类型 |
lineWidth | 设置或返回当前的线条宽度 |
miterLimit | 设置或返回最大斜接长度 |
3.矩形
方法 | 描述 |
---|---|
rect() | 创建矩形 |
fillRect() | 绘制被填充的矩形 |
strokeRect | 绘制矩形(无填充) |
clearRect() | 在给定的矩形内清除指定的像素 |
4.路径
方法 | 描述 |
---|---|
fill() | 填充当前绘图(路径) |
stroke() | 绘制已定义的路径 |
beginPath() | 起始一条路径,或重置当前路径 |
moveTo() | 把路径移动到画布中的指定点,不创建线条 |
closePath() | 创建从当前点回到起始点的路径 |
lineTo() | 添加一个新点,然后在画布中创建从该点到最后指定点的线条 |
clip() | 从原始画布剪切任意形状和尺寸的区域 |
quadraticCurveTo() | 创建二次贝塞尔曲线 |
bezierCurveTo() | 创建三次贝塞尔曲线 |
arc() | 创建弧/曲线(用于创建圆形或部分圆) |
arcTo() | 创建两切线之间的弧/曲线 |
isPointInPath() | 如果指定的点位于当前路径中,返回true,否则返回false |
5.转换
方法 | 描述 |
---|---|
scale() | 缩放当前绘图至更大或更小 |
rotate() | 旋转当前绘图 |
translate() | 重新映射画布上的(0,0)位置 |
transform() | 替换绘图的当前转换矩阵 |
setTransform() | 将当前转换重置为单位矩阵,然后运行transform() |
6.文本
属性 | 描述 |
---|---|
font | 设置或返回文本内容的当前字体属性 |
textAlign | 设置或返回文本内容的当前对齐方式 |
textBaseLine | 设置或返回在绘制文本时使用的当前文本基线 |
方法 | 描述 |
---|---|
fillText() | 在画布上绘制被填充的文本 |
strokeText() | 在画布上绘制文本(无填充) |
measureText() | 返回包含指定文本宽度的对象 |
7.图像绘制
方法 | 描述 |
---|---|
drawImage() | 向画布上绘制图像,画布或者视频 |
8.像素操作
属性 | 描述 |
---|---|
width | 返回ImageData对象的宽度 |
height | 返回ImageData对象的高度 |
data | 返回一个对象,其包含指定的ImageData对象的图像数据 |
方法 | 描述 |
---|---|
createImageData() | 创建新的,空白的ImageData对象 |
getImageData() | 返回ImageData对象,该对象为画布上指定的矩形复制像素数据 |
putImageData() | 把图像数据(从指定的ImageData对象)放回画布上 |
9.合成
属性 | 描述 |
---|---|
globalAlpha | 设置或返回绘图的当前aloha或透明度 |
globalComposeiteOperation | 设置或返回新图像如何绘制到已有图像上 |
10.其他
方法 | 描述 |
---|---|
save() | 保存当前环境的状态 |
restore() | 返回之前保存过的路径状态和属性 |
createEvent() | |
getContext() | |
toDataURL() | 可以返回Canvas图像对应的data URI,也就是平常我们所说的base64地址 |
canvas兼容
<canvas>元素与<img>
标签的不同之处在于,就像<video>
,<audio>
,或者 <picture>
元素一样,很容易定义一些替代内容。由于某些较老的浏览器(尤其是IE9之前的IE浏览器)或者文本浏览器不支持HTML元素"canvas",在这些浏览器上你应该总是能展示替代内容。
<canvas id="canvas" width="400" height="400">
canvas unsupported
</canvas>
ie8出现以下替换界面:替换内容是用于在不支持 <canvas>
标签的浏览器中展示的。通过简单的测试getContext()方法的存在,脚本可以检查编程支持性
if (canvas.getContext){
var ctx = canvas.getContext('2d');
// drawing code here
} else {
// canvas-unsupported code here
}
绘制图形
1. 绘制矩形
rect(x, y, width, height)
绘制一个左上角坐标为(x,y),宽高为width以及height的矩形
ctx.beginPath();
ctx.rect(100, 25, 100, 100)
ctx.stroke();
- fillRect(x,y,width,height)
绘制一个填充的矩形 - strokeRect(x,y,width,height)
绘制一个矩形的边框 - clearRect(x,y,width,height)
清除指定矩形区域,让清除部分完全透明。
ctx.fillRect(25, 25, 100, 100);
ctx.clearRect(45, 45, 60, 60);
ctx.strokeRect(50, 50, 50, 50);
可以看到填充以及描边的颜色默认为黑色,通过fillStyle,strokeStyle改变其样式
ctx.fillStyle = 'pink';
ctx.fillRect(25, 25, 100, 100);
ctx.strokeStyle = 'red';
ctx.clearRect(45, 45, 60, 60);
ctx.strokeRect(50, 50, 50, 50);
2. 绘制路径
- 创建路径起始点
生成路径的第一步叫做beginPath(),路径是由很多子路径构成,这些子路径都是在一个列表中,所有的子路径(线、弧形、等等)构成图形。而每次这个方法调用之后,列表清空重置,然后我们就可以重新绘制新的图形。
注意:当前路径为空,即调用beginPath()之后,或者canvas刚建的时候,第一条路径构造命令通常被视为是moveTo(),无论实际上是什么。出于这个原因,你几乎总是要在设置路径之后专门指定你的起始位置
- 使用画图命令去画出路径
- 把路径封闭
闭合路径closePath(),不是必需的。这个方法会通过绘制一条从当前点到开始点的直线来闭合图形。如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。
注意:当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合
- 通过描边和填充来渲染图形
ctx.beginPath();
ctx.moveTo(75, 50);
ctx.lineTo(100, 75);
ctx.lineTo(100, 25);
ctx.fill();
3.绘制线
lineTo(x,y)
绘制一条从当前位置到指定x以及y位置的直线
该方法有两个参数:x以及y ,代表坐标系中直线结束的点。开始点和之前的绘制路径有关,之前路径的结束点就是接下来的开始点,等等。。。开始点也可以通过moveTo()函数改变。
ctx.beginPath();
ctx.moveTo(200,200);
ctx.lineTo(100,100);
ctx.lineTo(50,100);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.moveTo(200,200);
ctx.lineTo(100,100);
ctx.lineTo(50,100);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(200,200);
ctx.lineTo(100,100);
ctx.lineTo(50,100);
ctx.fill();
lineWidth = value
设置线条宽度
for(var i = 0; i < 10; i++){
ctx.lineWidth = i + 1;
ctx.strokeStyle = 'lightpink';
ctx.beginPath();
ctx.moveTo(5 + i * 12,5);
ctx.lineTo(5 + i * 12,120);
ctx.stroke();
}
lineCap = type
设置线条末端样式
butt,round 和 square。默认是 butt
lineJoin = type
设置线条与线条间接合处的样式
round, bevel 和 miter。默认是 miter
miterlimit = value
限制当两条线相交时交接处最大长度;所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度(lineJoin类型为miter时,miter生效的限制值)
getLineDash()
返回一个包含当前虚线样式,长度为非负偶数的数组
setLineDash(segments)
设置当前虚线样式,线的实线和透明部分长度
ctx.beginPath();
ctx.setLineDash([4,2]);
ctx.moveTo(20, 70);
ctx.lineTo(280, 70);
ctx.stroke();
lineDashOffset = value
设置虚线样式的起始偏移量
let i = 1;
setInterval(function(){
ctx.clearRect(0,0, canvas.width, canvas.height);
ctx.beginPath();
i ++;
if(i > 20) {
i = 1;
}
ctx.lineDashOffset = i;
ctx.setLineDash([10,20]);
ctx.strokeRect(100,100,100,50);
ctx.stroke();
},200)
4. 圆弧
arc(x, y, radius, startAngle, endAngle, anticlockwise)
画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针)来生成,为true时,是逆时针方向,否则顺时针方向。
弧度=(Math.PI/180)*角度
ctx.beginPath();
ctx.arc(50,50,50,0,Math.PI / 2,true)
ctx.closePath();
ctx.strokeStyle = 'rgb(255,255,255)';
ctx.stroke();
arcTo(x1, y1, x2, y2, radius)
根据给定的控制点和半径画一段圆弧,再以直线连接两个控制点
ctx.beginPath();
ctx.moveTo(150,80);
ctx.arcTo(150, 100, 200, 40, 40);
ctx.strokeStyle = 'red';
ctx.stroke();
5. 渐变
可以用线性或者径向的渐变来填充或描边
createLinearGradient(x1, y1, x2, y2)
createLinearGradient 方法接受 4 个参数,表示渐变的起点 (x1,y1) 与终点 (x2,y2)
createRadialGradient(x1, y1, r1, x2, y2, r2)
createRadialGradient 方法接受 6 个参数,前三个定义一个以 (x1,y1) 为原点,半径为 r1 的圆,后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的圆
同时需要addColorStop(position,color)配合上色
var lingrad = ctx.createLinearGradient(0,0,0,150);
lingrad.addColorStop(0, '#00ABEB');
lingrad.addColorStop(1, '#fff');
ctx.fillStyle = lingrad;
ctx.fillRect(10,10,130,130);
var radgrad2 =ctx.createRadialGradient(45,45,10,52,50,30);
radgrad2.addColorStop(0, '#FF5F98');
radgrad2.addColorStop(0.75, '#FF0188');
radgrad2.addColorStop(1, 'rgba(255,1,136,0)');
ctx.fillStyle = radgrad2;
ctx.fillRect(0,0,150,150);
6. 文本
- 文本渲染方法
fillText(text,x,y,[,maxWidth])
strokeText(text,x,y,[,maxWidth]) - 文本样式
font = value
默认字体是 10px sans-serif
textAlign = value
文本对齐选项. 可选的值包括:start, end, left, right or center. 默认值是 start
textBaseline = value
基线对齐选项. 可选的值包括:top, hanging, middle, alphabetic, ideographic, bottom。默认值是 alphabetic
direction = value
文本方向。可能的值包括:ltr, rtl, inherit。默认值是 inherit
ctx.font = "48px serif";
ctx.textBaseline = "hanging";
ctx.strokeText("Hello world", 0, 100);
7. 使用图像
引入图像到canvas中需要一下基本操作:
- 获取一个指向htmlImageElement对象或者另一个canvas元素的引用作为源,也可以通过url的方式来使用图片
使用相同页面内的图片
document.getElementById()获取这个图片
使用其他域名下的图片
在HTMLImageElement
上使用crossOrigin属性,你可以请求加载其它域名上的图片。如果图片的服务器允许跨域访问这个图片,那么你可以使用这个图片而不污染canvas,否则,使用这个图片将会污染canvas
使用其他canvas元素
document.getElementByTagName 或者 document.getElementById 获取其他准备好的canvas
从零开始创建图像
var img = new Image(); // 创建一个<img>元素
img.onload = function(){
// 执行drawImage语句
}
img.src = 'myImage.png'; // 设置图片源地址
通过data:url方式嵌入图像
可以引用Base64编码字符串来定义图片进行引用
使用视频帧
即使视频不可见也可以这样做
function getMyVideo() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
return document.getElementById('myvideo');
}
}
- 使用drawImage() 函数绘制图片到画布上
ctx.drawImage(image, dx, dy);
ctx.drawImage(image, dx, dy, dWidth, dHeight);
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
image: 绘制在Canvas上的元素
dx:在Canvas画布上规划一片区域用来放置图片,dx就是这片区域的左上角横坐标
dy:在Canvas画布上规划一片区域用来放置图片,dy就是这片区域的左上角纵坐标
dWidth:在Canvas画布上规划一片区域用来放置图片,dWidth就是这片区域的宽度
dHeight:在Canvas画布上规划一片区域用来放置图片,dHeight就是这片区域的高度
sx:表示图片元素绘制在Canvas画布上起始横坐标
sy:表示图片元素绘制在Canvas画布上起始纵坐标
sWidth:表示图片元素从坐标点开始算,多大的宽度内容绘制Canvas画布上
sHeight:表示图片元素从坐标点开始算,多大的高度内容绘制Canvas画布上
let img = new Image();
img.onload = () => {
ctx.drawImage(img,0,0);
};
img.src = 'https://www.canvasapi.cn/assets/images/examples/500/1.jpg';
let img = new Image();
img.onload = () => {
ctx.drawImage(img,0,0,100,100,50,50,50,50);
};
img.src = 'https://www.canvasapi.cn/assets/images/examples/500/1.jpg';
注意:如果不指定图片放置的位置和大小 ctx.drawImage(img,0,0,100,100) 这样就会使得图片整体放到放置区域,可能导致形变