1.Canvas 本质上是一个位图画布,其上绘制的图形是不可缩放的,不能像 SVG 那样可以被放大缩小。
2.用 Canvas 绘制出的对象不属于页面 DOM 结构或者任何命名空间——这点被认为是一个缺陷。 SVG 图像却可以在不同的分辨率下流畅的缩放,并且支持单击检测(能检测到鼠标点击了图像上的哪个点)。
虽然 Canvas 有这些不足,但是 Canvas API 有两方面的优势可以弥补:首先,不需要将所绘制图像中的每个图元当做对象存储,因此执行性能非常好。
其次,在其他编程语言现有的优秀二维绘制 API 的基础上实现 Canvas API 相对来说比较简单。毕竟,二鸟在林不如一鸟在手。
<canvas></canvas>
默认创建一块矩形区域,宽 300 ,高 150 像素,可设置 border style 使其可见。
使用 canvas 编程,首先要获取其上下文( context ) . 然后在上下文中执行动作,最后将这些动作应用到上下文中。
Canvas 坐标从左上角开始, x 轴水平右延伸, y 轴垂直下延伸。左上角坐标为 x=0,y=0 ,称作原点。
检测浏览器支持代码:
try{ document.createElement(“canvas”).getContext(“2d”); document.getElementById(“support”).innerHTML= “HTML5 Canvas is supported in your browser.”; }catch(e){ document.getElementById(“support”).innerHTML= “HTML5 Canvas is not supported in your browser.”; }
不支持时替代内容写法:
<canvas> Update your browser to enjoy canvas! </canvas>
1. 画直线
html <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>canvas</title> <script type="text/javascript" src="../js/canvas/canvas1.js"></script> </head> <body> <canvas id="diagonal" width="200" height="200" style="border:1px solid;"> update your browser to support canvas </canvas> </body> </html>
Js:
window.addEventListener("load",drawcans,true); function drawcans() { var canvs = document.getElementById("diagonal"); var context = canvs.getContext("2d"); context.beginPath(); context.moveTo(70, 140); context.lineTo(140, 70); context.stroke(); }
2.变换
平移,缩放,旋转等
下面的 js 代码使用 translate 函数实现上面同样的对角线
function drawDiagonal(){ var canvas = document.getElementById("diagonal"); var context = canvas.getContext("2d"); context.save() ; context.translate(70,140); context.beginPath(); context.moveTo(0,0) ; context.lineTo(70,-70); context.stroke() ; context.restore(); }
3.路径
简而言之,上面两个函数的区别在于, moveTo 就像是提起画笔,移动到新位置,而 lineTo 告诉 canvas 用画笔从纸上的旧坐标画条直线到新坐标。不过,提醒大家,不管调用那个,都不会真正画出图形,因为还没有调用 stroke 或者 fill 函数。目前只是在定义路径的位置,以便后面绘制时使用。
closePath 会将起始坐标自动作为目标坐标,和 lineTo 很像。还会通知 canvas 当前的图形已经闭合或者形成了完全封闭的区域,这对将来填充和描边非常有用。
context.beginPath(); context.moveTo(-25,-50); context.lineTo(-10,-80); context.lineTo(-20,-80); context.lineTo(-5,-110); context.lineTo(-15,-110); context.lineTo(0,-140); context.lineTo(15,-110); context.lineTo(5,-110); context.lineTo(20,-80); context.lineTo(10,-80); context.lineTo(25,-50); context.closePath() ;
以上 js 代码可以绘制出一个松树的树冠。
4.描边样式
//设置使用描边样式 //加宽线条 context.lineWidth=4; //平滑路径接合点 context.lineJoin = 'round'; //将颜色改成棕色 context.strokeStyle='#663300'; //最后绘制树冠 context.stroke();
5.填充样式
//填充树颜色为绿色 context.fillStyle="#339900"; context.fill();
6.填充矩形区域
//将填充色设为棕色 context.fillStyle=’#663300’; //填充用作树干的矩形区域 context.fillRect(-5,-50,10,50);
7.绘制曲线
context.save(); context.translate(-10,350); context.beginPath(); //第一条曲线向右上方弯曲 context.moveTo(0,0); context.quadraticCurveTo(170,-50,260,-190); //第二条曲线向右下方弯曲 context.quadraticCurveTo(310,-250,410,-250); //使用棕色的粗线条来挥之路径 context.strokeStyle="#663300"; context.lineWidth=20; context.stroke(); context.restore();
8.在 canvas 中插入图片
//保证图片加载完才调用 var Bark = new Image(); Bark.src=”bark.jpg”; Bark.onload = function(){ drawTrails(); }
在 canvas 中显示图像
context.drawImage(Bark,-5,-50,10,50);
9.渐变
步骤:
① 创建渐变对象
② 为渐变对象设置颜色,指明过度方式
③ 在 context 上为填充样式或者描边样式设置渐变
var trunkGradient = context.createLinearGradient(-5,-50,5,-50); trunkGradient.addColorStop(0,'#663300'); trunkGradient.addColorStop(0.4,'#996600'); trunkGradient.addColorStop(1,'#552200'); context.fillStyle=trunkGradient; context.fillRect(-5,-50,10,50); //接下来,创建垂直渐变,以用作树冠在树干上的投影 var canopyShadow = context.createLinearGradient(0,-50,0,0); canopyShadow.addColorStop(0,'rgba(0,0,0,0.5)'); //方向垂直向下,渐变色在很短的距离内迅速渐变为完全透明,这段长度之外的树干上没有投影 canopyShadow.addColorStop(0.2,'rgba(0,0,0,0.0)'); //在树干上填充投影渐变 context.fillStyle=canopyShadow; context.fillRect(-5,-50,10,50);
10.背景图
使用 createPattern 函数替代之前的 drawImage 函数
var Bark = new Image(); Bark.src=”bark.jpg”; Bark.onload = function(){ drawTrails(); } //用背景图替代棕色的粗线条 context.strokeStyle = context.createPattern(Bark,’repeat’); context.lineWidth=20; Context.stroke();
11.缩放 canvas 对象
//在(130,250)的位置绘制第一棵树 context.save(); context.translate(130,250); drawTree(context); context.restore(); //在(260,500)的位置绘制第二棵树 context.save(); context.translate(260,500); //将第二棵树的宽高分别放大至原来的2倍 context.scale(2,2); drawTree(context); context.restore();
12.Canvas 变换
context.save(); //X值随着Y值的增加而增加,借助拉伸变换,可以创建一颗用作阴影的倾斜的数,应用了变换以后,所有坐标都与矩阵相乘 context.transform(1,0,-0.5,1,0,0); //在Y轴方向,将阴影的高度压缩为原来的60% context.scale(1,0.6); //使用透明度为20%的黑色填充树干 context.fillStyle='rgba(0,0,0,0.2)'; context.fillRect(-5,-50,10,50); //使用已有的阴影效果重新绘制树 createCanopyPath(context); context.fill(); context.restore();
运用上面的所有变换后的图形:
13.canvas 文本
Context 对象的文本绘制功能由两个函数组成:
Maxwidth 是可选的,用于限制字体的大小,它将文字强制收缩到指定尺寸。
//在canvas上绘制标题文本 context.save(); context.font='60px impact'; //将文本填充为棕色 context.fillStyle='#996600'; //将文本设为居中对齐 context.textAlign='center'; //在canvas顶部中央的位置以大字体的样式显示文本 context.fillText('Merry Christmas!',200,60,400); context.restore();
最后显示如下,是不是很欢快的感觉,绘制的还是很不错的。
14.应用阴影
//设置文字阴影的颜色为黑色,透明度为20% context.shadowColor ='rgba(0,0,0,0.2)'; //将阴影向右移动15px,向上移动10px context.shadowOffsetX=15; context.shadowOffsetY = -10; //轻微模糊阴影 context.shadowBlur=2;
最终效果图:
JS:
window.addEventListener("load",drawTrails,true); //绘制松树树冠 function createCanopyPath(context){ context.beginPath(); context.moveTo(-25,-50); context.lineTo(-10,-80); context.lineTo(-20,-80); context.lineTo(-5,-110); context.lineTo(-15,-110); context.lineTo(0,-140); context.lineTo(15,-110); context.lineTo(5,-110); context.lineTo(20,-80); context.lineTo(10,-80); context.lineTo(25,-50); context.closePath() ; } function drawTrails(){ var canvas = document.getElementById("diagonal"); var context = canvas.getContext("2d"); //在(130,250)的位置绘制第一棵树 context.save(); context.translate(130,250); drawTree(context); context.restore(); context.save(); context.translate(-10,350); context.beginPath(); //第一条曲线向右上方弯曲 context.moveTo(0,0); context.quadraticCurveTo(170,-50,260,-190); //第二条曲线向右下方弯曲 context.quadraticCurveTo(310,-250,410,-250); //使用棕色的粗线条来挥之路径 context.strokeStyle="#663300"; context.lineWidth=20; context.stroke(); context.restore(); //在(260,500)的位置绘制第二棵树 context.save(); context.translate(260,500); //将第二棵树的宽高分别放大至原来的2倍 context.scale(2,2); drawTree(context); context.restore(); //在canvas上绘制标题文本 context.save(); context.font='60px impact'; //将文本填充为棕色 context.fillStyle='#996600'; //将文本设为居中对齐 context.textAlign='center'; //在canvas顶部中央的位置以大字体的样式显示文本 //设置文字阴影的颜色为黑色,透明度为20% context.shadowColor ='rgba(0,0,0,0.2)'; //将阴影向右移动15px,向上移动10px context.shadowOffsetX=15; context.shadowOffsetY = -10; //轻微模糊阴影 context.shadowBlur=2; context.fillText('Merry Christmas!',200,60,400); context.restore(); } function drawTree(context){ context.save(); var trunkGradient = context.createLinearGradient(-5,-50,5,-50); trunkGradient.addColorStop(0,'#663300'); trunkGradient.addColorStop(0.4,'#996600'); trunkGradient.addColorStop(1,'#552200'); context.fillStyle=trunkGradient; context.fillRect(-5,-50,10,50); //接下来,创建垂直渐变,以用作树冠在树干上的投影 var canopyShadow = context.createLinearGradient(0,-50,0,0); canopyShadow.addColorStop(0,'rgba(0,0,0,0.5)'); //方向垂直向下,渐变色在很短的距离内迅速渐变为完全透明,这段长度之外的树干上没有投影 canopyShadow.addColorStop(0.2,'rgba(0,0,0,0.0)'); //在树干上填充投影渐变 context.fillStyle=canopyShadow; context.fillRect(-5,-50,10,50); createCanopyPath(context); context.restore() ; context.save(); //设置使用描边样式 context.lineWidth=4; context.lineJoin = 'round'; context.strokeStyle='#663300'; context.stroke(); //填充数颜色 context.fillStyle="#339900"; context.fill(); context.restore(); context.save(); //X值随着Y值的增加而增加,借助拉伸变换,可以创建一颗用作阴影的倾斜的数,应用了变换以后,所有坐标都与矩阵相乘 context.transform(1,0,-0.5,1,0,0); //在Y轴方向,将阴影的高度压缩为原来的60% context.scale(1,0.6); //使用透明度为20%的黑色填充树干 context.fillStyle='rgba(0,0,0,0.2)'; context.fillRect(-5,-50,10,50); //使用已有的阴影效果重新绘制树 createCanopyPath(context); context.fill(); context.restore(); }
HTML:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>canvas</title> <script type="text/javascript" src="../js/canvas/canvas1.js"></script> </head> <body> <canvas id="diagonal" width="410" height="510" style="border:1px solid;"> update your browser to support canvas </canvas> </body> </html>