zoukankan      html  css  js  c++  java
  • 【canvas学习笔记六】状态保存和变换

    save()和restore()

    save()
    保存当前状态,将当前canvas的状态存入栈中。
    restore()
    恢复之前save的一个状态,将之前的状态从栈中弹出。

    保存的当前状态包含以下信息:

    • 变换(平移、旋转、缩放)
    • 属性: strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline, direction, imageSmoothingEnabled
    • 剪裁路径

    save()和restore()的用处就是有时候用canvas绘图会经过很多操作,然后可以用restore()直接恢复原先的状态,而不用再变换到原来的状态。这个API在需要进行很多变换的时候特别有用。
    比如说在一开始先用save()保存了canvas最先的状态,也就是没经过任何操作的状态,然后开始用canvas绘图API绘图,中间对strokeStyle、lineWidth、globalAlpha等很多属性进行了修改,还进行了平移、旋转等等变换操作,这时,如果又要重新再画某个图形,而画这个图形要变换回原来最先的状态才方便画,那么直接restore()变回最初保存的状态就行,否则,又要重新平移、旋转,对各种属性赋值,才变回需要的状态,会非常麻烦。而save()和restore()两行就解决了这个问题。

    例子

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
    
      ctx.fillRect(0, 0, 150, 150);   // Draw a rectangle with default settings
      ctx.save();                  // Save the default state
     
      ctx.fillStyle = '#09F';      // Make changes to the settings
      ctx.fillRect(15, 15, 120, 120); // Draw a rectangle with new settings
    
      ctx.save();                  // Save the current state
      ctx.fillStyle = '#FFF';      // Make changes to the settings
      ctx.globalAlpha = 0.5; 
      ctx.fillRect(30, 30, 90, 90);   // Draw a rectangle with new settings
    
      ctx.restore();               // Restore previous state
      ctx.fillRect(45, 45, 60, 60);   // Draw a rectangle with restored settings
    
      ctx.restore();               // Restore original state
      ctx.fillRect(60, 60, 30, 30);   // Draw a rectangle with restored settings
    }
    

    结果

    image

    平移

    translate(x, y)
    将canvas沿x轴平移x个单位,沿y轴平移y个单位。

    image

    平移是会移动画布的,是画布的位置变了。

    例子

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
      for (var i = 0; i < 3; i++) {
        for (var j = 0; j < 3; j++) {
          ctx.save();
          ctx.fillStyle = 'rgb(' + (51 * i) + ', ' + (255 - 51 * i) + ', 255)';
          ctx.translate(10 + j * 50, 10 + i * 50);
          ctx.fillRect(0, 0, 25, 25);
          ctx.restore();
        }
      }
    }
    

    结果

    image

    旋转

    rotate(angle)
    以原点(0, 0)为中心点,旋转angle弧度。

    如果要以画布的中心点为旋转点,需要用translate()平移画布。
    旋转也是针对画布的。

    例子

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
      
      // left rectangles, rotate from canvas origin
      ctx.save();
      // blue rect
      ctx.fillStyle = '#0095DD';
      ctx.fillRect(30, 30, 100, 100); 
      ctx.rotate((Math.PI / 180) * 25);
      // grey rect
      ctx.fillStyle = '#4D4E53';
      ctx.fillRect(30, 30, 100, 100);
      ctx.restore();
    
      // right rectangles, rotate from rectangle center
      // draw blue rect
      ctx.fillStyle = '#0095DD';
      ctx.fillRect(150, 30, 100, 100);  
      
      ctx.translate(200, 80); // translate to rectangle center 
                              // x = x + 0.5 * width
                              // y = y + 0.5 * height
      ctx.rotate((Math.PI / 180) * 25); // rotate
      ctx.translate(-200, -80); // translate back
      
      // draw grey rect
      ctx.fillStyle = '#4D4E53';
      ctx.fillRect(150, 30, 100, 100);
    }
    

    结果

    image

    缩放

    scale(x, y)
    在水平方向缩放x个单位,在垂直方向缩放y个单位。

    x, y可以是负数,如果是负数的话,图片就会呈镜像。比如这行代码translate(0,canvas.height); scale(1,-1); 就将canvas垂直翻转,坐标原点变成了左下角。

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
    
      // draw a simple rectangle, but scale it.
      ctx.save();
      ctx.scale(10, 3);
      ctx.fillRect(1, 10, 10, 10);
      ctx.restore();
    
      // mirror horizontally
      ctx.scale(-1, 1);
      ctx.font = '48px serif';
      ctx.fillText('MDN', -135, 120);
    }
    

    结果

    image

    变换矩阵

    transform(a, b, c, d, e, f)
    将当前的变换矩阵乘上 [a, b, c, d, e, f, 0, 0, 1] (是个3X3的矩阵)。

    各个参数表示的变换如下:
    a (m11)
    水平缩放。
    b (m12)
    水平斜切。
    c (m21)
    垂直斜切。
    d (m22)
    垂直缩放。
    e (dx)
    水平平移。
    f (dy)
    垂直平移。
    要实现斜切的话,只能用变换矩阵。

    setTransform(a, b, c, d, e, f)
    重设当前变换矩阵,并进行变换。
    resetTransform()
    将当前矩阵设置为同等变换矩阵。相当于这行ctx.setTransform(1, 0, 0, 1, 0, 0);

    例子

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
    
      var sin = Math.sin(Math.PI / 6);
      var cos = Math.cos(Math.PI / 6);
      ctx.translate(100, 100);
      var c = 0;
      for (var i = 0; i <= 12; i++) {
        c = Math.floor(255 / 12 * i);
        ctx.fillStyle = 'rgb(' + c + ', ' + c + ', ' + c + ')';
        ctx.fillRect(0, 0, 100, 10);
        ctx.transform(cos, sin, -sin, cos, 0, 0);
      }
      
      ctx.setTransform(-1, 0, 0, 1, 100, 100);
      ctx.fillStyle = 'rgba(255, 128, 255, 0.5)';
      ctx.fillRect(0, 50, 100, 100);
    }
    

    结果

    image

  • 相关阅读:
    s 中日期 转换成时间戳 例如2013-08-30 转换为时间戳
    php解析html类库simple_html_dom
    c++关于字符串的读入和截取
    八皇后问题
    激活函数matlab代码
    转:ubuntu添加用户adduser,并给予sudo权限
    shell遍历多个文件夹并进行批量修改文件名
    【转】用win7(64位)远程桌面连接linux(Ubuntu14.04)详细教程
    机器学习-线性回归
    编译gpu集群版caffe
  • 原文地址:https://www.cnblogs.com/-867259206/p/7442687.html
Copyright © 2011-2022 走看看