自定义view相关

canvas-状态的变换及图形变换

2019-06-11  本文已影响0人  我只会吃饭

一、状态的保存

有两种方法可以跟踪上下文的状态变化

  1. save()
    调用这个方法,将当前所有的设置放入一个栈结构,保存起来
    然后可以对上下文进行其他修改;
    需要注意的是:save() 方法保存的只是对绘图上下文的设置和变换,不会保存绘图上下文的内容
  1. restore()
    等想要回到之前保存的设置时,可以调用restore()方法,在保存设置的栈结构中向前返回一级,恢复之前的状态
    连续调用save()可以把更多设置保存到栈结构中,之后再连续调用restore()则可以以一级一级返回

栗子:

ctx.beginPath();

ctx.translate(50, 50); // 第一次移动
ctx.fillStyle = 'skyblue';
ctx.rect(100, 100, 200, 200);

ctx.fill();

// 开始画第二个正方形
ctx.beginPath();

ctx.fillStyle = 'orange';
ctx.translate(100, 100); // 第二次移动
ctx.rect(100, 100, 100, 100);

ctx.fill();
image.png

当第二次移动位置的时候,承接的第一次移动的距离,因此何时如何保存当前上下文的状态及变换变得尤为重要

下面,我们使用save及restore方法:

// 先保存当前设置及变换
ctx.save();

// 开始画第一个正方形
ctx.beginPath();

ctx.translate(50, 50); // 第一次移动
ctx.fillStyle = 'skyblue';
ctx.rect(100, 100, 200, 200);

ctx.fill();

// 画完第一个回到起初状态
ctx.restore();

// 开始画第二个正方形
ctx.beginPath();

ctx.fillStyle = 'orange';
ctx.translate(100, 100); // 第二次移动
ctx.rect(100, 100, 100, 100);

ctx.fill();

// 画完第二个再回到起初状态
ctx.restore();

image.png

二、图形变换

  1. 位移 translate(x, y)
    上面的栗子使用的就是位移
  1. 旋转 rotate(deg)
    旋转当前的绘图
ctx.beginPath();
ctx.fillStyle = 'skyblue';
ctx.rect(0, 0, 100, 100);

ctx.rect(250, 250, 100, 100);
ctx.fill();

// 旋转15deg
ctx.beginPath();
ctx.fillStyle = 'green';
ctx.rotate(Math.PI / 180 * 15);
ctx.rect(0, 0, 100, 100);

ctx.rect(250, 250, 100, 100);
ctx.fill();


// 再次旋转15deg
ctx.beginPath();
ctx.fillStyle = 'blue';
ctx.rotate(Math.PI / 180 * 15);
ctx.rect(0, 0, 100, 100);

ctx.rect(250, 250, 100, 100);
ctx.fill();
image.png
  1. 缩放 scale(xs, ys);
    对绘图进行缩放,所有之后的绘图也会被缩放。定位也会被缩放
ctx.beginPath();
ctx.fillStyle = 'skyblue';
ctx.rect(50, 50, 100, 100);
ctx.fill();

ctx.beginPath();
ctx.fillStyle = 'green';
ctx.scale(1.5, 1.5);
ctx.rect(50, 50, 100, 100);
ctx.fill();

ctx.beginPath();
ctx.fillStyle = 'blue';
ctx.scale(1.5, 1.5);
ctx.rect(50, 50, 100, 100);
ctx.fill();
image.png
  1. 矩阵 transform(a, b, c, d, e, f);
    transform(水平缩放, 水平倾斜, 垂直倾斜, 垂直缩放, 水平位移, 垂直位移)

以上的变换效果会产生级联,导致在一级一级的不断累积

  1. setTransform(): 可以让之前的transform的累积效果失效
    setTransform(水平缩放, 水平倾斜, 垂直倾斜, 垂直缩放, 水平位移, 垂直位移)
ctx.beginPath();
ctx.fillStyle = 'skyblue';
ctx.rect(0, 0, 100, 100);
ctx.fill();

// 移动50
ctx.beginPath();
ctx.fillStyle = 'green';
// ctx.rotate(Math.PI / 180 * 15);
ctx.setTransform(1, 0, 0, 1, 50, 50);

ctx.rect(0, 0, 100, 100);

ctx.fill();


// 移动150
ctx.beginPath();
ctx.fillStyle = 'blue';
ctx.setTransform(1, 0, 0, 1, 150, 150);
ctx.rect(0, 0, 100, 100);
ctx.fill();
image.png
上一篇下一篇

猜你喜欢

热点阅读