高程3总结#第15章使用Canvas绘图

使用Canvas绘图

基本用法

  • 要使用<canvas>元素,必须先设置其width和height属性,指定可以绘图的区域大小。出现在开始和结束标签中的内容是后备信息,如果浏览器不支持<canvas>元素,就会显示这些信息

    <canvas id="drawing" width="200" height="200">A drawing of something</canvas>
  • 要在这块画布上绘图,需要取得绘图上下文,而取得绘图上下文对象的引用,需要调用getContext()方法并传入上下文的名字,传入"2d",就可以取得2D上下文的对象

    var drawing=document.getElementById("drawing");
    //确定浏览器支持<canvas>元素
    if(drawing.getContext){
      var context=drawing.getContext("2d");
      //更多代码
    }
  • 在使用<canvas>元素之前,首先要检测getContext()方法是否存在

    var drawing=document.getElementById("drawing");
    //确定浏览器支持<canvas>元素
    if(drawing.getContext){
      //取得图像的数据URI
      var imgURI=drawing.toDataURL("image/png");
      //显示图像
      var image=document.createElement("img");
      image.src=imgURI;
      document.body.appendChild(image);
    }

2D上下文

  • 2D上下文的坐标开始于<canvas>元素的左上角,原点坐标是(0,0)。所有坐标的值都基于这个原点计算,x值越大表示越靠右,y值越大表示越靠下。默认情况下,width和height表示水平和垂直两个方向上可用的像素数目

填充和描边

  • 操作得结果取决于两个属性,fillStyle和strokeStyle
  • 这两个属性的值可以是字符串,渐变对象或模拟对象,而且它们的默认值都是"#000000"

    var drawing=document.getElementById("drawing");
    //确定浏览器支持<canvas>元素
    if(drawing.getContext){
      var content=drawing.getContext("2d");
      context.strokeStyle="red";
      context.fillStyle="#0000ff"
    }

绘制矩形

  • 与矩形相关的方法包括fillRect()、strokeRect()、clearRect()三个方法接收4个参数,矩形的x坐标、矩形的y坐标、矩形的宽度和矩形的高度。这些参数的单位都是像素

    • fillRect()方法在画布上绘制的矩形会填充指定的颜色

      var drawing = document.getElementById("drawing");
      //确定浏览器支持<canvas>元素
      if (drawing.getContext){
        var context = drawing.getContext("2d");
        // 绘制红色矩形
        context.fillStyle = "#ff0000";
        context.fillRect(10, 10, 50, 50);
        // 绘制半透明的蓝色矩形
        context.fillStyle = "rgba(0,0,255,0.5)";
        context.fillRect(30, 30, 50, 50);
      }
    • strokeRect()方法在画布上绘制的矩形会使用指定的颜色描边,描边颜色通过strokeStyle属性指定

      var drawing=document.getElementById("drawing");
      //确定浏览器支持<canvas>元素
      if(drawing.getContext){
        var context=drawing.getContext("2d");
        //绘制红色描边矩形
        context.strokeStyle="#ff0000";
        context.strokeRect(10,10,50,50);
        //绘制半透明的蓝色描边矩形
        context.strokeStyle="rgba(0,0,255,0.5)";
        context.strokeRect(30,30,50,50)
      }
    • clearRect()方法用于清除画布上的矩形区域,本质上,这个方法可以把绘制上下文中的某一矩形区域变透明

      var drawing = document.getElementById("drawing");
      //确定浏览器支持<canvas>元素
      if (drawing.getContext){
        var context = drawing.getContext("2d");
        //绘制红色矩形
        context.fillStyle = "#ff0000";
        context.fillRect(10, 10, 50, 50);
        //绘制半透明的蓝色矩形
        context.fillStyle = "rgba(0,0,255,0.5)";
        context.fillRect(30, 30, 50, 50);
        // 在两个矩形重叠的地方清除一个小矩形
        context.clearRect(40, 40, 10, 10);
      }

