zoukankan      html  css  js  c++  java
  • Canvas 基础汇总

    语法

    getContext()   用来获得渲染上下文和它的绘画功能(只有一个参数)

    检测浏览器是否支持Canvas

    1 var canvas = document.getElementById('tutorial');
    2 
    3 if (canvas.getContext){
    4   var ctx = canvas.getContext('2d');
    5   // drawing code here
    6 } else {
    7   // canvas-unsupported code here
    8 }

    绘制矩形

    • fillRect(x, y, width, height) 绘制一个填充的矩形
    • strokeRect(x, y, width, height) 绘制一个矩形的边框
    • clearRect(x, y, width, height) 清除指定矩形区域,让清除部分完全透明。

    绘制路径

    • beginPath() 新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
    • closePath() 闭合路径之后图形绘制命令又重新指向到上下文中。
    • stroke() 通过线条来绘制图形轮廓。
    • fill() 通过填充路径的内容区域生成实心的图形。
    1. 生成路径的第一步叫做beginPath()。本质上,路径是由很多子路径构成,这些子路径都是在一个列表中,所有的子路径(线、弧形、等等)构成图形。而每次这个方法调用之后,列表清空重置,然后我们就可以重新绘制新的图形。
    2. 第二步就是调用函数指定绘制路径
    3. 第三,就是闭合路径closePath(),不是必需的。这个方法会通过绘制一条从当前点到开始点的直线来闭合图形。如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。

    注意:当前路径为空,即调用beginPath()之后,或者canvas刚建的时候,第一条路径构造命令通常被视为是moveTo(),无论实际上是什么。出于这个原因,你几乎总是要在设置路径之后专门指定你的起始位置。

    注意:当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合

    移动笔触

    • moveTo(xy)  将笔触移动到指定的坐标x以及y上。

    当canvas初始化或者beginPath()调用后,通常会使用moveTo()函数设置起点。也能够使用moveTo()绘制一些不连续的路径。

    线

    • lineTo(x, y)  绘制一条从当前位置到指定x以及y位置的直线。

    圆弧

    注意:arc()函数中表示角的单位是弧度,不是角度。角度与弧度的js表达式:

                                  弧度 = (Math.PI / 180) * 角度。

    二次贝塞尔曲线及三次贝塞尔曲线

    • quadraticCurveTo(cp1x, cp1y, x, y) 绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。
    • bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) 绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。

    右边的图能够很好的描述两者的关系,二次贝塞尔曲线有一个开始点(蓝色)、一个结束点(蓝色)以及一个控制点(红色),而三次贝塞尔曲线有两个控制点。

    参数x、y在这两个方法中都是结束点坐标。cp1x,cp1y为坐标中的第一个控制点,cp2x,cp2y为坐标中的第二个控制点。

    矩形 

    • rect(xywidthheight) 绘制一个左上角坐标为(x,y),宽高为width以及height的矩形。

    Path2D 对象

      作用:用来缓存或记录绘画命令,这样你将能快速地回顾路径。

      创建对象:

          Path2D()  Path2D()会返回一个新初始化的Path2D对象(可能将某一个路径作为变量——创建一个它的副本,或者将一个包含SVG path数据的字符串作为变量)。

    1 new Path2D();     // 空的Path对象
    2 new Path2D(path); // 克隆Path对象
    3 new Path2D(d);    // 从SVG建立Path对象

      注意: 所有的路径方法比如 moveTorectarc quadraticCurveTo等,都可以在Path2D中使用。

      Path2D API 添加了 addPath作为将path结合起来的方法。当你想要从几个元素中来创建对象时,这将会很实用。

      比如:Path2D.addPath(path [, transform])
      添加了一条路径到当前路径(可能添加了一个变换矩阵)。

    Path2D 示例

     1 function draw() {
     2   var canvas = document.getElementById('canvas');
     3   if (canvas.getContext){
     4     var ctx = canvas.getContext('2d');
     5 
     6     var rectangle = new Path2D();    // 创建实例
     7     rectangle.rect(10, 10, 50, 50);  // 创建矩形
     8 
     9     var circle = new Path2D();    // 创建实例
    10     circle.moveTo(125, 35);       // 规定画笔起始点
    11     circle.arc(100, 35, 25, 0, 2 * Math.PI);    // 创建圆
    12 
    13     ctx.stroke(rectangle);    // 生成边框图像
    14     ctx.fill(circle);         // 生成实心图像
    15   }
    16 }

    使用 SVG paths

    这条路径将先移动到点 (M10 10) 然后再水平移动80个单位(h 80),然后下移80个单位 (v 80),接着左移80个单位 (h -80),再回到起点处 (z)。你可以在Path2D constructor 查看这个例子。

    1 var p = new Path2D("M10 10 h 80 v 80 h -80 Z");

    色彩 Colors

      注意:一旦设置了 strokeStyle 或者 fillStyle 的值,那么这个新值就会成为新绘制的图形的默认值。如果要给每个图形上不同的颜色,需要重新设置 fillStyle 或 strokeStyle 的值。

    透明度 Transparency

    • globalAlpha = transparencyValue  这个属性影响到 canvas 里所有图形的透明度,有效的值范围是 0.0 (完全透明)到 1.0(完全不透明),默认是 1.0。
    • 也可以用 strokeStyle  fillStyle 来设置 globalAlpha 的透明度
    • 1 // 指定透明颜色,用于描边和填充样式
      2 ctx.strokeStyle = "rgba(255,0,0,0.5)";
      3 ctx.fillStyle = "rgba(255,0,0,0.5)";

    线型 Line styles

    • miterLimit = value   限制当两条线相交时交接处最大长度;所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度。
    • getLineDash()   返回一个包含当前虚线样式,长度为非负偶数的数组。

    lineCap 属性的例子

    • 属性 lineCap 的值决定了线段端点显示的样子。它可以为下面的三种的其中之一:buttround 和 square。默认是 butt。

    lineJoin 属性的例子

    • lineJoin 的属性值决定了图形中两线段连接处所显示的样子。它可以是这三种之一:roundbevel 和 miter。默认是 miter

    使用虚线

    • 用 setLineDash 方法和 lineDashOffset 属性来制定虚线样式. setLineDash 方法接受一个数组,来指定线段与间隙的交替;lineDashOffset 属性设置起始偏移量.

    渐变 Gradients

    • createLinearGradient(x1, y1, x2, y2)  createLinearGradient 方法接受 4 个参数,表示渐变的起点 (x1,y1) 与终点 (x2,y2)
    • createRadialGradient(x1, y1, r1, x2, y2, r2)  createRadialGradient 方法接受 6 个参数,前三个定义一个以 (x1,y1) 为原点,半径为 r1 的圆,后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的圆。
    • 1 var lineargradient = ctx.createLinearGradient(0,0,150,150);
      2 var radialgradient = ctx.createRadialGradient(75,75,0,75,75,100);
    • gradient.addColorStop(position, color)  addColorStop 方法接受 2 个参数,position 参数必须是一个 0.0 与 1.0 之间的数值,表示渐变中颜色所在的相对位置。例如,0.5 表示颜色会出现在正中间。color 参数必须是一个有效的 CSS 颜色值(如 #FFF, rgba(0,0,0,1),等等)。
    • 1 var lineargradient = ctx.createLinearGradient(0,0,150,150);
      2 lineargradient.addColorStop(0,'white');
      3 lineargradient.addColorStop(1,'black');

    图案样式 Patterns

    • createPattern(image, type)  该方法接受两个参数。Image 可以是一个 Image 对象的引用,或者另一个 canvas 对象。Type 必须是下面的字符串值之一:repeatrepeat-xrepeat-y 和 no-repeat

      注意: 用 canvas 对象作为 Image 参数在 Firefox 1.5 (Gecko 1.8) 中是无效的

      图案的应用跟渐变很类似的,创建出一个 pattern 之后,赋给 fillStyle 或 strokeStyle 属性即可

    1 var img = new Image();
    2 img.src = 'someimage.png';
    3 var ptrn = ctx.createPattern(img,'repeat');

      注意:与 drawImage 有点不同,你需要确认 image 对象已经装载完毕,否则图案可能效果不对的。

    阴影 Shadows

    • shadowOffsetX = float   shadowOffsetX 和 shadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为 0
    • shadowOffsetY = float   shadowOffsetX 和 shadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为 0
    • shadowBlur = float   shadowBlur 用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为 0
    • shadowColor = color   shadowColor 是标准的 CSS 颜色值,用于设定阴影颜色效果,默认是全透明的黑色。

    文字阴影的例子

     1 function draw() {
     2   var ctx = document.getElementById('canvas').getContext('2d');
     3 
     4   ctx.shadowOffsetX = 2;
     5   ctx.shadowOffsetY = 2;
     6   ctx.shadowBlur = 2;
     7   ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
     8  
     9   ctx.font = "20px Times New Roman";
    10   ctx.fillStyle = "Black";
    11   ctx.fillText("Sample String", 5, 30);
    12 }

    Canvas 填充规则

    当我们用到 fill(或者 clipisPointinPath )你可以选择一个填充规则,该填充规则根据某处在路径的外面或者里面来决定该处是否被填充,这对于自己与自己路径相交或者路径被嵌套的时候是有用的。

    两个可能的值:

    绘制文本

    有样式的文本

    • font = value  当前我们用来绘制文本的样式. 这个字符串使用和 CSS font 属性相同的语法. 默认的字体是 10px sans-serif
    • textAlign = value  文本对齐选项. 可选的值包括:startendleftright or center. 默认值是 start
    • textBaseline = value  基线对齐选项. 可选的值包括:tophangingmiddlealphabeticideographicbottom。默认值是 alphabetic。
    • direction = value  文本方向。可能的值包括:ltrrtlinherit。默认值是 inherit
    • 1 ctx.font = "48px serif";
      2 ctx.textBaseline = "hanging";
      3 ctx.strokeText("Hello world", 0, 100);

    预测量文本宽度

      示例:

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
      var text = ctx.measureText("foo"); // TextMetrics object
      text.width; // 16;
    }

    获得需要绘制的图片

    • HTMLImageElement  这些图片是由Image()函数构造出来的,或者任何的<img>元素
    • HTMLVideoElement  用一个HTML的 <video>元素作为你的图片源,可以从视频中抓取当前帧作为一个图像
    • HTMLCanvasElement  可以使用另一个 <canvas> 元素作为你的图片源。
    • ImageBitmap  这是一个高性能的位图,可以低延迟地绘制,它可以从上述的所有源以及其它几种源中生成。

    绘制图片

    • drawImage(image, x, y)  其中 image 是 image 或者 canvas 对象,x 和 y 是其在目标 canvas 里的起始坐标。

    缩放 Scaling

    切片 Slicing

      相框例子

     1 function draw() {
     2   var canvas = document.getElementById('canvas');
     3   var ctx = canvas.getContext('2d');
     4 
     5   // Draw slice
     6   ctx.drawImage(document.getElementById('source'),
     7                 33,71,104,124,21,20,87,104);
     8 
     9   // Draw frame
    10   ctx.drawImage(document.getElementById('frame'),0,0);
    11 }

    状态的保存和恢复 Saving and restoring state

    • save()  保存画布(canvas)的所有状态
    • restore()  save 和 restore 方法是用来保存和恢复 canvas 状态的,都没有参数。Canvas 的状态就是当前画面应用的所有样式和变形的一个快照。

    Canvas状态存储在栈中,每当save()方法被调用后,当前的状态就被推送到栈中保存。一个绘画状态包括:

    • 当前应用的变形(即移动,旋转和缩放,见下)
    • strokeStylefillStyleglobalAlphalineWidthlineCaplineJoinmiterLimitshadowOffsetXshadowOffsetYshadowBlurshadowColorglobalCompositeOperation 的值
    • 当前的裁切路径(clipping path),会在下一节介绍

    移动 Translating

    • translate(x, y)  translate 方法接受两个参数。是左右偏移量,y 是上下偏移量,如右图所示。

    旋转 Rotating

    • rotate(angle)  这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。

      旋转的中心点始终是 canvas 的原点,如果要改变它,我们需要用到 translate 方法。

    缩放 Scaling

    • scale(x, y) scale 方法可以缩放画布的水平和垂直的单位。两个参数都是实数,可以为负数,x 为水平缩放因子,y 为垂直缩放因子,如果比1小,会比缩放图形, 如果比1大会放大图形。默认值为1, 为实际大小。

      画布初始情况下, 是以左上角坐标为原点的第一象限。如果参数为负实数, 相当于以x 或 y轴作为对称轴镜像反转 (例如, 使用translate(0,canvas.height); scale(1,-1); 以y轴作为对称轴镜像反转, 就可得到著名的笛卡尔坐标系,左下角为原点)。 

    注: 画图的方法的长度单位并不是1个像素点。

    例如 fillRect(0,0,100,100),表示长为100 * canvas默认单位长度,宽为100 * canvas默认单位长度。(canvas默认单位长度为1px)。

     

    变形 Transforms

    • transform(m11, m12, m21, m22, dx, dy)  这个方法是将当前的变形矩阵乘上一个基于自身参数的矩阵,在这里我们用下面的矩阵:
    • 1 m11 m21 dx
      2 m12 m22 dy
      3 0     0     1

      如果任意一个参数是无限大,变形矩阵也必须被标记为无限大,否则会抛出异常。

      这个函数的参数各自代表如下:

      m11:水平方向的缩放

      m12:水平方向的倾斜偏移

      m21:竖直方向的倾斜偏移

      m22:竖直方向的缩放

      dx:水平方向的移动

      dy:竖直方向的移动

    • resetTransform()  重置当前变形为单位矩阵,它和调用以下语句是一样的:
    1 ctx.setTransform(1, 0, 0, 1, 0, 0);

    globalCompositeOperation

    我们不仅可以在已有图形后面再画新图形,还可以用来遮盖指定区域,清除画布中的某些部分(清除区域不仅限于矩形,像clearRect()方法做的那样)以及更多其他操作。

    裁切路径

    • clip()  将当前正在构建的路径转换为当前的裁剪路径。

      我们使用 clip()方法来创建一个新的裁切路径。

      默认情况下,canvas 有一个与它自身一样大的裁切路径(也就是没有裁切效果)。

    绘制星星示例

     1 function draw() {
     2   var ctx = document.getElementById('canvas').getContext('2d');
     3   ctx.fillRect(0,0,150,150);
     4   ctx.translate(75,75);
     5 
     6   // Create a circular clipping path
     7   ctx.beginPath();
     8   ctx.arc(0,0,60,0,Math.PI*2,true);
     9   ctx.clip();
    10 
    11   // draw background
    12   var lingrad = ctx.createLinearGradient(0,-75,0,75);
    13   lingrad.addColorStop(0, '#232256');
    14   lingrad.addColorStop(1, '#143778');
    15   
    16   ctx.fillStyle = lingrad;
    17   ctx.fillRect(-75,-75,150,150);
    18 
    19   // draw stars
    20   for (var j=1;j<50;j++){
    21     ctx.save();
    22     ctx.fillStyle = '#fff';
    23     ctx.translate(75-Math.floor(Math.random()*150),
    24                   75-Math.floor(Math.random()*150));
    25     drawStar(ctx,Math.floor(Math.random()*4)+2);
    26     ctx.restore();
    27   }
    28   
    29 }
    30 function drawStar(ctx,r){
    31   ctx.save();
    32   ctx.beginPath()
    33   ctx.moveTo(r,0);
    34   for (var i=0;i<9;i++){
    35     ctx.rotate(Math.PI/5);
    36     if(i%2 == 0) {
    37       ctx.lineTo((r/0.525731)*0.200811,0);
    38     } else {
    39       ctx.lineTo(r,0);
    40     }
    41   }
    42   ctx.closePath();
    43   ctx.fill();
    44   ctx.restore();
    45 }

    首先,我画了一个与 canvas 一样大小的黑色方形作为背景,然后移动原点至中心点。然后用 clip 方法创建一个弧形的裁切路径。裁切路径也属于 canvas 状态的一部分,可以被保存起来。如果我们在创建新裁切路径时想保留原来的裁切路径,我们需要做的就是保存一下 canvas 的状态。

    裁切路径创建之后所有出现在它里面的东西才会画出来。在画线性渐变时我们就会注意到这点。然后会绘制出50 颗随机位置分布(经过缩放)的星星,当然也只有在裁切路径里面的星星才会绘制出来。

  • 相关阅读:
    构建之法阅读笔记01
    学习进度13
    学习进度12
    个人冲刺十
    个人冲刺九
    个人冲刺八
    学习进度11
    个人冲刺七
    个人冲刺六
    [HDU 1232 ]畅通工程
  • 原文地址:https://www.cnblogs.com/PasserByOne/p/12457692.html
Copyright © 2011-2022 走看看