今天讲的例子比较多,可能篇幅长一些。从实用性看,前三个例子需要完全理解。后面的可以有兴趣再回头看,因为圆弧和曲线平时的设计当中不经常用到。
闲话少说,先来第一个例子:最基本的矩形
案例中涉及的函数
- fillRect(x, y, width, height):在(x, y)点上以width和height的长高来画全填充矩形。
- strokeRect(x, y, width, height):在(x, y)点上以width和height的长高来给矩形描边(只有边框,里面为空)。
- clearRectt(x, y, width, height):在(x, y)点上以width和height的长高清空内容,使他变为透明)
效果图:
直接贴上所有的代码,具体的编号请根据方法名称的最后一个字母索引值进行辨别。

/** * @author Administrator */ window.addEventListener("load", eventWindowLoaded, false); function eventWindowLoaded() { canvasApp(); } function canvasSupport() { // return !document.createElement('testcanvas').getContext; } function canvasApp() { var theCanvas = document.getElementById("canvas"); var context = theCanvas.getContext("2d"); //canvas中有很多不同的context,这里我们仅需要2D // if(!theCanvas || !theCanvas.getContext) { // return; // } function drawScreen1() { context.fillStyle = "#000000"; context.strokeStyle = "#ff00ff"; context.lineWidth = 2; context.fillRect(10, 10, 40, 40); context.strokeRect(0, 0, 60, 60); context.clearRect(20, 20, 20, 20); } function drawScreen2() { var ctx = document.getElementById('canvas').getContext('2d'); ctx.fillRect(0, 0, 150, 150); ctx.save(); //保存当前的context状态 例如当前的context1 ctx.fillStyle = '#3399FF' //新的context对象 当前为context2 ctx.fillRect(15, 15, 120, 120); ctx.save(); //保存当前的context状态 例如当前的context2 ctx.fillStyle = '#FFF'; //新的context对象 当前为context3 ctx.globalAlpha = 0.5; ctx.fillRect(30, 30, 90, 90); ctx.restore(); //恢复到context2状态,也就是说ctx.fillSyle恢复到 #3399FF ctx.fillRect(45, 45, 60, 60); ctx.restore(); //再进行恢复 恢复到context1状态,恢复到最开始的默认状态 ctx.fillRect(60, 60, 30, 30); } function drawScreen3() { context.strokeStyle = "black"; context.lineWidth = 10; //线的粗细 context.lineJoin = "bevel"; /** * lineCap:线的两端 * 1. butt:线的两端是平坦的 * 2. round:线的两端是半圆形 * 3. square:以线的宽度为长边,线的宽度的一半为短边的矩形 */ context.lineCap = "round"; context.beginPath(); context.moveTo(0, 0); context.lineTo(25, 0); context.lineTo(25, 25); /** * fill():实心 * stroke():描边 */ context.stroke(); context.closePath(); context.beginPath(); context.moveTo(10, 50); context.lineTo(35, 50); context.lineTo(35, 75); context.stroke(); context.closePath(); /** * lineJoin:线的连接处 * 1. miter:在连接处画出边缘(例如垂直) * 2. bevel:在连接处画出斜线 * 3. round:在连接处画出圆形 */ context.lineJoin = "round"; context.lineCap = "butt"; context.beginPath(); context.moveTo(10, 100); context.lineTo(35, 100); context.lineTo(35, 125); context.stroke(); context.closePath(); } function drawScreen4() { context.beginPath(); context.strokeStyle = "black"; context.lineWidth = 5; /** * context.arc(x, y, radius, startAngle, endAngle, anticlockwise) * 画圆弧,可以是整个弧,也可以是一部分 * @param: x 圆弧的中心坐标 * @param: y 圆弧的中心坐标 * @param: radius 圆弧的半径 * @param: startAngle 圆弧的起始角度 * @param: endAngle 圆弧的结束角度 * @param: anticlockwise 是否为《逆》时针方向 * * 其中角度是沿着x轴方向为0或360度,x轴的反向为180度 * y轴的反向为90度,y轴方向为270度 */ context.arc(100, 100, 20, (Math.PI / 180) * 90, (Math.PI / 180) * 180, false); context.stroke(); context.closePath(); } function drawScreen5() { context.beginPath(); context.lineWidth = 5; context.moveTo(0, 0); context.quadraticCurveTo(100, 25, 0, 50); context.moveTo(250, 0); context.bezierCurveTo(0, 125, 300, 175, 150, 300); context.stroke(); context.closePath(); } drawScreen5(); }
drawScreen1()方法当中前面几行应该都没啥问题,最后一行因为它清空了(20, 20, 20, 20)的区域,因此中间会显示白色的区域。
它是网页的背景颜色,用户可以调整<body>的背景颜色,进行检查。
Canvas状态
当我们使用canvas context进行画画的时候,我们可以使用画画状态的一组栈。栈中保存着任何时候的Canvas context的信息(例如画笔颜色)。
这里将列举一些栈当中保存的数据。
- 矩阵的变化(旋转,移动)
- 裁剪的区域
- canvas的一些属性(例如fillStyle, strokeStyle, textAlign, globalAlpha等等)
但是当前的路径(path)及在canvas当中操作的bitmap对象不会包含在状态当中。
状态的保存及恢复
- context.save();
- context.restore();
笔者找了一个很好的例子,练习context的保存及恢复。
效果图如下:
如果能完全的理解这个例子,那基本的保存状态及恢复应该没什么问题,因代码旁边都有注释就不说明了。
使用Path画线条
因代码有注释,不介绍了。但大家思考一下第一个图形,为什么上边的横线为细的。
圆弧
方法名称:context.arc(x, y, radius, startAngle, endAngle, anticlockwises)
在这里唯一需要注意的是,开始的角度及,结束的角度。并且第五个参数是《是否为逆时针》,别惯性思维想成true为顺时针。
还有一个画圆弧的方法context.arcTo(),但很多浏览器不支持该方法,并且跟context.arc()方法有些重叠,这里不介绍了。
贝塞尔曲线
- context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y):这个有点复杂,有兴趣的自行了解。笔者虽然查看文档研究了一阵子,但实在不知道什么时候能用到。
- context.quadraticCurveTo(cpx, cpy, x, y):就是所谓的双曲线
这次的到此结束了,有任何问题或建议希望给我留言,谢谢。