绘制路径

  • 要绘制路径,首先必须调用beginPath()方法,表示要开始绘制的新路径

    • arc(x, y, radius, startAngle, endAngle, counterclockwise),以 (x,y) 为圆心绘制一条弧线,弧线半径为 radius ,起始和结束角度(用弧度表示)分别为 startAngle 和endAngle 。最后一个参数表示 startAngle 和 endAngle 是否按逆时针方向计算,值为 false表示按顺时针方向计算。
    • arcTo(x1, y1, x2, y2, radius),从上一点开始绘制一条弧线,到 (x2,y2) 为止,并且以给定的半径 radius 穿过 (x1,y1) 。
    • bezierCurveTo(c1x, c1y, c2x, c2y, x, y),从上一点开始绘制一条曲线,到 (x,y) 为止,并且以 (c1x,c1y) 和 (c2x,c2y) 为控制点。
    • lineTo(x, y),从上一点开始绘制一条直线,到 (x,y) 为止。
    • moveTo(x, y),将绘图游标移动到 (x,y) ,不画线。
    • quadraticCurveTo(cx, cy, x, y),从上一点开始绘制一条二次曲线,到 (x,y) 为止,并且以 (cx,cy) 作为控制点。
    • rect(x, y, width, height),从点 (x,y) 开始绘制一个矩形,宽度和高度分别由 width 和height 指定。这个方法绘制的是矩形路径,而不是 strokeRect() 和 fillRect() 所绘制的独立的形状。
    var drawing = document.getElementById("drawing");
    //确定浏览器支持<canvas>元素
    if (drawing.getContext){
      var context = drawing.getContext("2d");
      // 开始路径
      context.beginPath();
      // 绘制外圆
      context.arc(100, 100, 99, 0, 2 * Math.PI, false);
      // 绘制内圆
      context.moveTo(194, 100);
      context.arc(100, 100, 94, 0, 2 * Math.PI, false);
      // 绘制分针
      context.moveTo(100, 100);
      context.lineTo(100, 15);
      // 绘制时针
      context.moveTo(100, 100);
      context.lineTo(35, 100);
      // 描边路径
      context.stroke();
    }

绘制文本

  • 绘制文本主要两个方法:fillText()和strokeText()。这两个方法都可以接收4个参数:要绘制的文本字符串、x坐标、y坐标和可选的最大像素宽度
  • 这两个方法以3个属性为基础

    • font,表示文本样式、大小及字体,用 CSS 中指定字体的格式来指定,例如 "10px Arial" 。
    • textAlign,表示文本对齐方式。可能的值有 "start" 、 "end" 、 "left" 、 "right" 和 "center" 。建议使用 "start" 和 "end" ,不要使用 "left" 和 "right" ,因为前两者的意思更稳妥,能同时适合从左到右和从右到左显示(阅读)的语言。
    • textBaseline,表示文本的基线。可能的值有 "top" 、 "hanging" 、 "middle" 、 "alphabetic" 、"ideographic" 和 "bottom" 。
    //正常
    context.font = "bold 14px Arial";
    context.textAlign = "center";
    context.textBaseline = "middle";
    context.fillText("12", 100, 20);
    // 起点对齐
    context.textAlign = "start";
    context.fi llText("12", 100, 40);
    // 终点对齐
    context.textAlign = "end";
    context.fi llText("12", 100, 60);

变换

  • 修改变换矩阵

    • rotate(angle),围绕原点旋转图像 angle 弧度。
    • scale(scaleX, scaleY),缩放图像,在 x 方向乘以 scaleX ,在 y 方向乘以 scaleY 。 scaleX和 scaleY 的默认值都是 1.0。
    • translate(x, y),将坐标原点移动到 (x,y) 。执行这个变换之后,坐标(0,0)会变成之前由 (x,y)表示的点。
    • transform(m1_1, m1_2, m2_1, m2_2, dx, dy),直接修改变换矩阵,方式是乘以如下矩阵。
      m1_1 m1_2 dx
      m2_1 m2_2 dy
      0 0 1
    • setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy),将变换矩阵重置为默认状态,然后再调用 transform()
    var drawing = document.getElementById("drawing");
    //确定浏览器支持<canvas>元素
    if (drawing.getContext){
      var context = drawing.getContext("2d");
      //开始路径
      context.beginPath();
      //绘制外圆
      context.arc(100, 100, 99, 0, 2 * Math.PI, false);
      //绘制内圆
      context.moveTo(194, 100);
      context.arc(100, 100, 94, 0, 2 * Math.PI, false);
      //变换原点
      context.translate(100, 100);
      // 旋转表针
      context.rotate(1);
      //绘制分针
      context.moveTo(0,0);
      context.lineTo(0, -85);
      //绘制时针
      context.moveTo(0, 0);
      context.lineTo(-65, 0);
      //描边路径
      context.stroke();
    }

绘制图像

  • 使用drawImage()将图像绘制到画布上,三种不同的参数组合

    • 3个参数:传入HTML<img>元素,绘制图像的起点的x和y坐标
    • 5个参数:3个参数+目标宽度和目标高度
    • 9个参数:要绘制的图像,源图像的x坐标,源图像的y坐标,源图像的宽度,源图像的高度,目标图像的x坐标,目标图像的y坐标,目标图像的宽度,目标图像的高度

