Canvas
一.概述
Canvas是HTML5中非常重要的一个更新亮点,画布,替代Flash的!制作动画、制作游戏。渲染效率非常的高,浏览器不需要安装任何的插件就可以渲染这个动画
1. Hello World
canvas是一个标签,有一个默认的宽高(300px,150px)。如果我们要设置宽度、高度,必须设置在HTML标签上面,而不能设置在CSS上。
我们必须使用JavaScript来控制Canvas渲染各种东西:
<style type="text/css">
canvas{
border: 1px solid gray;
}
</style>
<canvas width="600" height="400"></canvas>
<script type="text/javascript">
//使用DOM方法得到画布
var mycanvas = document.querySelector("canvas");
//使用画布的上下文,获取绘画功能对象,就像拿到一直画笔,这支画笔只在当前画笔有效
var ctx = mycanvas.getContext("2d");
//画各种东西,用ctx打点调用方法,而不是mycanvas
ctx.fillRect(100,100,300,40);
</script>
2. 涉及的API
2.1 getContext()
get表示得到,context是上下文的意思。
canvas起初是空白的。为了展示,首先脚本需要找到渲染上下文,然后在它的上面绘制。<canvas>
元素有一个做 getContext() 的方法,这个方法是用来获得渲染上下文和它的绘画功能。getContext()只有一个参数,上下文的格式。
var ctx = canvas.getContext('2d');
ctx对象,非常重要所有的绘制都是ctx的方法。canvas就是画布,功能就是生产画笔,
剩下所有的绘制都是有这支画笔ctx对象的属性来操作
//也就是说所有的绘制API都是ctx的事情,而不是canvas对象
ctx.fillStyle = "blue";
ctx.arc(300,300,100,0,Math.PI * 2,true);
ctx.fill();
2.2 绘制圆形 arc()
绘制圆形 arc(x,y,r,)
bol,是布尔值
ctx.arc(300,300,100,0,Math.PI * 2,true); // 圆心坐标,半径,起始位置,终点位置,顺时针
- x,y为圆心的坐标
- radius 为圆形的半径
- startAngle 为弧度的起始位置,0是正x轴的
- endAngle 为弧度的终点位置,
- anticlockwise 布尔值,true为逆时针绘制,false为顺时针绘制
2.3 绘制矩形 rect()
绘制矩形 rect(x,y,w,h)
ctx.rect(200, 200, 100, 100); // 左上角位置 , 长宽
2.4 stroke()笔触
绘制线条
ctx.stroke()
2.5 fill() 填充
ctx.fill()
2.6 可以合在一起写
-
strokeRect(x,y,w,h)
-
fillRect(x,y,w,h)
参数:
x,y 为起点的x,y坐标
w,h 为要绘制矩形的宽高
2.7 清除 clearRect()
清除clearRect(x,y,w,h)
ctx.clearRect(250, 250, 30, 30);
清除在绘制有先后属性之分
二. 笔触和填充
Canvas中能够产生颜色的是两个东西,一个叫做笔触(也叫做描边),一个叫做填充。
1. 笔触(描边) strokeRect(x,y,w,h)
参数,x,y 左上角起点坐标,w,h为绘制矩形的宽高
1.1 笔触的使用:
//笔触
ctx.strokeRect(100,100,300,40);
你会发现只有描边没有填充色
fillRect() API绘制的矩形是有填充色的
1.2 设置笔触的颜色
// 设置笔触颜色
ctx.strokeStyle = 'red';
// 绘制笔触矩形
ctx.strokeRect(100,100,300,50);
此时你就会发现你绘制的是一个没有填充色,只有红色边框的矩形
1.3 绘制笔触的宽度
ctx.lineWidth = 20; // 设置笔触的宽为20
1.4 笔触绘制线段
moveTo() 绘制开始位置 lineTo() 画笔移动的下一个wezhi
ctx.moveTo(100,100); //将画笔移动到一个位置(先移动到开始点的位置)
ctx.lineTo(300,300); //用画笔画,此时是抽象的一个线,没有显示在画布上(下一个点的位置)
ctx.stroke(); //划线(告诉浏览器,我说完了,你画吧)
我们可以多次使用lineTo:
告诉浏览器下一个点的位置,来绘制相邻点之间的线段
ctx.moveTo(100,100); // 将画笔移动到一个位置
ctx.lineTo(300,300); // 准备绘制从开始点到这个点的线,
ctx.lineTo(300,200); // 准备绘制从上一个点到这个点的线,
ctx.lineTo(430,180); // 准备绘制从上一个点到这个点的线,
ctx.stroke(); // 正式开始划线
1.5 闭合路径
而且我们还可以使用closePath() ,来闭合路径
就是浏览器会自动的在开始点moveTo的点和最后一个lineTo的结束点之间绘制一条线
ctx.beginPath(); // 开始准备画线
ctx.moveTo(100,100); // 将画笔移动到一个位置
ctx.lineTo(300,300); // 准备绘制从开始点到这个点的线,
ctx.lineTo(300,200); // 准备绘制从上一个点到这个点的线,
ctx.lineTo(430,180); // 准备绘制从上一个点到这个点的线,
ctx.closePath(); // 闭合路径
ctx.stroke(); // 正式开始划线
1.6 绘制新的线条开始
可以使用beginPath() 表示开始一个新的路径
ctx.beginPath()
ctx.moveTo(50, 50);
ctx.lineTo(300, 300);
ctx.stroke()
ctx.beginPath()
ctx.lineTo(300, 200);
ctx.lineTo(430, 180);
ctx.stroke()
可以使用lineWidth属性设置线的宽度
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(300,300);
ctx.lineTo(300,200);
ctx.lineTo(430,180);
ctx.strokeStyle = 'red';// 绘制描边的颜色
ctx.closePath(); // 闭合路径
ctx.lineWidth = '10'; // 绘制线的宽度
ctx.stroke();
ctx.filStyle = 'skyblue';// 绘制填充颜色
ctx.fill(); // 绘制填充色
1.7 绘制线条的转角
lineJoin : 边界连接点样式
miter(默认值),round(圆角),bevel(斜角)
ctx.moveTo(50, 50);
ctx.lineTo(300, 300);
ctx.lineTo(300, 200);
ctx.lineTo(430, 180);
ctx.closePath()
ctx.strokeStyle = 'red';
ctx.lineWidth = 20;
ctx.lineJoin = 'round'
ctx.stroke()
1.8 端点样式
lineCap: 端点样式
butt(默认值),round(圆角),square(高度多出线宽一半)
ctx.moveTo(50, 50);
ctx.lineTo(300, 300);
ctx.strokeStyle = 'red';
ctx.lineWidth = 50;
ctx.lineCap = 'round'
ctx.stroke()
2. 填充 fill()
还可以是用fill()给闭合路径后的闭合区域填充颜色
ctx.beginPath(); // 开始准备画线
ctx.moveTo(100,100); // 将画笔移动到一个位置
ctx.lineTo(300,300); // 准备绘制从开始点到这个点的线,
ctx.lineTo(300,200); // 准备绘制从上一个点到这个点的线,
ctx.lineTo(430,180); // 准备绘制从上一个点到这个点的线,
ctx.closePath(); // 闭合路径
ctx.stroke(); // 正式开始划线
ctx.fill(); // 绘制填充色
2.1 绘制填充颜色 fillStyle
strokeStyle 属性修改描边颜色
fillStyle 属性修改填充颜色
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(300,300);
ctx.lineTo(300,200);
ctx.lineTo(430,180);
ctx.strokeStyle = 'red';// 绘制描边的颜色
ctx.closePath(); // 闭合路径
ctx.stroke();
ctx.filStyle = 'skyblue';// 绘制填充颜色
ctx.fill(); // 绘制填充色
三.弧与圆形
1. 绘制弧度及圆形的公式
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
1.1 参数
- x,y为圆心的坐标
- radius 为圆形的半径
- startAngle 为弧度的起始位置,0是正x轴的
- endAngle 为弧度的终点位置,
- anticlockwise 布尔值,true为逆时针绘制,false为顺时针绘制
1.2 注意
canvas中角度是弧度制
弧和圆形也是笔触(描边),所以也需要以beginPath()开始
var ctx = mycanvas.getContext('2d');
ctx.beginPath();
ctx.arc(150,150,100,0,2*Math.PI,false);
ctx.arc(200,200,100,0,2,false);
ctx.arc(150,150,100,2,2,false);
ctx.fill();
ctx.beginPath();
ctx.arc(150,150,100,2,0,true);
ctx.strokeStyle= 'red';
ctx.lineWidth = 2;
ctx.stroke();
四. 绘制曲线
1. 绘制弧度曲线
arcTo(x1,y1,x2,y2,r)
x1,y1 坐标一 x2,y2坐标二 r圆弧半径
ctx.moveTo(100, 300)
ctx.arcTo(100, 100, 200, 100, 50)
ctx.stroke()
2. 绘制贝塞尔曲线
2.1 绘制公式
ctx.quadraticCurveTo(cp1x,cp1y,x,y)
2.2 参数
- cp1x, cp1y 为贝塞尔曲线的控制点
- x,y 为绘制曲线的终点
ctx.beginPath()
ctx.moveTo(100,100);
ctx.quadraticCurveTo(200,100,200,200)
ctx.stroke();
3. 绘制二次贝塞尔曲线
3.1 绘制公式
ctx.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y)
3.2 参数
- cp1x, cp1y 为贝塞尔曲线的第一个控制点
- cp2x, cp3y 为贝塞尔曲线的第二个控制点
- x,y 为绘制曲线的终点
ctx.beginPath()
ctx.moveTo(100,100);
ctx.bezierCurveTo(200,120,50,150,200,200);
ctx.stroke();
五. canvas变换
1. translate(x,y)
坐标基准点偏移 : 从起始点为基准,移动到当前位置
ctx.translate(100, 100)
ctx.arc(100, 100, 50, 0, Math.PI * 2, true)
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;
ctx.stroke()
2.rotate(弧度):
旋转 弧度公式 :角度*PI/180
以画布左上角为基点
ctx.rotate(Math.PI / 180 * 30)
ctx.rect(200, 200, 100, 100)
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;
ctx.stroke()
3. scale(wb,hb)
缩放比例(缩放canvas绘制的图片)
ctx.scale(1.5, 1.5)
ctx.rect(200, 200, 100, 100)
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;
ctx.stroke()
这里不单单将宽高放到,圆心坐标也会乘以倍数
六. 保存与恢复路径
1. 保存路径 save()
2.恢复路径 restore()
ctx.save()
ctx.scale(3, 2)
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 100, 20)
ctx.restore()
ctx.beginPath()
ctx.fillRect(0, 50, 100, 20)
会封闭一个独立路径 不会对外边的区域产生影响
七 绘制图片
1. 绘制图片
1.1 创建图片对象,获取图片
图片预加载,获取图片文件
const img = new Image();
img.src = '../1.jpg'
1.2 onload事件,当图片加载完成执行绘制
img.onload = function(){}
1.3 图片加载完成后将图片绘制在画布上
ctx.drawImage(image, dx, dy, dWidth, dHeight);
绘制图片(图片对象,画布坐标x,画布坐标y,绘制显示图片宽度,绘制显示图片高度)
const img = new Image();
img.src = '../1.jpg';
img.onload = function () {
ctx.drawImage(this, 0, 0, 100, 300)
}
1.4 切图
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
参数:
-
image 绘制到上下文的元素
-
sx 可选
需要绘制到目标上下文中的,
image
的矩形(裁剪)选择框的左上角 X 轴坐标。 -
sy 可选
需要绘制到目标上下文中的,
image
的矩形(裁剪)选择框的左上角 Y 轴坐标。 -
sWidth 可选
需要绘制到目标上下文中的,
image
的矩形(裁剪)选择框的宽度。 -
sHeight 可选
需要绘制到目标上下文中的,
image
的矩形(裁剪)选择框的高度。 -
dx
image
的左上角在目标canvas上 X 轴坐标。 -
dy
image
的左上角在目标canvas上 Y 轴坐标。 -
dWidth 可选
image
在目标canvas上绘制的宽度。 -
dHeight 可选
image
在目标canvas上绘制的高度。 允许对绘制的image
进行缩放。
const img = new Image();
img.src = '../1.jpg';
img.onload = function () {
ctx.drawImage(this, 50, 50, 500, 500, 100, 100, 100, 100)
}
2. 填充背景
2.1 createPattern(img,平铺方式)
参数: 平铺方式:repeat,repeat-x,repeat-y,no-repeat
const img = new Image();
img.src = '../1.jpg';
img.onload = function () {
const bg = ctx.createPattern(img, 'no-repeat');
ctx.fillStyle = bg;
ctx.fillRect(100, 100, 300, 200)
}
3. 颜色渐变
3.1 线性渐变:createLinearGradient(x1,y1,x2,y2)
x1,y1起始坐标点
x2,y2结束坐标点
3.2 径向渐变:createRadialGradient(x1,y1,r1,x2,y2,r2)
x1,y1,r1内圆坐标及半径
x2,y2,r2外圆坐标及半径
3.3 addColorStop(位置,颜色)
位置:渐变点 0-1之间 可多个
例子,
线性渐变
let color = ctx.createLinearGradient(0, 0, 500, 500);
color.addColorStop(0, 'pink');
color.addColorStop(0.5, 'yellow')
color.addColorStop(1, 'deeppink')
ctx.fillStyle = color;
ctx.fillRect(0, 0, 500, 500)
径向渐变
let color = ctx.createRadialGradient(200, 200, 100, 200, 200, 200);
color.addColorStop(0, 'pink');
color.addColorStop(0.5, 'yellow')
color.addColorStop(1, 'deeppink')
ctx.fillStyle = color;
ctx.fillRect(0, 0, 500, 500)
八.绘制文本
1. 绘制文本
- strokeText(文本,x,y); 绘制空心文本
- fillText(文本,x,y); 绘制实心文本
- font = “font-size font-family” 注:尺寸 字体缺一不可
- textAlign = “”;文本左右对齐方式
start center end left right - textBaseline文本上下对齐方式
alphabetic 默认。文本基线是普通的字母基线。
top 文本基线是 em 方框的顶端。。
hanging 文本基线是悬挂基线。
middle 文本基线是 em 方框的正中。
ideographic 文本基线是表意基线。
bottom 文本基线是 em 方框的底端。
measureText(文本).width; 文本实际宽度(只有宽度值)
let str = 'wuwei'
ctx.font = '50px 宋体'
ctx.textAlign = 'center'
ctx.textBaseline = 'top'
ctx.strokeText(str, 100, 100)
ctx.fillText(str, 100, 200)
2. 绘制阴影
- shadowOffsetX,shadowOffsetY x轴、y轴偏移
- shadowBlur 阴影模糊度
- shadowColor 阴影颜色
默认颜色:rgba(0,0,0,0)
ctx.shadowOffsetX = '10'
ctx.shadowOffsetY = '10'
ctx.shadowBlur = '3'
ctx.shadowColor = 'red'
九.API使用总结
1. canvas标签
<canvas width="" height="" id="">
您的浏览器不支持canvas,请更换浏览器!
</canvas>
默认宽度300px,默认高度 150px
2. canvas绘图环境设置
getContext(“2d”); 目前支持2d绘图环境
3.绘图路径:
- beginPath() :开始路径
- closePath():闭合路径
- moveTo(x,y):将触笔移动到x,y点
- lineTo(x,y):绘制到x,y点
- stroke(): 触笔方法 画线 默认为黑色
- fill():填充方法
- rect(x,y,w,h):矩形路径
- save():保存路径
- restore():恢复路径
4. 绘制矩形:
- fillRect(x,y,w,h) 填充实心矩形
- strokeRect(x,y,w,h) 绘制空心矩形
- clearRect(x,y,w,h) 清除矩形选区
5. 设置绘图样式:
- fillStyle: 填充颜色
- strokeStyle: 触笔颜色
- lineWidth: 触笔宽度(线宽)
6. 图形边界样式:
- lineJoin : 边界连接点样式
miter(默认值),round(圆角),bevel(斜角) - lineCap: 端点样式
butt(默认值),round(圆角),square(高度多出线宽一半)
7. 绘制圆形:
- arc(x,y,r,0,360,false)
x,y 圆心坐标位置
r 圆半径
0,360 从0度到360度 绘制一个圆形(用弧度公式)
true/false 逆时针/顺时针绘图
8. 绘制曲线
- arcTo(x1,y1,x2,y2,r)
x1,y1 坐标一 x2,y2坐标二 r圆弧半斤 - quadraticCurveTo(dx,dy,x1,y1)
贝塞尔曲线:dx,dy控制点 x1,y1结束坐标 - bezierCurveTo(dx1,dy1,dx2,dy2,x1,y1)
贝塞尔曲线:dx1,dy1 控制点一 dx2,dy2控制点二
x1,y1结束坐标
9. canvas变换
- translate(x,y)
坐标基准点偏移 : 从起始点为基准,移动到当前位置 - rotate(弧度): 旋转 弧度公式 :角度*PI/180
- scale(wb,hb)缩放比例(缩放canvas绘制的图片)
10. 绘制图片
- 图片预加载,获取图片文件
- onload事件,监听图片是否加载完毕,如果加载完毕执行第三步
- drawImage(img,x,y,w,h);绘制图片(图片,坐标x,坐标y,宽度,高度)
11.设置背景
- createPattern(img,平铺方式)
平铺方式:repeat,repeat-x,repeat-y,no-repeat
12. 颜色渐变
- 线性渐变:createLinearGradient(x1,y1,x2,y2)
x1,y1起始坐标点
x2,y2结束坐标点 - 径向渐变:createRadialGradient(x1,y1,r1,x2,y2,r2)
x1,y1,r1内圆坐标及半径
x2,y2,r2外圆坐标及半径 - addColorStop(位置,颜色)
位置:渐变点 0-1之间 可多个
13. 绘制文本
- strokeText(文本,x,y); 绘制空心文本
- fillText(文本,x,y); 绘制实心文本
- font = “font-size font-family” 注:尺寸 字体缺一不可
- textAlign = “”;文本左右对齐方式
start center end left right - textBaseline文本上下对齐方式
alphabetic 默认。文本基线是普通的字母基线。
top 文本基线是 em 方框的顶端。。
hanging 文本基线是悬挂基线。
middle 文本基线是 em 方框的正中。
ideographic 文本基线是表意基线。
bottom 文本基线是 em 方框的底端。 - measureText(文本).width; 文本实际宽度(只有宽度值)
14. 阴影
- shadowOffsetX,shadowOffsetY x轴、y轴偏移
- shadowBlur 阴影模糊度
- shadowColor 阴影颜色
- 默认颜色:rgba(0,0,0,0)