zoukankan      html  css  js  c++  java
  • canvas画图

    一,基本用法
    1,使用前给canvas设定高度和宽度,出现在标签中的内容在浏览器不支持canvas时使用
      <canvas id="drawing" width="200",height="200">A drawing of something</canvas>
    2,getContext("2d");取得绘图上下文的引用

      var drawing = document.getElementById("drawing");
          if(drawing.getContext){
            var context = drawing.getContext("2d");
          }

    3,使用toDataURL()方法,可以导出canvas元素上绘制的图像,接收一个MIME类型格式

      var drawing = document.getElementById("drawing");
      if(drawing.getContext){
        var context = drawing.getContext("2d");
        var imgURL = drawing.toDataURL("image/png");
        var image = document.createElement("img");
        image.src=imgURL;
        document.body.appendChild(image);
      }

    二,2D上下文
    1,填充和描边
      填充是用指定的样式(颜色,渐变或图像)填充图形  
      描边只在图形的边缘画线,
      使用fillStyle,strokeStyle两个属性
    2,绘制矩形
      fillRect(),strokeRect(),clearRect(),接收四个参数,矩形的x坐标,y坐标,矩形宽度和矩形高度

      var drawing = document.getElementById("drawing");
      if(drawing.getContext){
        var context = drawing.getContext("2d");
        context.fillStyle = "#0000ff";
        context.fillRect(10,10,40,50);
        context.fillStyle = "rgba(0,0,255,0.5)";
        context.fillRect(30,30,50,50);
        context.strokeStyle = "red";
        context.StrokeRect(30,30,80,80);
      }

      lineWidth属性指定线条的宽度,
      lineCap属性指定线条末端的形状,平头(butt),圆头(round),方头(square)
      lineJoin属性指定线条相交的方式,圆交(round),斜交(bevel),斜接(miter)
      clearRect()用于清除一个矩形,把上下文的某一矩形表透明
    3,绘制路径
      beginPath(),开始路径,closePath(),闭合路径(将终点和起点闭合)
      arc(x,y,radius,startAngle,endAngle,counterclockwise)
      arcTo(x1,y1,x2,y2,radius):从上一点开始到(x2,y2)的一条弧线,给定的半径穿过(x1,y1)
      bezierCurveTo(c1x,c1y,c2x,c2y,x,y):从上一点开始到(x,y)的弧线,(x1,y1)(x2,y2)为控制点
      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)绘制矩形,
      路径完成,使用filleStyle属性设置填充样式,使用fill()方法实现填充
      使用strokeStyle属性设置描边样式,使用stroke()方法,对路径描边
      使用clip(),在路径上创建一个剪切区域

      var drawing = document.getElementById("drawing");
      if(drawing.getContext){
        var context = doawing.getContext;
        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();
      }

      isPointInPath(x,y)方法,用于判断路径被闭合之前,(x,y)是否位于路径上
      if(context.isPointInPath(100,100)){alert("Yes");}
    4,绘制文本
      fillText(),strokeText(),接收四个参数,绘制的文本字符串,x坐标,y坐标,可选的最大像素宽度
      font属性:表示文本样式,大小,字体
      textAlign属性:文本对齐方式,有start,end,left,right,和center
      textBaseline属性:文本的基线,top,hanging,middle,alphabetic,ideographic,bottom
      使用fillStyle属性绘制文本,使用fillText()方法实现
      measureText(),接收一个参数,要绘制的文本,返回一个对象,仅有一个width属性,用来确定文本大小的方法
      var fontSize = 100;
      context.font = fontSize + "px Arial";
      while(context.measureText("Hello world").width > 140){
        fontSize --;
      context.font = fontSize + "px Arial";
      }
      context.fillText("hello world",10,10);
      context.fillText("Font size is" + fontSize + "px",10,50);
    5,变换
      rotate(angle):围绕原点旋转图像angle弧度
      scale(scaleX,scaleY):缩放图像,x方向乘以scaleX,y方向上乘以scaleY
      translate(x,y):将坐标原点移动到(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):将变换矩阵重置为默认状态,然后调用transform()
      save(),方法保存某组属性与变换,后面可能还会用到,只保存上下文的设置和变换,不会保存内容
      restore(),在保存设置的栈结构中向前返回一级
      连续设置save(),可以把更多的设置保存在栈结构中,restore(),可以一级一级的返回
    6,绘制图像
      drawImage(要绘制的图像,源图像的x坐标,源图像的y坐标,源图像的宽度,源图像的高度,目标图像的x坐标,目标图像的y坐标,目标图像的宽度,目标   图像的高度);
      image为从html<img>元素获取
      操作结果通过toDataURL()方法获取
    7,阴影
      shadowColor属性:用css样式表示阴影颜色,默认为黑色
      shadowOffsetX属性:形状或路径x轴方向的阴影偏移量
      shadowOffsetY属性:形状或路径y轴方向的引用偏移量
      shadowBlur属性:模糊的像素数
    8,渐变
      渐变有canvasGradient实例表示
      线性渐变,createLinearGradient(起点x坐标,起点y坐标,终点x坐标,终点y坐标)
      使用addColorStop(色标位置,CSS颜色值)方法来指定色标
      var gradient = context.createLinearGradient(30,30,70,70);
      gradient.addColor(0,"white");
      gradient.addColor(1,"black");
      context.fillStyle = gradient;
      context.fillRect(30,30,50,50);
      图形坐标要和渐变对象坐标对应效果才明显
      function createRectLinearGradient(context,x,y,width,height){
        return context.createLinearGradient(x,y,x+width,y+height);
      }
      径向渐变,createRadialGradient(x1,y1,radius1,x2,y2,radius2)
      一般设置同心圆情况较多,此时只要考虑两个圆设置不同的半径就好
    9,模式
      createPattern(HTML<img>元素,表示如何重复图像的字符串)
      第二个参数可以为 repeat,repeat-x,repeat-y,no-repeat
      var image = document.images[0];
      pattern = context.createPattern(image,"repeat");
      context.fillStyle = pattern;
      context.fillRect(10,10,150,150);
      只表示在画布中的从(10,10)到(150,150)区域显示重复的图片
      第一个参数也可以是video元素,或者另一个canvas元素
    10,使用图像数据
      getImageData(要取得其数据的画面区域的x和y坐标,该区域的像素宽度和高度),
      返回一个imageData的实例,每个imageData对象有三个属性,width,height,data
      data属性是一个数组,保存着图像中每个像素的数据,data数组中,每个像素用四个元素来保存,表示红,绿,蓝,透明度
      第一个像素的数据就保存在数组的第0到第3个元素中
      var data = imageData.data,red=data[0],green=data[1],blue=data[2],alpha=fata[3];
      一个简单的灰阶过滤器

    var drawing = document.getElementById("drawing");
    if(drawing.getContext){
      var context = drawing.getContext;
      var image = document.images[0];
      var imageData,data,i,len,average,re,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=i+4){
        red = data[i];
        green = data[i+1];
        blue = data[i+2];
        alpha = data[i+3];
        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)
    }

      putImageData()方法是把图像数据绘制到画布上
    11,合成
      globalAlpha属性:介于0-1的值,指定所有绘制的透明度,全局透明度,设置后要设置为默认透明度为0
      globalCompositionOperation属性:表示后绘制的图像怎样与先绘制的图形结合,属性值如下
      source-over:后绘制的图像位于先绘制的图形上面
      source-in:后绘制的图形和先绘制的图形重叠部分可见,两者其余部分完全透明
      source-out:后绘制的图形和先绘制的图形不重叠部分可见,先绘制的图形完全透明
      source-atop:后绘制的图形和先绘制的图形重叠部分可见,先绘制的图形不受影响
      destination-over:后绘制的图形位于先绘制的图形下方,只有之前透明像素下的部分可见
      destination-in:后绘制的图形位于先绘制的图形下方,两者不重叠部分完全透明
      destination-out:后绘制的图形擦除与先绘制的图形重叠部分
      destination-atop:后绘制的图形位于先绘制的图形下方,不重叠不部分,先绘制的图形会变透明
      lighter:后绘制的图形与先绘制的图形重叠部分的值相加,该部分变亮
      copy:后绘制的图形完全替代与之重叠的先绘制的图形
      xor:后绘制的图形与先绘制的图形重叠部分执行异或操作
    三,WebGL
    1,类型化数组
      类型化数组的核心是一个名为ArrayBuffer的类型,每个ArrayBuffer对象表示的只是内存中指定的字节数,不会指定这些字节用于保存什么类型的数据
      var buffer = new ArrayBuffer(20);
      var bytes = buffer.byteLength;
      1)视图
      使用ArrayBuffer的一种特别的方式就是来创建数组缓冲器视图,创建视图DataView实例的时候传人ArrayBuffer,可选的字节偏移量,可选的要选择的字节数
      var buffer = new ArrayBuffer(20);
      var view = new DataView(buffer,9,15);
      实例化后,byteOffset保存字节偏移量,byteLength保存字节长度
      读取和写入DataView的时候,要根据实际操作的数据类型,选择相应的getter和setter方法
        有符号8位整数 getInt8(byteOffset) setInt8(byteOffset,value)
        无符号8位整数 getUint8(byteOffset) setUint8(byteOffset,value)
        有符号16位整数 getInt16(byteOffset) setInt16(byreOffset,value)
        无符号16位整数 getUint16(byteOffset) setUint16(byteOffset,value)
        有符号32位整数 getInt32(byteOffset) setInt32(byteOffset,value)
        无符号32位整数 getUitn32(byteOffset) setUint32(byteOffset,value)
        32位浮点数 getFloat32(byteOffset setFloat32(byteOffset,value)
        64位浮点数 getFloat64(byteOffset) setFloat64(byteOffset,value)
      读写16位或更大数值的方法都有一个可选的littleEndian属性,是一个布尔值,表示是否采用最小端字节序
      var buffer = new ArrayBuffer(20);
      var view = new DataView(buffer);
      view.setUint16(0,25); 以无符号16位写入25在0位置
      var value = view.getInt8(0); 以有符号8为读出0位置的值
      2)类型化视图
      类型化视图继承了DataView,
        Int8Array,Int16Array,Int32Array,表示8,16,32位二补整数
        Uint8Array,Uint16Array,Uint32Array,表示8,16,32位无符号整数
        Float32Array,Float64Array,表示32,64为IEEE浮点值
      var int8s = new Int8Array(buffer,9,10)
      同一个缓冲区保存不同类型的数值
      var int8s = new Int8Array(buffer,0,10);
      var int16s = new Int16Array(butter,11,10);
      每个视图构造函数都有一个名为BYTES_PER_ELEMENT属性,保存类型化数组的每个元素需要多少字节
      创建类型化视图可以不用先创建ArrayBuffer对象,只要传人希望数组保存的元素数,相应的构造函数就会自动创建包含足够字节数的ArrayBuffer对象
      var int8s = new Int8Array(10);
      var int8s = new Int8Array([10,20,30,20,20]);保存5个8位整数
      通过length属性确定数组中包含的元素个数
      subarray()方法,接收两个参数,开始元素的索引和可选的结束元素的索引,返回类型与调用该方法的视图类型相同
    2,WebGL上下文

      var drawing = document.getElementById("drawing");
      if(drawing.getContext){
      var gl = drawing.getContext("experimental-webgl");
      if(gl){}
      }

      getContext()接收第二个参数,可以为webGL上下文设置一些选项,参数本身是一个对象,包含属性如下
      alpha:值为true,表示为上下文创建一个Alpha通道缓冲区,默认值为true
      depth:值为true,表示可以使用16位深缓冲区,默认为true
      stencil:值为true,表示可以使用8位模板缓冲区,默认为true
      antialias:值为true,表示将使用默认机制执行抗锯齿操作,默认值为true
      premultipliedAlpha:值为true,表示绘图缓冲区有预乘Alpha值,默认为true
      preserveDrawingBuffer:值为true,表示在绘图完成后,保留绘图缓冲区,默认为false

      var gl = drawing.getContext("experimental-webgl",{alpha:false});
      if(drawing.getContext){
        try{
          gl = drawing.getContext("experimental-webgls");
        }catch(ex){}
        if(gl){}else{}
      }

      1)常量
      gl.开头,比如gl.COLOR_BUFFER_BIT
      2)方法命名
      通过方法名后缀判断接收的参数的类型和数量,f表示浮点数,i表示整数,v表示接收数组参数
      如gl.uniform3iv()
      3)准备绘图
      实际操作上下文前,要使用某种实色清除canvas
      clearColor(),方法来指定要使用的颜色值,接收4个参数,红,绿,蓝,透明度,参数0-1,表示分量的强度
      clear(),方法,清理缓冲区
      4)视图与坐标
      开始绘图之前,要先定义webGL的视口,调用viewport()方法,参数为视口相对于canvas元素的x坐标,y坐标,宽度和高度
      gl.viewport(0,0,drawing.width,drawing.height);
      视口坐标原点在canvas元素的左下角
      视口内部的坐标系原点在中心位置
      5)缓冲区
      创建缓冲区,var buffer = gl.createBuffer(),
      绑定到上下文,gl.bindbuffer(gl.ARRAY_BUFFER,buffer),
      数据填充,gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([0,0.5,1])),gl.STATIC_DRAW);
      释放内存,gl.deleteBuffer(buffer);
      gl.bufferData(),的最后一个参数用于指定使用缓冲区的方式,取值范围如下
      gl.STATIC_DRAW:数据只加载一次,在多次绘图中使用
      gl.STREAM_DRAW:数据只加载一次,在几次绘图中使用
      gl.DYNAMIC_DRAW:数据动态改变,在多次绘图中使用
      6)错误
      手工调用gl.getError(),返回一个错误类型的常量
      gl.NO_ERROR:没有错误
      gl.INVALID_ENUM:应该传人webGL常量,但传错了参数
      gl.INVALID_VALUE:在需要无符号的地放传入了负值
      gl.INVALID_OPERATION:在当前状态下不能完成操作
      gl.OUT_OF_MENORY:没有足够的内存完成操作
      gl.CONTEXT_LOST_WEBGL:外部文件干扰,丢失了当前webGL上下文

      var errorCode = gl.getError();
      while(errorCode){
        console.log("Error occurred:" + errorCode);
        errorCode = gl.getError();
      }

      7)着色器
      定点着色器:将3D顶点转换为需要渲染的2D点
      片段着色器:准确计算要绘制的每个像素的颜色
      8)编写着色器
      9)编写着色器程序
      10)为着色器传人值
      11)调试着色器和程序
      12)绘图
      13)文理
      14)读取像素
    3,支持

  • 相关阅读:
    DNS-解析、劫持、污染
    JavaScript-闭包注意事项
    Firefox-常用扩展
    Nginx-server_name匹配规则
    PHP-mysqllib和mysqlnd
    Nginx-缓冲原理及优化
    Linux-NFS原理介绍
    Linux-strace命令
    语音增强的几个基本算法
    【论文:麦克风阵列增强】Microphone Array Post-Filtering For Non-Stationary Noise Suppression
  • 原文地址:https://www.cnblogs.com/b0xiaoli/p/3643348.html
Copyright © 2011-2022 走看看