zoukankan      html  css  js  c++  java
  • 前端--关于Canvas

    Canvas基础

    参考文档

    http://dev.w3.org/html5/spec 2d渲染上下文--W3C维护

    http://www.khronos.org/registry/webgl/specs/latest 3D渲染上下文--WebGL

    http://code.google.com/p/explorercanvas/ ExplorerCanvas

    CANVAS介绍

    1. canvas历史

      canvas这个标记最初是由苹果公司发明的,苹果公司希望有一种方式可以在Dashboard 中支持脚本化的图形,所以在 Safari 1.3 Web 浏览器中首次实现了对canvas的引入。但很快canvas标签成功引起了其他浏览器开发商的注意,并最终导致将它直接加入到HTML5的规范中。

    2. 什么是canvas

      canvas是html5规范中新加入的标签,这个标签本身没有任何绘画能力,可以把它看作一个普通的块级元素,每个canvas的dom对象实例都继承自HTMLCanvasElement这个原型,这个原型里有一个叫getContext的方法,这个方法返回一个渲染上下文对象。根据传入的参数的不同,可以返回不同类别的渲染上下文,目前只能返回一个2d的渲染上下文。这个渲染上下文对象提供了绘图和图形操作所需要的全部属性和方法,即渲染对象实例中的19种属性和渲染对象实例继承的CanvasRenderingContext2D对象中的40种方法。所以canvas元素只是这个渲染上下文的容器,真正的绘图操作是在渲染上下文中进行,它起到的作用只是容纳和显示渲染上下文及其绘制的内容。

    3. 创建canvas

      在支持canvas的浏览器中创建canvas元素和创建div元素一样随意而又容易,因为canvas的运行完全不需要任何外部的插件,对于不支持canvas的浏览器可以引用ExplorerCanvas这个外部脚本来使浏览器支持canvas。

      创建canvas代码:

      <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>

      上面这段代码非常简单,就创建了一个标签并写了几个属性,在浏览器中也看不到任何的效果,只是创建了一个空元素,因为这个canvas的渲染山下文并没有执行任何操作,而元素中间的文字是当浏览器不支持canvas时显示出来的。但要特别注意width和height这两个属性。首先,这两个属性值的书写是不能带百分号的,因为百分号后缀都会被忽略并直接使用px为单位。其次,这个长和宽不但设置了canvas元素的尺寸还设置了抽象的渲染上下文的尺寸。抽象的渲染上下文的尺寸只能通过改变canvas元素的width和height属性去设置,而canvas元素的尺寸还可以通过css去设置,所以通过css设置的尺寸大小是没有办法改变渲染上下文尺寸的,所以建议canvas的尺寸大小不要用css去设置,因为这可能会导致canvas元素的尺寸大小和渲染上下文的尺寸大小不一致的情况,这两个尺寸不一致可能会导致意外的效果,比如说浏览器会自动缩放渲染上下文的大小使其符合元素的大小。demo:正常设置width、height

      <!DOCTYPE html>
      <html>
      ​
      <head>
      <meta charset="utf-8">
      <title>canvas</title>
      </head>
      ​
      <body>
      <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
      <script>
          var canvas = document.getElementById('canvas');
          var context = canvas.getContext('2d');
          context.font = '40px serif';
          context.fillText('hello canvas', 100, 100);
      </script>
      </body>
      ​
      </html>

      通过css设置width、height

      <!DOCTYPE html>
      <html>
      ​
      <head>
      <meta charset="utf-8">
      <title>canvas</title>
      <style>
          canvas {
           600px;
          height: 600px;
          }
      </style>
      </head>
      ​
      <body>
      <canvas id="canvas">您的浏览器不支持canvas</canvas>
      <script>
          var canvas = document.getElementById('canvas');
          var context = canvas.getContext('2d');
          context.font = '40px serif';
          context.fillText('hello canvas', 100, 100);
      </script>
      </body>
      ​
      </html>
    4. 2d渲染上下文坐标系

      现在知道在canvas元素中存在一个抽象的绘图环境,这个绘图环境是一种基于屏幕的绘图平台,和其他2D平台类似,它也采用笛卡尔坐标系统,左上角为原点,向左移动为X轴,向下移动为Y轴。

    ​ 坐标系统中1个单位通常相当于屏幕的一个像素,然而canvas的坐标系统并不是固定不变的,还可以对坐标系统进行平移、旋转、缩放等操作,就像前面使用了css设置canvas大小一样,浏览器对绘图环境的坐标系统进行了自动缩放,所以产生了意外的效果。

    图形绘制

    在canvas的绘图环境中有两种绘制图形的方式,一种是立即绘制图形,一种是基于路径的绘制图形。立即绘制图形就是调用绘图环境提供的方法可以立即在画布中画出图形;而基于路径的绘制是说需要预先定义一个不可见的路径,然后再对其进行描边或者填充。

    1. 立即绘制图形

    绘图环境对象一共提供了4种立即绘制图形的方法:fillRect、strokeRect、fillText、strokeText。

    fillRect:直接填充某颜色的实心矩形,默认颜色为黑色,填充颜色可以用fillStyle属性设置

    使用方法:fillRect(x, y, width, height),x、y表示矩形原点左上角的坐标,width、height表死后水平方向和垂直方向的长度

       <!DOCTYPE html>
       <html>
        <head>
         <meta charset="utf-8">
         <title>canvas</title>
        </head>
       <body>
        <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
        <script>
           var canvas = document.getElementById('canvas');
           var context = canvas.getContext('2d');
           context.fillStyle='#108EE9';
           context.fillRect(100,100,100,200);
        </script>
       </body>
       </html>

    strokeRect:直接描边画出某颜色的矩形框,默认颜色为黑色,矩形框的颜色可以用strokeStyle属性设置

    使用方法:strokeRect(x, y, width, height),x、y表示矩形原点即左上角的坐标,width、height表死后水平方向和垂直方向的长度

       <!DOCTYPE html>
       <html>
        <head>
         <meta charset="utf-8">
         <title>canvas</title>
        </head>
       <body>
        <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
        <script>
           var canvas = document.getElementById('canvas');
           var context = canvas.getContext('2d');
           context.font='40px serif';
           context.strokeText('hello canvas',100,200);
        </script>
       </body>
       </html>

    fillText:直接绘制填色的文本,文本的默认颜色是黑色,填充颜色可以用fillStyle属性设置,font属性可以设置文本其他特征,与css的font属性保持一致书写方式。

    使用方法:fillText(text,x,y),text表示要书写的文本,x、y表示文本原点即左下角的坐标

       <!DOCTYPE html>
       <html>
        <head>
         <meta charset="utf-8">
         <title>canvas</title>
        </head>
       <body>
        <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
        <script>
           var canvas = document.getElementById('canvas');
           var context = canvas.getContext('2d');
           context.fillStyle='#108EE9';
           context.font='60px serif';
           context.fillText('hello canvas',200,200);
        </script>
       </body>
       </html>

    strokeText:在画布上绘制文本(没有填色),文本的默认颜色是黑色,边框颜色可以用strokeStyle属性设置,font属性可以设置文本其他特征,与css的font属性保持一致书写方式。

       <!DOCTYPE html>
       <html>
        <head>
         <meta charset="utf-8">
         <title>canvas</title>
        </head>
       <body>
        <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
        <script>
           var canvas = document.getElementById('canvas');
           var context = canvas.getContext('2d');
           context.font='40px serif';
           context.strokeText('hello canvas',100,200);
        </script>
       </body>
       </html>

    注意:如果图形的原点坐标跑到了canvas元素的外面,那么在外面的部分是不显示的。

    1. 基于路径的图形绘制

      路径这个概念不太好理解,主要是因为canvas对路径的多样性操作导致的,例如描边、填充,以及衍生出开放路径、闭合路径、子路径、清除路径等概念。

      路径最简单粗暴的理解就是线段。路径包括两个要素:点以及点与点之间的连线方式,一条路径可能包含多个点而点与点之间的连接方式又可能是线段、弧线或者不规则的曲线。像这种预先在绘图环境中定义好的、还没有画出的点以及点与点之间的连接方式,就叫做路径。

      线条路径:moveTo lineTo

      线条路径包括两个点:起始点和终点

      点与点之间的连接方式:直线

      <!DOCTYPE html>
      <html>
       <head>
        <meta charset="utf-8">
        <title>canvas</title>
       </head>
      <body>
       <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
       <script>
          var canvas = document.getElementById('canvas');
          var context = canvas.getContext('2d');
          context.strokeStyle='#108EE9';
          context.moveTo(200,100);
          context.lineTo(300,500);
          context.stroke();
       </script>
      </body>
      </html>

      moveTo(x,y)方法设置路径原点,lineTo(x,y)设置路径的终点并决定起始点与终点用直线相连,stroke()方法执行对路径进行描边

      矩形路径:rect(x, y, width, height)

      矩形路径是一种特殊的线条路径,会在绘图环境中形成四个点,点与点之间用直线相连形成一个闭合路径

      <!DOCTYPE html>
      <html>
       <head>
        <meta charset="utf-8">
        <title>canvas</title>
       </head>
      <body>
       <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
       <script>
          var canvas = document.getElementById('canvas');
          var context = canvas.getContext('2d');
          context.strokeStyle='#108EE9';
          context.rect(0,0,300,400);
          context.stroke();
       </script>
      </body>
      </html>

      x、y设置了矩形路径的原点(矩形左上角)坐标,width和height决定了该矩形路径的剩下三个点的坐标,最后调用stroke方法对路径进行描边

      弧形路径:arc(x, y, radius, startAngle, endAngle, anticlock)

      在canvas中不存在定义圆形路径这个方法,只有定义一段圆弧路径的方法,若要画一个圆形只要画一个360度的圆弧即可

      arc(x, y, radius, startAngle, endAngle, anticlock)这个方法中:

      x、y定义了圆心坐标;

      radius定义了圆的半径;

      startAngle和endAngle定义了起始点和终点的位置:这两个位置指的是以x、y为圆心radius为半径的圆弧上的位置,这个位置是依靠弧度来确定的,如下图

      在圆心水平最右边是0度,在原点垂直最下方是0.5pi,这里的度数是以弧度为单位计算的而不是角度

      anticlock是个布尔值表示圆弧是按逆时针还是顺时针绘制,为true表示按逆时针,false表示按顺时针绘制

      一段圆弧:

      <!DOCTYPE html>
      <html>
       <head>
        <meta charset="utf-8">
        <title>canvas</title>
       </head>
      <body>
       <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
       <script>
          var canvas = document.getElementById('canvas');
          var context = canvas.getContext('2d');
          context.strokeStyle='#108EE9';
          context.arc(100,300,50,Math.PI*0.2,Math.PI*0.8,true);
          context.stroke();
          context.beginPath();
          context.arc(300,300,50,Math.PI*0.2,Math.PI*0.8,false);
          context.stroke();
       </script>
      </body>
      </html>

      一个整圆:

      <!DOCTYPE html>
      <html>
       <head>
        <meta charset="utf-8">
        <title>canvas</title>
       </head>
      <body>
       <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
       <script>
          var canvas = document.getElementById('canvas');
          var context = canvas.getContext('2d');
          context.fillStyle='#108EE9';
          context.arc(300,300,50,Math.PI*0,Math.PI*2,true);
          context.fill();
       </script>
      </body>
      </html>

      关于beginPath和closePath

      在前一个例子中画了两段圆弧,在两个arc方法之间有一个beginPath方法,beginPath按字面理解就是开始路径,它的官方解释也差不多:清除当前路径并重置,以开始一个新的路径。前面讲过路径是预先在绘图环境中定义好的,当调用stroke或者fill时再对路径进行描边或者填充。但是,当对路径进行过描边或者填充后,这个路径还是仍然会在内存中继续存在的,当你又定义了其他路径并再次调用stroke或者fill方法时,原来的路径仍然会再次进行一次绘制,不是重绘,原来的路径存在两幅图,只是互相重叠了。

      <!DOCTYPE html>
      <html>
      ​
      <head>
          <meta charset="utf-8">
          <title>canvas</title>
      </head>
      ​
      <body>
          <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
          <script>
              var canvas = document.getElementById('canvas');
              var context = canvas.getContext('2d');
              context.globalAlpha = 0.5;
              context.strokeStyle = '#108EE9';
              context.moveTo(200, 100);
              context.lineTo(300, 500);
              context.stroke();
              context.beginPath();
              context.strokeStyle = '#4A4A4A';
              context.moveTo(300, 200);
              context.lineTo(100, 400);
              context.stroke();
          </script>
      </body>
      ​
      </html>

      closePath:显示的封闭某段开放路径。

      <!DOCTYPE html>
      <html>
       <head>
        <meta charset="utf-8">
        <title>canvas</title>
       </head>
      <body>
       <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
       <script>
          var canvas = document.getElementById('canvas');
          var context = canvas.getContext('2d');
          context.strokeStyle='#108EE9';
          context.beginPath();
          context.arc(100,300,50,Math.PI*0.2,Math.PI*0.8,true);
          context.closePath();
          context.stroke();
       </script>
      </body>
      </html>

      注意:closePath这个方法不能单独存在,一定要先有一个beginPath方法;closePath方法要放在stroke或fill之前。

      贝塞尔曲线

      canvas绘制曲线的方法就两种,一种是前面讲的圆弧画法,另外一种就是贝塞尔曲线。

      贝塞尔曲线又分为二次贝塞尔曲线和三次贝塞尔曲线,如图

      贝塞尔曲线就是通过控制点将一条直线变成曲线。二次贝塞尔曲线有一个控制点,三次贝塞尔曲线有两个控制点,有两个控制点就意味着直线会有两次弯曲。

      二次贝塞尔曲线:quadraticCurveTo(cpx, cpy, x, y) 该方法前两个参数是控制点的坐标,后两个参数是路径终点的坐标

      <!DOCTYPE html>
      <html>
       <head>
        <meta charset="utf-8">
        <title>canvas</title>
       </head>
      <body>
       <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
       <script>
          var canvas = document.getElementById('canvas');
          var context = canvas.getContext('2d');
          context.beginPath();
          context.moveTo(200,200);
          context.quadraticCurveTo(50,300,500,500)
          context.stroke();
       </script>
      </body>
      </html>

      三次贝塞尔曲线:bezierCurveTo(cpx1,cpy1,cpx2,cpy2,x,y) 该方法前两个参数是第一个控制点的坐标,后两个参数是第二个控制点的坐标,最后两个参数是路径终点的坐标

      <!DOCTYPE html>
      <html>
       <head>
        <meta charset="utf-8">
        <title>canvas</title>
       </head>
      <body>
       <canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
       <script>
          var canvas = document.getElementById('canvas');
          var context = canvas.getContext('2d');
          context.beginPath();
          context.moveTo(50,250);
          context.bezierCurveTo(150,50,350,450,450,250)
          context.stroke();
       </script>
      </body>
      </html>
      擦除canvas

      canvas能绘制出图像就能擦除图像

      clearRect(x, y, width, height):清除某个矩形区域内的图像

      重置width或height:重置整个canvas

  • 相关阅读:
    kubernetes 将pod运行在某些特定的节点上,给节点打标签
    kubernetes 安装metrics-server
    数组基本内容,如有遗漏还请指出!
    ES6新属性(追加)
    ES6新属性笔记
    Flex 布局教程
    你知道js中的变量你会定义吗?那常量呢?
    ES6-01:常量与变量的声明
    三种方法实现js中类的继承
    JS完成页面跳转并传参的方法|附加:循环遍历对象
  • 原文地址:https://www.cnblogs.com/jinjilin/p/6847858.html
Copyright © 2011-2022 走看看