理解translate、rotate、scale与save、restore的结合

在使用HTML5 Canvas进行绘图操作时,translaterotatescale等变换操作是通过Canvas的2D上下文(CanvasRenderingContext2D)提供的变换方法实现的。这些变换会影响后续绘制的所有图形,直到你通过调用saverestore来保存和恢复变换状态。

saverestore 的作用

  • save():将当前的变换矩阵和其他属性(如填充颜色、字体等)保存到一个栈中。
  • restore():从栈中恢复最近一次保存的状态,包括变换矩阵和其他属性。

变换操作的影响范围

所有的变换操作(如translaterotatescale)都会修改当前的变换矩阵,并且这些修改是累积的。这意味着如果你不使用saverestore来管理变换状态,变换会一直影响后续的绘图操作,直到显式地重置变换矩阵。

示例代码

基本变换操作示例
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// 平移画布中心到(100, 100)
ctx.translate(100, 100);

// 旋转45度
ctx.rotate(Math.PI / 4); // 45度转换为弧度

// 缩放x轴和y轴各放大2倍
ctx.scale(2, 2);

// 绘制一个矩形
ctx.fillStyle = 'blue';
ctx.fillRect(-50, -50, 100, 100);

在这个例子中,所有变换都是累积的,最终绘制的矩形会受到平移、旋转和缩放的影响。

使用 saverestore 管理变换状态
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// 保存当前状态
ctx.save();

// 平移画布中心到(100, 100)
ctx.translate(100, 100);

// 旋转45度
ctx.rotate(Math.PI / 4); // 45度转换为弧度

// 缩放x轴和y轴各放大2倍
ctx.scale(2, 2);

// 绘制一个矩形
ctx.fillStyle = 'blue';
ctx.fillRect(-50, -50, 100, 100);

// 恢复之前保存的状态
ctx.restore();

// 再次绘制一个矩形,这次不受之前的变换影响
ctx.fillStyle = 'red';
ctx.fillRect(150, 150, 100, 100);

在这个例子中,第一个矩形受到了平移、旋转和缩放的影响,而第二个矩形则没有受到影响,因为它是在调用restore之后绘制的。

变换操作是否受 saverestore 控制

是的,translaterotatescale等变换操作是受saverestore控制的。具体来说:

  • save():保存当前的变换矩阵以及其他绘图状态(如填充颜色、字体等),并将它们压入栈中。
  • restore():从栈中弹出最近一次保存的状态,并恢复这些状态,包括变换矩阵。

因此,当你需要临时应用一些变换并在之后恢复原始状态时,可以使用saverestore来管理这些变换。

进一步说明

  1. 变换矩阵的累积性

    • 每次调用translaterotatescale等方法都会修改当前的变换矩阵,并且这些修改是累积的。也就是说,如果你连续调用这些方法,它们的效果会叠加在一起。
  2. 重置变换矩阵

    • 如果你不使用saverestore,也可以通过调用setTransform(1, 0, 0, 1, 0, 0)来重置变换矩阵,使其恢复到默认状态。
  3. 嵌套变换

    • 你可以嵌套使用saverestore来管理不同层次的变换。例如,在一个较大的变换块中嵌套一个小的变换块,这样可以确保小块内的变换不会影响外部的变换。

复杂示例:嵌套变换

const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// 第一组变换
ctx.save();
ctx.translate(100, 100);
ctx.rotate(Math.PI / 4); // 45度
ctx.scale(2, 2);

// 绘制一个蓝色矩形
ctx.fillStyle = 'blue';
ctx.fillRect(-50, -50, 100, 100);

// 第二组变换(嵌套)
ctx.save();
ctx.translate(50, 50);
ctx.rotate(Math.PI / 6); // 30度
ctx.scale(1.5, 1.5);

// 绘制一个绿色矩形
ctx.fillStyle = 'green';
ctx.fillRect(-25, -25, 50, 50);

// 恢复第二组变换前的状态
ctx.restore();

// 再次绘制一个黄色矩形,只受第一组变换影响
ctx.fillStyle = 'yellow';
ctx.fillRect(25, 25, 50, 50);

// 恢复第一组变换前的状态
ctx.restore();

// 绘制一个红色矩形,不受任何变换影响
ctx.fillStyle = 'red';
ctx.fillRect(150, 150, 100, 100);

在这个复杂示例中,我们展示了如何嵌套使用saverestore来管理不同层次的变换。每个嵌套块内的变换仅影响该块内的绘图操作,而不会影响外部的绘图操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

掘铁

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

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

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

打赏作者

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

抵扣说明:

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

余额充值