一、前言
Canvas是HTML5标准中推出的一个非常受欢迎的功能元素,这个元素负责在页面中设定一个区域,然后就可以JS动态地在这个区域中绘制图形了。并且它还是跨平台动画和游戏的标准方案。
二、前提条件
2.1 初始化
要使用canvas元素必须先设置其width和height属性,指定绘图区域的大小。
如果浏览器不支持该功能,那么将会显示你在canvas标签中键入的文本内容。
<!-- 宽度为400,高度为400的canvas --> <canvas id="myCvs" width="400" height="400"> Your browser does not support canvas. </canvas>
2.2 创建绘图环境
在使用canvas元素之前,必须保证要有一个2d的绘图环境。
if(myCvs.getContext) { var context = myCvs.getContext('2d'); }else { console.log('Your browser does not support canvas.'); }
使用2d绘图环境提供的方法,可以绘制简单的2d图形,比如矩形、弧线和路径。
它的坐标原点(0, 0)在canvas元素的左上角。
2.3 案例
在学习2d绘图方法之前,我们试着看一下canvas的一个简单例子:画一个绿色矩形。
<!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>Canvas</title> <style> canvas { border: 1px solid #000; } </style> </head> <body> <!-- 宽度为400,高度为400的canvas --> <canvas id="myCvs" width="400" height="400"> Your browser does not support canvas. </canvas> <script> var myCvs = document.getElementById('myCvs'); // 检测是否支持2d上下文 if(myCvs.getContext) { var context = myCvs.getContext('2d'); }else { console.log('Your browser does not support canvas.'); } function load() { context.fillStyle = '#0f0'; // 填充颜色为绿色 context.fillRect(50,25,300,150); // 填充矩形 (起点x坐标, 起点y坐标, 宽度, 高度) } window.onload = function() { load(); } </script> </body> </html>
三、基础使用
canvas在2d上下文环境中提供了一些可供画图的属性和方法,接下来具体看一下。
3.1 描边和填充
描边,就是只在图形的边缘画线;
填充,就是用指定的样式(颜色、渐变或图像)填充图像。
var myCvs = document.getElementById('myCvs'); if(myCvs.getContext) { var context = myCvs.getContext('2d'); context.strokeStyle = 'red'; // 描边 context.fillStyle = 'green'; // 填充 }
3.2 绘制矩形
矩形是唯一一种可以直接在2d上下文中绘制的形状。
与矩形有关的方法包括fillRect()、strokeRect()和clearRect()。
它们接收4个参数:矩形的x坐标,矩形的y坐标,矩形宽度和矩形高度。单位都是像素。
3.2.1 fillRect() 填充矩形
// 绘制红色矩形 context.fillStyle = 'red'; // 指定填充颜色为红色 context.fillRect(10,10,50,50); // 指定填充矩形的4个参数
3.2.2 strokeRect() 描边矩形
// 绘制绿色描边矩形 context.strokeStyle = 'green'; // 指定描边颜色 context.strokeRect(70,10,50,50); // 指定描边矩形的4个参数
3.2.3 clearRect() 清除矩形区域
// 清除画布矩形区域 context.clearRect(0,0,400,400);
3.3 绘制路径
通过路径可以创造出复杂的形状和线条。
3.3.1 路径方法
- arc(x, y, radius, startAngle, endAngle, counterclockwise):以(x, y)为圆心绘制一条弧线,弧线半径为radius,起始和结束角度(弧度)分别为 startAngle和endAngle,最后一个参数counterclockwise表示绘制方向是否按照逆时针方向计算,值false表示按顺时针方向计算。
- arcTo(x1, y1, x2, y2, radius):从上一点开始绘制一条弧线,到(x2,y2)为止,并且以给定半径radius穿过(x1,y1)。
- bezierCurveTo(c1x, c1y, c2x, c2y, x, y):从上一点开始绘制一条曲线,到(x,y)为止,并且以(c1x,c1y)和(c2x,c2y)为控制点。
- lineTo(x, y):从上一点开始绘制一条直线,到(x,y)为止。
- moveTo(x, y):将绘图画笔移动到(x, y),不画图。一般后面就接lineTo()方法。
- quadraticCurveTo(cx, cy, x, y):从上一点开始绘制一条二次曲线,到(x, y)为止,并且以(cx, cy)作为控制点。
- rect(x, y, width, height):从点(x, y)开始绘制一个矩形,宽度和高度分别由width和height指定。注意这里画的是矩形路径而不是独立形状。
3.3.2 绘制流程
在绘制路径之前,必须调用beginPath()方法,表示要开始绘制新的路径了。
在创建了新的路径之后,如果想要绘制一条连接到路径起点的线条,那么就调用closePath()方法;
如果路径已经完成,想要填充它那么就调用fill()方法,想要描边就调用stroke()方法。
3.3.3 案例
画线
// 画线组成矩形 context.beginPath(); // 指定新路径 context.moveTo(10,70); // 画笔移动至(10,70) context.lineTo(10,120); // 第一点坐标 context.lineTo(60,120); // 第二点坐标 context.lineTo(60,70); // 第三点坐标 context.closePath(); // 闭合路径 context.strokeStyle = 'blue'; // 指定描边颜色 context.stroke(); // 描边
画圆弧
// 画圆弧 context.beginPath(); context.arc(95,95,25,0,2*Math.PI,true); // 圆心(95,95) 起始角度0弧度 结束角度2PI弧度 逆时针方向计算 context.closePath(); context.stroke();
三角形
// 三角形 context.beginPath(); context.moveTo(150, 70); // 第一点坐标 context.lineTo(125, 120); // 第二点坐标 context.lineTo(175, 120); // 第三点坐标 context.closePath(); context.fillStyle = 'yellow' // 指定填充颜色 context.fill(); // 填充
贝塞尔曲线
// 二次贝塞尔曲线(1个控制点) context.beginPath(); context.moveTo(10, 155); // 画笔移动到(10,155) context.quadraticCurveTo(60, 200, 300, 155); // 控制点坐标(60,200) 结束点坐标(300,155) context.stroke(); // 三次贝塞尔曲线(2个控制点) context.beginPath(); context.moveTo(10, 355); // 画笔移动到(10,355) context.bezierCurveTo(90, 200, 150, 300, 350, 350); // 控制点坐标(90,200)和(150,300) 结束点坐标(350,350) context.strokeStyle = 'green'; context.stroke();
案例结果如图所示:
四、Canvas的图形变换
在Canvas的2d上下文中还支持各种基本的绘制变换。
这里介绍平移、旋转、缩放三种变换在Canvas中的实现。
4.1 保存与恢复
在了解各种变换之前,我们先想一个这样的问题:在用canvas画图时,如果我们频繁使用几个默认值的设定,是否可以重置为默认值而不必重复定义呢?
这时就要用到2d上下文提供的保存和恢复的方法了,即save()和restore()方法,它们是以堆栈**(先进后出)的形式保存绘图上下文的设置和变换**。
这里看个例子,依次保存然后依次恢复读取设置的颜色。
var myCvs = document.getElementById('myCvs'); var ctx = myCvs.getContext('2d'); ctx.strokeStyle = '#f00'; ctx.save(); // 保存指定颜色-红色 ctx.strokeStyle = '#0f0'; ctx.save(); // 保存指定颜色-绿色 ctx.strokeStyle = '#00f'; ctx.save(); // 保存指定颜色-蓝色 ctx.restore(); // 恢复指定颜色-蓝色 ctx.strokeRect(10, 10, 50, 50); ctx.restore(); // 恢复指定颜色-绿色 ctx.strokeRect(70, 10, 50, 50); ctx.restore(); // 恢复指定颜色-红色 ctx.strokeRect(130, 10, 50, 50);