阴影

  • 2D上下文根据属性值自动绘制阴影

    • shadowColor,用 CSS 颜色格式表示的阴影颜色,默认为黑色。
    • shadowOffsetX,形状或路径 x 轴方向的阴影偏移量,默认为 0。
    • shadowOffsetY,形状或路径 y 轴方向的阴影偏移量,默认为 0。
    • shadowBlur,模糊的像素数,默认 0,即不模糊。
    var context = drawing.getContext("2d");
    // 设置阴影
    context.shadowOffsetX = 5;
    context.shadowOffsetY = 5;
    context.shadowBlur = 4;
    context.shadowColor = "rgba(0, 0, 0, 0.5)";
    //绘制红色矩形
    context.fillStyle = "#ff0000";
    context.fillRect(10, 10, 50, 50);
    //绘制蓝色矩形
    context.fillStyle = "rgba(0,0,255,1)";
    context.fillRect(30, 30, 50, 50);

渐变

  • 要创建一个新的线性渐变,可以调用createLinearGradient()方法,这个方法接收4个参数:起点的x坐标、起点的y坐标、终点的x坐标、终点的y坐标

    //绘制红色矩形
    context.fillStyle="#ff0000";
    context.fillRect(10,10,50,50);
    //绘制渐变矩形
    context.fillStyle=gradient;
    context.fillRect(30,30,50,50);

模式

var image=document.images[0],
  pattern=context.createPattern(image,"repeat");
//绘制矩形
context.fillStyle=pattern;
context.fillRect(10,10,150,150);

使用图像数据

  • getImageData()取得原始图像数据,这个方法接收4个参数:要取得其数据的画面区域的x和y坐标以及该区域的像素宽度和高度

    var drawing = document.getElementById("drawing");
    //确定浏览器支持<canvas>元素
    if (drawing.getContext){
      var context = drawing.getContext("2d"),
          image = document.images[0],
          imageData, data,
          i, len, average,
          red, green, blue, alpha;
      //绘制原始图像
      context.drawImage(image, 0, 0);
      //取得图像数据
      imageData = context.getImageData(0, 0, image.width, image.height);
      data = imageData.data;
      for (i=0, len=data.length; i < len; i+=4){
        red = data[i];
        green = data[i+1];
        blue = data[i+2];
        alpha = data[i+3];
        //求得 rgb 平均值
        average = Math.floor((red + green + blue) / 3);
        //设置颜色值,透明度不变
        data[i] = average;
        data[i+1] = average;
        data[i+2] = average;
      }
      //回写图像数据并显示结果
      imageData.data = data;
      context.putImageData(imageData, 0, 0);
    }

合成

  • 应用到2D上下文所有绘制操作得属性。globalAlpha和globalCompositionOperation

    • globalAlpha是一个介于0和1之间的值,用于指定所有绘制的透明度,默认值为0,如果所有后续操作都要基于相同的透明度,就可以先把globalAlpha设置为适当值,然后绘制,最后再把它设置回默认值0

      //绘制红色矩形
      context.fillStyle = "#ff0000";
      context.fillRect(10, 10, 50, 50);
      //修改全局透明度
      context.globalAlpha = 0.5;
      //绘制蓝色矩形
      context.fillStyle = "rgba(0,0,255,1)";
      context.fillRect(30, 30, 50, 50);
      //重置全局透明度
      context.globalAlpha = 0
    • globalCompositionOperation表示绘制的图形怎样与先绘制的图形结合,这个属性的值是字符串

      • source-over默认值,后绘制的图形位于先绘制的图形上方。
      • source-in,后绘制的图形与先绘制的图形重叠的部分可见,两者其他部分完全透明。
      • source-out,后绘制的图形与先绘制的图形不重叠的部分可见,先绘制的图形完全透明。
      • source-atop,后绘制的图形与先绘制的图形重叠的部分可见,先绘制图形不受影响。
      • destination-over,后绘制的图形位于先绘制的图形下方,只有之前透明像素下的部分才可见。
      • destination-in,后绘制的图形位于先绘制的图形下方,两者不重叠的部分完全透明。
      • destination-out,后绘制的图形擦除与先绘制的图形重叠的部分。
      • destination-atop,后绘制的图形位于先绘制的图形下方,在两者不重叠的地方,先绘制的图形会变透明。
      • lighter,后绘制的图形与先绘制的图形重叠部分的值相加,使该部分变亮。
      • copy,后绘制的图形完全替代与之重叠的先绘制图形。
      • xor,后绘制的图形与先绘制的图形重叠的部分执行“异或”操作。

WebGL

类型化数组

  • 类型化数组也是数组,只不过其元素被设置为特定类型的值
  • 类型化数组的核心就是一个名为ArrayBuffer的类型。

WebGL上下文

支持

  • Firefox 4+和 Chrome 都实现了 WebGL API。Safari 5.1 也实现了 WebGL,但默认是禁用的。

相关推荐