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(x, y, radius, startAngle, endAngle, anticlockwise)
我们用 arc 方法来绘制弧线或圆
方法接受五个参数:x,y 是圆心坐标,radius 是半径,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 方法接受两个参数。是左右偏移量,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)


posted @ 2012-01-05 21:02  风去无痕  阅读(347)  评论(0编辑  收藏  举报