canvas 学习
检测浏览器是否支持canvas
var canvas = document.getElementById('tutorial'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); // drawing code here } else { // canvas-unsupported code here }
三个函数用于绘制矩形的:
fillRect(x,y,width,height)
: Draws a filled rectangle 矩形strokeRect(x,y,width,height)
: Draws a rectangular outline 矩形轮廓clearRect(x,y,width,height)
: Clears the specified area and makes it fully transparent 清除指定区域,并使其完全透明的
function draw(){
var canvas = document.getElementById('tutorial');
if (canvas.getContext){
var ctx = canvas.getContext('2d');
ctx.fillRect(25,25,100,100); //fillRect
函数画了一个大的黑色矩形(100x100)
ctx.clearRect(45,45,60,60);//clearRect
函数清空了中间 60x60 大小的方块
ctx.strokeRect(50,50,50,50);//后strokeRect
函数又在清空了的空间内勾勒出一个 50x50 的矩形边框
} }
绘制路径:
beginPath()
closePath()
stroke()
fill()
第一步是用beginPath
创建一个路径。在内存里,路径是以一组子路径(直线,弧线等)的形式储存的,它们共同构成一个图形。每次调用beginPath
,子路径组都会被重置,然后可以绘制新的图形。
第二步就是实际绘制路径的部分
第三步是调用 closePath
方法,它会尝试用直线连接当前端点与起始端点来关闭路径,但如果图形已经关闭或者只有一个点,它会什么都不做。这一步不是必须的。
最后一步是调用stroke
或fill 方法,这时,图形才是实际的绘制到 canvas
上去。stroke
是绘制图形的边框,fill
会用填充出一个实心图形
moveTo
moveTo
是一个十分有用的方法,虽然并不能用它来画什么,但却是绘制路径的实用方法的一部分。你可以把它想象成是把笔提起,并从一个点移动到另一个点的过程。
lineTo
方法接受终点的坐标(x,y)作为参数。起始坐标取决于前一路径,前一路径的终点即当前路径的起点,起始坐标也可以通过 moveTo
方法来设置。 arc
方法来绘制弧线或圆startAngle
和 endAngle
分别是起末弧度(以 x 轴为基准),anticlockwise
为 true 表示逆时针,反之顺时针。注意:arc
方法里用到的角度是以弧度为单位而不是度。度和弧度直接的转换可以用这个表达式:var radians = (Math.PI/180)*degrees;
贝塞尔和二次方曲线
quadraticCurveTo(cp1x, cp1y, x, y) // BROKEN in Firefox 1.5 (see work around below)
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
参数 x
和 y
是终点坐标,cp1x
和 cp1y 是第一个控制点的坐标,
cp2x
和 cp2y
是第二个的。drawImage
drawImage(image, x, y) 其中 image
是 image 或者 canvas 对象,x
和 y 是其在目标 canvas 里的起始坐标
drawImage(image, x, y, width, height) drawImage
方法的又一变种是增加了两个用于控制图像在 canvas 中缩放的参数。
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) drawImage
方法的第三个也是最后一个变种有8个新参数,用于控制做切片显示的
前4个是定义图像源的切片位置和大小,后4个则是定义切片的目标显示位置和大小
https://developer.mozilla.org/samples/canvas-tutorial/3_3_canvas_drawimage.html
https://developer.mozilla.org/samples/canvas-tutorial/3_4_canvas_gallery.html
要给图形上色,有两个重要的属性可以做到:fillStyle
和 strokeStyle
strokeStyle
是用于设置图形轮廓的颜色,而 fillStyle
用于设置填充颜色。color
可以是表示 CSS 颜色值的字符串,渐变对象或者图案对象。我们迟些再回头探讨渐变和图案对象。默认情况下,线条和填充颜色都是黑色(CSS 颜色值 #000000)。
function draw() { var ctx = document.getElementById('canvas').getContext('2d'); for (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); } } }
function draw() { var ctx = document.getElementById('canvas').getContext('2d'); for (i=0;i<6;i++){ for (j=0;j<6;j++){ ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' + Math.floor(255-42.5*j) + ')'; ctx.beginPath(); ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true); ctx.stroke(); } } }
通过设置 globalAlpha
属性或者使用一个半透明颜色作为轮廓或填充的样式
save
和 restore
方法是用来保存和恢复 canvas 状态的,都没有参数。Canvas 的状态就是当前画面应用的所有样式和变形的一个快照。
translate
方法,它用来移动 canvas 和它的原点到一个不同的位置 translate
方法接受两个参数。x 是左右偏移量,y 是上下偏移量
function draw() { var ctx = document.getElementById('canvas').getContext('2d'); ctx.fillRect(0,0,300,300); for (i=0;i<3;i++) { for (j=0;j<3;j++) { ctx.save(); ctx.strokeStyle = "#9CFF00"; ctx.translate(50+j*100,50+i*100); drawSpirograph(ctx,20*(j+2)/(j+1),-8*(i+3)/(i+1),10); ctx.restore(); } } } function drawSpirograph(ctx,R,r,O){ var x1 = R-O; var y1 = 0; var i = 1; ctx.beginPath(); ctx.moveTo(x1,y1); do { if (i>20000) break; var x2 = (R+r)*Math.cos(i*Math.PI/72) - (r+O)*Math.cos(((R+r)/r)*(i*Math.PI/72)) var y2 = (R+r)*Math.sin(i*Math.PI/72) - (r+O)*Math.sin(((R+r)/r)*(i*Math.PI/72)) ctx.lineTo(x2,y2); x1 = x2; y1 = y2; i++; } while (x2 != R-O && y2 != 0 ); ctx.stroke(); }
它用于以原点为中心旋转 canvas rotate(angle)
function draw() { var ctx = document.getElementById('canvas').getContext('2d'); ctx.translate(75,75); for (i=1;i<6;i++){ ctx.save(); ctx.fillStyle = 'rgb('+(51*i)+','+(255-51*i)+',255)'; for (j=0;j<i*6;j++){ ctx.rotate(Math.PI*2/(i*6)); ctx.beginPath(); ctx.arc(0,i*12.5,5,0,Math.PI*2,true); ctx.fill(); } ctx.restore(); } }
我们用它来增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大。scale(x, y)
ale
方法接受两个参数。x,y 分别是横轴和纵轴的缩放因子,它们都必须是正值。值比 1.0 小表示缩小,比 1.0 大则表示放大,值为 1.0 时什么效果都没有
function draw() { var ctx = document.getElementById('canvas').getContext('2d'); ctx.strokeStyle = "#fc0"; ctx.lineWidth = 1.5; ctx.fillRect(0,0,300,300); // Uniform scaling ctx.save() ctx.translate(50,50); drawSpirograph(ctx,22,6,5); ctx.translate(100,0); ctx.scale(0.75,0.75); drawSpirograph(ctx,22,6,5); ctx.translate(133.333,0); ctx.scale(0.75,0.75); drawSpirograph(ctx,22,6,5); ctx.restore(); // Non uniform scaling (y direction) ctx.strokeStyle = "#0cf"; ctx.save() ctx.translate(50,150); ctx.scale(1,0.75); drawSpirograph(ctx,22,6,5); ctx.translate(100,0); ctx.scale(1,0.75); drawSpirograph(ctx,22,6,5); ctx.translate(100,0); ctx.scale(1,0.75); drawSpirograph(ctx,22,6,5); ctx.restore(); // Non uniform scaling (x direction) ctx.strokeStyle = "#cf0"; ctx.save() ctx.translate(50,250); ctx.scale(0.75,1); drawSpirograph(ctx,22,6,5); ctx.translate(133.333,0); ctx.scale(0.75,1); drawSpirograph(ctx,22,6,5); ctx.translate(177.777,0); ctx.scale(0.75,1); drawSpirograph(ctx,22,6,5); ctx.restore(); } function drawSpirograph(ctx,R,r,O){ var x1 = R-O; var y1 = 0; var i = 1; ctx.beginPath(); ctx.moveTo(x1,y1); do { if (i>20000) break; var x2 = (R+r)*Math.cos(i*Math.PI/72) - (r+O)*Math.cos(((R+r)/r)*(i*Math.PI/72)) var y2 = (R+r)*Math.sin(i*Math.PI/72) - (r+O)*Math.sin(((R+r)/r)*(i*Math.PI/72)) ctx.lineTo(x2,y2); x1 = x2; y1 = y2; i++; } while (x2 != R-O && y2 != 0 ); ctx.stroke(); } transform(m11, m12, m21, m22, dx, dy)