html5中的<canvas>标签是一个可以使用js脚本在其中绘图的html元素。有强大的API,可用于制作照片集或制作简单的动画。有人说canvas是html5的精髓。
一、基本用法
1、初始画布
一般会拿<canvas>和<img>对比,因为它画出来也是张图片,但实际上没什么可比性。canvas只有width和height属性,而且还是可选的。如果没有给canvas样式和宽高,则它是透明的,默认大小为300px*150px;可通过css设置,有时候面试题会问anvas的默认大小是多少?。
画笔默认颜色是黑色。
举例:初始画布
给canvas加上边框,就可以清楚的看到初始画布大小:300px*150px
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Canvas</title> <style type="text/css"> canvas { border: 1px solid black; } </style> </head> <body> <canvas id="myCanvas"></canvas> </body> </html>
渲染过程图片会缩放以适应布局大小。如果图片的宽高比和canvas的不同,可能会出现变形。
Note:如果图片出现变形,在<canvas>标签中直接设置宽高,而不要在css中设置。
2、后备内容
<canvas>可以像<video>,<audio>或者<picture>元素一样,在不支持它的浏览器中给一些后备内容(fallback content)。
后备内容写在<canvas></canvas>之间的内容,不支持canvas的浏览器忽略canvas渲染里面的内容,支持canvas的浏览器忽略后备内容,正常渲染canvas。
所以在低版本浏览器最好给出一些后备内容描述canvas的内容,可以是文字或者图片。
Note:也是因为后备内容的关系,必须有</canvas>闭合标签,否则后面所以内容会被当成后备内容,在浏览器支持canvas时不显示。
3、渲染上下文
canvas有一个固定大小的画布,可以有一个或多个渲染上下文,用来创建和操作绘图。现在只关注2d渲染上下文。 WebGL用的是3d渲染上下文。
getContext("2d") 对象是内建的 HTML5 对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的API。
一个画布初始是空白的,要想作画,首先脚本要获取渲染上下文才能在画布上作画。<canvas>元素通过getContext()
来获取一个渲染上下文,和画图方法。getContext()有一个参数,2d画图只需要一个"2d"即可获取一个 CanvasRenderingContext2D
。
所以画图首先需要的就是两步:
var canvas=document.getElementById('myCanvas'); var ctx=canvas.getContext('2d');
举例:一个简单的例子
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Canvas</title> <style type="text/css"> canvas { border: 1px solid black; } </style> </head> <body> <canvas id="myCanvas" width="150" height="150"></canvas> <script type="text/javascript"> var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); ctx.fillStyle="rgb(200,0,0)"; ctx.fillRect(10, 10, 55, 50); ctx.fillStyle="rgba(0, 0, 200, 0.5)"; ctx.fillRect(30, 30, 55, 50); </script> </body> </html>
二、绘制图形
通过基本用法我们已经可以画简单的图了,使用canvas主要是要掌握几个画图方法,现在深入了解一下。
1、canvas坐标
默认情况:1个格子对应1px,从(0,0)开始。
我们可以通过一些手段平移坐标起点,旋转甚至缩放网格。现在就以默认情况介绍。复杂的图都是由简单的组合来的,现一一介绍。
2、画矩形
三个函数:
fillRect(x, y, width, height)
:画一个填充矩形
strokeRect(x, y, width, height)
:画矩形轮廓。【stroke英文意思是“笔画”,所以看到的是落笔与起笔之间的笔画】
clearRect(x, y, width, height)
:清除指定的矩形区域,使其完全透明。类似橡皮擦。
参数含义都一样:x,y表示相对origin【默认就是相对左上角】的一个画图起点,width,height就是矩形的大小。
举例:
ctx.fillRect(25,25,100,100);//画一个黑色最大填充矩形 ctx.clearRect(45,45,60,60);//擦除一块中等大小透明矩形 ctx.strokeRect(50,50,50,50);//画一个小矩形轮廓
3、绘制路径
这里路径指的是很多被线段连接起来的点,可以有不同的形状,完全,颜色和粗细。
绘制路径步骤:
a、创建path
b、使用 drawing commands 绘制路径
c、闭合路径
d、渲染路径
用到的函数:
beginPath()
:创建一个新的路径,之后的绘图命令直接作用于于该路径。
Path methods:该方法为对象设置不同的路径。
closePath()
:关闭路径,很重要,让之后的绘图命令再次回到上下文。
stroke()
:绘制路径轮廓。
fill()
:填充路径。
Note:调用了fill()方法后,一些打开的shapes自动关闭,而调用stroke却不会自动关闭。下面举例来说明这点。
举例:画三角形,stroke不会自动闭合,fill自动闭合。
<script type="text/javascript"> var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); var path=new Path2D(); path.moveTo(75,50); path.lineTo(100,75); path.lineTo(100,25); // ctx.stroke(path); ctx.fill(path); </script>
分析:可见stroke不会自动闭合路径,我们可以通过stroke看到绘制路径的过程。
4、移动画笔Moving the pen
移动画笔指的是一个上面例子中用到的一个函数——moveTo(x,y)。
初始化一张画布,首先就是举起画笔移动到要作画的位置,就是要用moveTo(x,y)函数。
可以类比一下moveTo就相当于在空中画线,不会在画布上留下任何痕迹,延伸一下,我们就知道可以用moveTo来画一些独立路径。
举例:
<script type="text/javascript"> var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); var path=new Path2D(); path.arc(75,75,50,0,Math.PI*2,true);//外部圆圈 path.moveTo(110,75); path.arc(75,75,35,0,Math.PI,false); //顺时针画半个圆做嘴巴 path.moveTo(65,65); path.arc(60,65,5,0,Math.PI*2,true);//左眼 path.moveTo(95,65); path.arc(90,65,5,0,Math.PI*2,true);//右眼 ctx.stroke(path); </script>
5、画线
画线用LineTo(x,y)函数,表示从当前位置画一条到左边(x,y)的线,起点可通过moveTo()函数重置。
举例:
<script type="text/javascript"> var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); //填充三角形 var ftriangle=new Path2D(); ftriangle.moveTo(25,25); ftriangle.lineTo(105,25); ftriangle.lineTo(25,105); ctx.fill(ftriangle); //三角形轮廓 var striangle=new Path2D(); striangle.moveTo(125,125); striangle.lineTo(125,45); striangle.lineTo(45,125); striangle.closePath(); //显示闭合路径 ctx.stroke(striangle); </script>
5、弧线
画弧和画圆都用arc()或arcTo()函数。
arc(x,y,radius,startAngle,endAngle,acticlockwise)
画弧,弧心为(x,y),半径为radius,起始弧为startAngle,终止弧到endAngle,方向按照anticlockwise来画。【clockwise意思是“顺时针”,加了anti-前缀就是逆时针,所以默认是逆时针画弧,可通过true和false来控制】
arcTo(x1,y1,x2,y2,radius)
arcTo()在画布上创建介于两个切线之间的弧/曲线。
6、曲线
贝塞尔曲线:
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
二次曲线:
quadraticCurveTo(cp1x, cp1y, x, y)
(cp1x,cp1y)--控制点 此函数表示从当前的画笔位置到(x,y)画一条二次曲线
var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(20, 20); ctx.quadraticCurveTo(20, 100, 200, 20); ctx.stroke();
Note:二次贝塞尔曲线需要两个点。第一个点是用于二次贝塞尔计算中的控制点,第二个点是曲线的结束点。曲线的开始点是当前路径中最后一个点。如果路径不存在,那么请使用 beginPath() 和 moveTo() 方法来定义开始点。
- 开始点:moveTo(20,20)
- 控制点:quadraticCurveTo(20,100,200,20)
- 结束点:quadraticCurveTo(20,100,200,20)
三、样式和颜色
主要是美化作用, 画线时添加不同颜色,线型,渐变,模式和阴影。
1、颜色
应用颜色用到两个重要属性:fillStyle和strokeStyle。
fillStyle=color:填充色。
strokeStyle=color:轮廓色。
//设置橘色的不同写法
ctx.fillStyle = "orange";
ctx.fillStyle = "#FFA500";
ctx.fillStyle = "rgb(255,165,0)";
ctx.fillStyle = "rgba(255,165,0,1)";
fillStyle取值color可以是普通颜色或一个渐变图片。
用的时候注意,想换种颜色就必须再次调用fillStyle或strokeStyle属性。
fillStyle举例:
<script type="text/javascript"> var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); for(var i=0;i<6;i++){ for(j=0;j<6;j++){ ctx.fillStyle='rgb('+Math.floor(255-42.5*i)+','+Math.floor(255-42.5*j)+',0)'; ctx.fillRect(j*25,i*25,25,25); } } </script>
strokeStyle举例:
<script type="text/javascript"> var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); for(var i=0;i<6;i++){ for(j=0;j<6;j++){ ctx.strokeStyle='rgb('+Math.floor(255-42.5*i)+','+Math.floor(255-42.5*j)+',0)'; ctx.beginPath(); ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true); ctx.stroke(); } } </script>
如果只是修改上例中fillStyle和fillRect为strokeStyle和strokeRect,效果如上图左。
改为画圆的方式,效果如上图右。
要画半透明图时,需要用到一个属性:globalAlpha
globalAlpha=trnaparencyVlaue。
这是个全局属性,对所有元素都起作用,要在局部图形使用透明度,可给fillStyle或strokeStyle赋值raba颜色。
2、线型
lineWidth:线宽。可选值:number,当前线条的宽度,单位px。
lineCap:线帽,即线段终点样式。可选值:butt默认,向线条的每个末端添加平直的边缘;round,向线条的每个末端添加圆形线帽;square向线条的每个末端添加正方形线帽。
lineJoin:两条线段交汇时,边角的类型。可选值:bevel斜角,round圆角,miter默认尖角。
miterLimit:miterLimit 属性设置或返回最大斜接长度。只有当 lineJoin 属性为 "miter" 时,miterLimit 才有效。
可选值:number,正数,规定最大斜接长度,如果斜接长度超过 miterLimit 的值,边角会以 lineJoin 的 "bevel" 类型来显示(Fig 3)。
getLineDash():获取当前线段样式,返回一个 Array
数组。一组描述交替绘制线段和间距(坐标空间单位)长度的数字。如果数组元素的数量是奇数,数组元素会被复制并重复。 例如, 设置线段为 [5, 15, 25]
将会得到以下返回值 [5, 15, 25, 5, 15, 25]。
3、渐变
四、使用图片
五、转换
六、合成
七、基本动画 优化canvas。
本文作者starof,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:http://www.cnblogs.com/starof/p/4596759.html 有问题欢迎与我讨论,共同进步。
写于2015-06-24 08:54