Canvas 06

canvas画布状态的保存和恢复

save() —— 保存画布 (canvas) 的所有状态 restore() —— 恢复画布之前保存状态 保存的Canvas状态就是当前画布应用的所有样式和变形的一个快照。 我们可以想象canvas的状态保存在一个栈里面,调用save就会将栈状态保存到栈中。调用restore将保存的状态从栈弹出。

  • 画布的变形(平移、缩放、旋转)
  • 样式属性 strokeStyle,fillStyle,globalAlpha,globalCompositeOperation,font,imageSmoothEnabled
  • 当前的裁切路径

示例

function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");

  ctx.fillRect(0, 0, 150, 150); // 使用默认设置绘制一个矩形
  ctx.save(); // 保存默认状态

  ctx.fillStyle = "#09F"; // 在原有配置基础上对颜色做改变
  ctx.fillRect(15, 15, 120, 120); // 使用新的设置绘制一个矩形

  ctx.save(); // 保存当前状态
  ctx.fillStyle = "#FFF"; // 再次改变颜色配置
  ctx.globalAlpha = 0.5;
  ctx.fillRect(30, 30, 90, 90); // 使用新的配置绘制一个矩形

  ctx.restore(); // 重新加载之前的颜色状态
  ctx.fillRect(45, 45, 60, 60); // 使用上一次的配置绘制一个矩形

  ctx.restore(); // 加载默认颜色配置
  ctx.fillRect(60, 60, 30, 30); // 使用加载的配置绘制一个矩形
}

移动

translate(x, y) 示例

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();
    }
  }
}

旋转

rotate(angle) —— 以原点为中心旋转canvas,旋转的角度,顺时针方向,以弧度为单位。

π * 角度 / 180 => 弧度 示例

function draw() {
  const 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);
}

缩放

scale(x, y) —— x y 为负数的话,就会在对应方向上镜像翻转。

默认情况下,canvas的一个单位为一个像素。如果我们的缩放因子是0.5,则一个单位对应就变成0.5个像素。

示例

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);
}

变形

transform(a, b, c, d, e, f) —— 该方法允许我们直接对变形矩阵进行修改。表示将当前的变形矩阵乘上一个基于自身参数的矩阵。 a 水平方向的缩放 b 竖直方向的倾斜偏移 c 水平方向的倾斜偏移 d 竖直方向的缩放 e 水平方向的移动 f 竖直方向的移动 setTransform(a, b, c, d, e, f) —— 将当前变换矩阵重置为单位矩阵,并用设置参数调用transform方法变换图形。(该方法是取消了当前变形,然后设置为指定的变形。) 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);
}

ctx.transform(cos, sin, -sin, cos, 0, 0) 解释当前方法执行为什么表示将图形旋转30°  我们以单位变形出发,半径是一个单位(sin30正弦值  cos30是余弦值),根据相关参数水平竖直方向缩放cos30,竖直和水平方向偏移sin30,组合起来刚好是一个直角三角形,并且夹角30度,所以表示旋转了30度。

写在最后

未完待续… 希望大家好好生活,健康快乐。