html5中canvas图形变换transform、setTransform原理(变换矩阵)

本节目录

变换矩阵

canvas中,平移 translate()、缩放 scale() 和旋转 rotate() 这 3 种方法在本质上是用变换矩阵 transform()方法来实现的。

也就是说,我们仅通过 transform() 方法就可以实现平移、缩放和旋转这 3 种操作。

语法

javascript 复制代码
ctx.transform(a,b,c,d,e,f);

a :水平缩放绘图

b :水平倾斜绘图

c :垂直倾斜绘图

d :垂直缩放绘图

e :水平移动绘图

f :垂直移动绘图

原理

原理是很简单的线性代数的矩阵乘法

设置开始坐标系为(x1, y1), 经过变换后得到 (x2, y2)

javascript 复制代码
          
令矩阵 
    [a, c, e]
A = [b, d, f]
    [0, 0, 1]

则:
  [x2]       [x1]
  [y2] = A * [y1]
  [c ]       [1]

则有:
x2 = a*x1 + c*y1 + e
y2 = b*x1 + d*y1 + f
c = 1

矩阵乘法原则是:
· 只有左矩阵的列数与右矩阵的行数相同的两个矩阵才能相乘.
· 乘积矩阵第i行第j列处的元素等于左矩阵的第i行与右矩阵的第j列对应元素乘积之和.
· 乘积矩阵的行数等于左矩阵的行数,列数等于右矩阵的列数.

c为了凑矩阵运算用的,计算得到后没用作用,直接舍去, 我们只看x2,y2

如果你对数学敏感,那么现在就可以看出来,前面abcdef的取名为什么是这样取的了

复制代码
x2 = a*x1 + c*y1 + e
y2 = b*x1 + d*y1 + f

a :水平缩放绘图
b :水平倾斜绘图
c :垂直倾斜绘图
d :垂直缩放绘图
e :水平移动绘图
f :垂直移动绘图

实现平移

由于:

x2 = ax1 + c y1 + e

y2 = bx1 + dy1 + f

对于点(x1, y1)平移到点(x2, y2), 那么应该有:

x2 = x1 + ?

y2 = y1 + ?

则令:

a=d=1

c=b=0

e即为x轴平移距离, f为y轴平移距离

即:

x2 = 1 * x1 + 0 * y1 + e

x2 = x1 + e
y2 = 0 * x1 + 1 * y1 + f

y2 = y1 + f

即

javascript 复制代码
ctx.transform(1, 0, 0, 1, e, f)

实现缩放

由于:

x2 = ax1 + c y1 + e

y2 = bx1 + dy1 + f

对于(x1, y1)缩放后到(x2, y2), 有:

x2 = nx1
y2 = n
y2

则令:

c = e = b = f = 0

则

x2 = ax1
y2 = d
y1

即

javascript 复制代码
ctx.transform(a, 0, 0, d, 0, 0)

实现旋转

假设图形开始坐标为(x1,y1),旋转后的坐标为(x2,y2),图形旋转的角度为 θ,那么就有

以下公式:

x2 = x1 * cosθ - y1 * sinθ;

y2 = x1 * sinθ + y1 * cosθ;

由于:

x 2 = a * x1 + c * y1 + e

y2 = b * x1 + d * y1 + f

则令

e = f = 0

a = cosθ

b = sinθ

c = -sinθ

d = cosθ

即

javascript 复制代码
ctx.transform(cosθ, sinθ,- sinθ, cosθ, 0, 0)

transform与setTransform的区别

区别就是transform会在上一次的基础上变换原点与坐标系旋转角度

而setTransform则每次都从w3c坐标系的基础上也就是最原始的坐标

这意味着混合使用先transform顺时针30度再使用setTransform顺时针旋转30度, 当前绘制的话, 其实只在w3c坐标系的基础上旋转了30度。

但是使用两个transform分别顺时针旋转30度则在w3c坐标系的基础上旋转了60度

相关推荐
晗夜未央2 小时前
任务队列反复失败,先分清重试、阻塞和结果待核对
开发语言·javascript
jktantan2 小时前
每个节点 41 字节:把一棵百万节点树拆进 14 个 typed array
前端·javascript·vue.js·算法·typescript
我命由我123453 小时前
访客系统形式(有用户概念、无用户概念)
java·开发语言·前端·javascript·python·产品运营·产品经理
程序员大阳4 小时前
副队长JavaScript教程(65)-详解JSON:轻量级数据交换格式
javascript·json·序列化·反序列化·stringify·parse
paopaokaka_luck5 小时前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts
栀椩5 小时前
Electron 内嵌页面跨域问题(CORS/PNA)解决全记录
前端·javascript·electron
SEO_juper6 小时前
Chrome 扩展一键查看当前页面 SEO 信息:不用切页面,点一下全出来
前端·javascript·chrome
Highcharts.js6 小时前
CSUN 2026|Highcharts无障碍数据与AI分享
javascript·人工智能·数据分析·highcharts·图表开发
系统集成-鹰翔6 小时前
ERP推单数据库怎么备份:SQLite WAL模式下只复制db文件为什么可能漏任务
javascript·数据库·经验分享·后端
小大宇7 小时前
Vue知识点-ElementPlus-05 输入框
前端·javascript·vue.js