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

一、状态的保存

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

  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
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、简介 HTML5 中的定义:“它是依赖分辨率的位图画布,你可以在 canvas 上面绘制任何图形,甚至加载照片...
    destiny0904阅读 10,601评论 1 4
  • Canvas绘图 HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像。 画布是一个矩形...
    shanruopeng阅读 18,430评论 2 14
  •   HTML5 添加的最受欢迎的功能就是 元素。这个元素负责在页面中设定一个区域,然后就可以通过 JavaScri...
    霜天晓阅读 3,069评论 0 2
  • canvas元素的基础知识 在页面上放置一个canvas元素,就相当于在页面上放置了一块画布,可以在其中进行图形的...
    oWSQo阅读 10,351评论 0 19
  • 如果画笔的方式不是insert,那么会出现一些奇怪的,情况,特别是圆角比较大的时候。https://docs.mi...
    吉凶以情迁阅读 792评论 0 0