前言
canvas
是H5新增的标签元素。canvas
意思为画布,我们可以通过js在上面绘制图形。应用场景,比如运动轨迹、人像的标注、个性化海报、炫酷特效等等。
基础&概念
创建一个画布(Canvas)
<canvas id="myCanvas" width="200" height="100"></canvas>
复制代码
注意:画布默认大小是300*150,不能用css去修改大小,可以利用画布的标签属性width
和height
修改;canvas
是一个双标签。
兼容性与支持
Mozilla 程序从 Gecko 1.8 (Firefox 1.5) 开始支持 <canvas>
, Internet Explorer 从 IE9 开始 <canvas>
。Chrome 和 Opera 9+ 也支持 <canvas>
。
<canvas>
你的浏览器不支持 canvas,请升级你的浏览器。
</canvas>
复制代码
检测支持性
var canvas = document.getElementById('tutorial');
if (canvas.getContext){
var ctx = canvas.getContext('2d');
//开始画图
} else {
// 不支持canvas
}
复制代码
注意: 支持 <canvas>
的浏览器只会渲染 <canvas>
标签,而忽略其中的文本内容。不支持 <canvas>
的浏览器则会直接显示文本内容;当然这个文本内容也可以换成一张图片。
渲染上下文
这里的getContext()
方法可以理解为工具箱,我们可以使用里面的工具进行绘制图形。
var mycanvas = document.getElementById('mycanvas');
//获得 2d 上下文对象
var ctx = mycanvas.getContext('2d');
复制代码
开始画直线
Q1:想一想,为什么有起点和终点?
//起点
ctx.moveTo(100, 100)
// 终点
ctx.lineTo(200, 100)
// Q2:对线进行描边这里的strock()是什么?
ctx.stroke();
复制代码
绘制形状(Q1)
canvas元素绘制图像的时候有两种方法(F-Q2)
context.fill()//闭合图形填充
context.stroke()//线段描边
复制代码
像素栅格
(F-Q1):canvas
元素默认被网格所覆盖。通常来说网格中的一个单元相当于 canvas
元素中的一像素。栅格的起点为左上角,坐标为 (0,0) 。所有元素的位置都相对于原点来定位。
绘制路径
上面说过,像素格组成我们的画布,所以路径就可以理解为,所有画布所有像素对的集合,只是我们规定了路径轨迹和像素点颜色,任意路径都是闭合的。
步骤:
- 创建路径起始点
- 调用绘制方法去绘制出路径
- 把路径封闭
- 一旦路径生成,通过描边或填充路径区域来渲染图形。
绘制线段
/*绘制线条*/
if (mycanvas.getContext) {
// 每个canvas节点上都有一个对应的context对象,要获取这个对象,方法是getCotext
let ctx=mycanvas.getContext("2d");
// 开启本次绘制
ctx.beginPath();
// 设置路径起点坐标
ctx.moveTo(50,50);
// 绘制一条线至坐标50 150
ctx.lineTo(150,50);
// 线条着色,描边
ctx.stroke();
// 结束本次绘制(闭合路径)
ctx.closePath();
} else {
alert("浏览器不支持")
}
复制代码
绘制矩形
重点留意下 fillStyle
fillRect()
strokeEect()
属性和方法的使用;
/*绘制矩形*/
if (mycanvas.getContext) {
let ctx = mycanvas.getContext("2d");
ctx.beginPath();
// 设置填充颜色
ctx.fillStyle = '#cfa';
//ctx.fillRect填充 (x,y,width,height)起始坐标值和矩形宽高
ctx.fillRect(500, 100, 200, 100);
// clearRect方法用来清除某个矩形区域的内容, (x,y,width,height)起始坐标值和矩形宽高
ctx.clearRect(525, 125, 50, 50)
//ctx.strokeRect 描边,ctx.strokeStyle 描边的颜色
ctx.strokeStyle = 'red'
ctx.strokeRect(50, 50, 100, 100);
ctx.closePath();
} else {
alert("浏览器不支持")
}
复制代码
结果如下所示:
【注意】
绘制圆形(这里默认画出的是空心圆)
if (mycanvas.getContext) {
let ctx = mycanvas.getContext("2d");
ctx.beginPath();
// arc方法的x和y参数是圆心坐标,radius是半径,startAngle和endAngle则是扇形的起始角度和终止角度(以弧度表示),anticlockwise表示做图时应该逆时针画(true)还是顺时针画(false)。
//ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
ctx.arc(200, 400, 100, 0, Math.PI * 2, true);
// ctx.fillStyle = "#cfa";
ctx.stroke();//空心圆
// ctx.fill();//实心圆
ctx.closePath();
} else {
alert("浏览器不支持")
}
复制代码
注意: 弧度=(Math.PI/180)*角度,思考一下利用这个我们是不是也可以画扇形?
特殊效果
绘制线条渐变
前面我门可以用css的渐变来实现线条渐变,这里我们试试用这个实现渐变。
if (mycanvas.getContext) {
let ctx = mycanvas.getContext("2d");
// createLinearGradient方法的参数是(x1, y1, x2, y2),
// 其中x1和y1是起点坐标,x2和y2是终点坐标。
// 通过不同的坐标值,可以生成从上至下、从左到右的渐变等等。
var myGradient = ctx.createLinearGradient(10, 10, 610, 30);
myGradient.addColorStop(0, "red");
myGradient.addColorStop(0.5, "green");
myGradient.addColorStop(1, "blue");
ctx.fillStyle = myGradient;
// 绘制矩形
ctx.fillRect(10, 10, 600, 20);
} else {
alert("浏览器不支持")
}
复制代码
效果:
绘制阴影
// /*绘制阴影*/
if (mycanvas.getContext) {
let ctx = mycanvas.getContext("2d");
ctx.shadowOffsetX = 5; // 设置水平位移
ctx.shadowOffsetY = 5; // 设置垂直位移
ctx.shadowBlur = 5; // 设置模糊度
ctx.shadowColor = "rgba(0,0,0,0.5)"; // 设置阴影颜色
ctx.fillStyle = "#CC0000";
ctx.fillRect(10, 600, 110, 20);
} else {
alert("浏览器不支持")
}
复制代码
效果:
绘制文本
canvas 有两种方法来渲染文本
fillText(text, x, y [, maxWidth])
//在指定的(x,y)位置填充指定的文本(text),绘制的最大宽度是可选的.
复制代码
strokeText(text, x, y [, maxWidth])
//在指定的(x,y)位置绘制文本边框(text),绘制的最大宽度是可选的.
复制代码
例子(想一想绘制文本有啥用?Q3)
var ctx;
function draw(){
var canvas = document.getElementById('tutorial');
if (!canvas.getContext) return;
ctx = canvas.getContext("2d");
ctx.font = "100px sans-serif"
ctx.fillText("想一想绘制文本有啥用?", 10, 100);
ctx.strokeText("想一想绘制文本有啥用?", 10, 200)
}
draw();
复制代码
绘制图片
我们也可以在canvas
上直接绘制图片;注意调整画布的宽高和图片相适应,效果会好点。
创建<img>
元素
var image = new Image();
image.src = "images/tu.jpg"
复制代码
绘制img
//参数1:要绘制的img 参数2、3:绘制的img在canvas中的坐标
ctx.drawImage(img,0,0);
复制代码
注意:考虑到图片是从网络加载,如果 drawImage
的时候图片还没有完全加载完成,则什么都不做,个别浏览器会抛异常。所以我们应该保证在 img
绘制完成之后再 drawImage
。
var img = new Image(); // 创建img元素
img.src = 'myImage.png'; // 设置图片源地址
img.onload = function(){
ctx.drawImage(img, 0, 0)
}
复制代码
绘制 img
标签元素中的图片
<img src="./tu.jpg" alt="" width="300"><br>
<canvas id="tutorial" width="600" height="400"></canvas>
<script type="text/javascript">
function draw(){
var canvas = document.getElementById('tutorial');
if (!canvas.getContext) return;
var ctx = canvas.getContext("2d");
var img = document.querySelector("img");
ctx.drawImage(img, 0, 0);
}
document.querySelector("img").onclick = function (){
draw();
}
</script>
复制代码
缩放图片
drawImage()
也可以再添加两个参数:drawImage(image, x, y, width, height)
这个方法多了2个参数:width
和 height,
这两个参数用来控制 当向canvas画入时应该缩放的大小。
ctx.drawImage(img, 0, 0, 400, 200)
复制代码
绘制图片+绘制文本--案例:水印(F-Q3)
1. 在html中准备canvas
<canvas id="myCanvas" width="1000" height="500" >
你的浏览器不支持 canvas,请升级你的浏览器。
</canvas>
复制代码
2. 加载图片
var img = new Image();
img.src = './img/demo.jpg';
复制代码
3. 绘制图片
img.onload=function(){
var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");
ctx.drawImage(img,0,0);
}
复制代码
4. 绘制水印 在canvas上绘制好图片之后,回到onload函数中,利用我们在上一步中获取的ctx对象,继续绘制水印。
ctx.font="20px microsoft yahei"; //定义水印的大小以及字体
ctx.fillStyle = "rgba(255,255,255,0.5)"; //自定义水印的颜色以及透明度
ctx.fillText("my images",100,100); //完成水印填充以及水印的位置定位
复制代码
源码
<canvas id="myCanvas" width="1000" height="500" >
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
//准备img对象
var img = new Image();
img.src = './img/demo.jpg';
// 加载完成开始绘制
img.onload=function(){
//准备canvas环境
var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");
// 绘制图片
ctx.drawImage(img,0,0);
// 绘制水印
ctx.font="20px microsoft yahei";
ctx.fillStyle = "rgba(255,255,255,0.5)";
ctx.fillText("洋葱水印",100,100);
}
</script>
复制代码
效果: