Canvas学习笔记五 - 变形 Transformations

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

Canvas状态存储在栈中,每当save()方法被调用后,当前的状态就被推送到栈中保存。可以调用任意多次 save方法。每一次调用 restore 方法,上一个保存的状态就从栈中弹出,所有设定都恢复。
其中绘画状态包括如下:

  • 当前应用的变形(即移动,旋转和缩放)
  • 以及下面这些属性:strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline, direction, imageSmoothingEnabled
  • 当前的裁切路径(clipping path)
方法描述
save()保存画布(canvas)的所有状态
restore()save 和 restore 方法是用来保存和恢复 canvas 状态的,都没有参数。Canvas 的状态就是当前画面应用的所有样式和变形的一个快照。

save和restore的结合使用

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

  ctx.fillRect(10, 10, 480, 480);
  ctx.save(); // 保存一

  ctx.fillStyle = '#87ceeb';
  ctx.fillRect(50, 50, 400, 400);
  ctx.save(); // 保存二

  ctx.fillStyle = '#3498dbaa';
  ctx.fillRect(100, 100, 300, 300);

  ctx.restore(); // 恢复保存二
  ctx.fillRect(150, 150, 200, 200);

  ctx.restore(); // 恢复保存一
  ctx.fillRect(220, 220, 60, 60);
}

二、移动 Translating

用来移动 canvas 和它的原点到一个不同的位置。translate 方法同时让我们可以任意放置这些图案,而不需要在 fillRect() 方法中手工调整坐标值。

在做变形之前先保存状态是一个良好的习惯。大多数情况下,调用 restore 方法比手动恢复原先的状态要简单得多。

方法描述
translate(x, y)translate 方法接受两个参数。x 是左右偏移量,y 是上下偏移量。
function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      ctx.save(); // 在translate移动之前进行保存,目的是可以回到初始的状态,重新绘制下一个。
      ctx.fillStyle = `#${j}${i}5`;
      ctx.fillText(`${j}${i}`, j * 100 + 100, i * 100 + 100);
      ctx.translate(j * 100 + 10, i * 100 + 10);
      ctx.fillRect(10, 10, 80, 80);
      ctx.restore();
    }
  }
}

在这里插入图片描述

三、旋转 Rotating

它用于以原点为中心旋转 canvas。

方法描述
rotate(angle)这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。
function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  ctx.translate(250, 250);

  for (var i = 1; i < 6; i++) {
    ctx.save();
    ctx.fillStyle = 'rgb(' + 51 * i + ',' + (255 - 51 * i) + ',255)';

    for (var j = 0; j < i * 6; j++) {
      ctx.rotate((Math.PI * 2) / (i * 6));
      ctx.beginPath();
      ctx.arc(0, i * 30, 10, 0, Math.PI * 2, true);
      ctx.fill();
    }

    ctx.restore();
  }
}

四、缩放 Scaling

用它来增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大。
画布初始情况下, 是以左上角坐标为原点的第一象限。如果参数为负实数, 相当于以x 或 y轴作为对称轴镜像反转(例如, 使用translate(0,canvas.height); scale(1,-1); 以y轴作为对称轴镜像反转, 就可得到著名的笛卡尔坐标系,左下角为原点)。

方法描述
scale(x, y)scale 方法可以缩放画布的水平和垂直的单位。两个参数都是实数,可以为负数,x 为水平缩放因子,y 为垂直缩放因子,如果比1小,会缩小图形, 如果比1大会放大图形。默认值为1, 为实际大小。
function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  ctx.font = '80px Times New Roman';
  ctx.save();
  ctx.scale(-1, 1);
  ctx.fillText('Canvas', -300, 100);
  ctx.restore();
}

在这里插入图片描述

五、变形 Transforms

这个方法允许对变形矩阵直接修改。

方法描述
transform(a, b, c, d, e, f)这个方法是将当前的变形矩阵乘上一个基于自身参数的矩阵
setTransform(a, b, c, d, e, f)这个方法会将当前的变形矩阵重置为单位矩阵,然后用相同的参数调用 transform 方法。如果任意一个参数是无限大,那么变形矩阵也必须被标记为无限大,否则会抛出异常。从根本上来说,该方法是取消了当前变形,然后设置为指定的变形,一步完成。
resetTransform()重置当前变形为单位矩阵,它和调用以下语句是一样的:ctx.setTransform(1, 0, 0, 1, 0, 0);

参数说明:

  • a (m11):水平方向的缩放
  • b(m12):竖直方向的倾斜偏移
  • c(m21):水平方向的倾斜偏移
  • d(m22):竖直方向的缩放
  • e(dx):水平方向的移动
  • f(dy):竖直方向的移动
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);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

俊小赞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值