无处不在的前端矩阵变换(上)

简介: 在前端开发中不论CSS3也好,SVG也好,还是Canvas,无论多复杂的图形,都是由一个个点组成的。一个元素渲染后就可以得到一张位图,然后对这个位图上每一点进行变换,就可以得到新的一张位图,从而产生了视觉上的平移translate、旋转rotate、缩放scale、拉伸skew 等效果。这一切都是变换矩阵的功劳。

2d与3d矩阵变换公式



CSS3中的2d矩阵变换


  • CSS3中的 transform: translate(tx, ty) 等价于 transform: matrix(1,0,0,1,tx,ty)


  • CSS3中的 transform:rotate(θ) 等价于 transform: matrix(cosθ,sinθ,-sinθ,cosθ,0,0)


  • CSS3中的 transform: scale(Sx, Sy) 等价于 transform: matrix(Sx,0,0,Sy,0,0)


  • CSS 3中的 transform: skew(θx,θy) 等价于 transform:matrix(tan(θx),0,0,tan(θy),0,0)


CSS3中的3d矩阵变换


给个简单的demo,利用CSS3动画库 bounce.js 通过设置元素属性 transform:matrix3d (1-16位参数值) 让元素偏移 200px。 从matrix三阶矩阵到matrix3d四阶矩阵,本质上很多东西都与2D大同小异,只是复杂度不一样而已。


<!--dom-->
<div class="animation-target"></div>
<!--css代码-->
.animation-target {
  background-color: #333;
  height: 100px;
  width: 100px;
}
<!--js代码-->
let bounce = new Bounce();
bounce.translate({
  from: { x: 0 },
  to: { x: 200 }
})
bounce.applyTo(document.querySelector('.animation-target'))
/*
   bounce.js 其余scale、rotate、skew等api最终都是通过transform:matrix3d(1-16位参数值)来实现元素的动画效果
*/


效果图如下:matrix3d对应的矩阵运算细节可参考 bounce.js



svg中的矩阵变换


svg中的变换原理和css3中的类似,但是在svg中没有相关的属性来设置变换的中心点,只能通过translate来模拟。如下设置transform-origin是不生效的


<!--dom-->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100" height="190">
   <rect id="SvgjsRect1008" width="100" height="100" transform-origin="0% 0%" transform="translate(100, 0)"></rect>
</svg>
/*
   transform-origin="0% 0%" 设置是不生效的
*/


下面结合SVG.js 这个开源库来看下svg中的矩阵变换应用


<!--dom 作为SVG.js的挂载节点-->
<div id="drawing"></div>
<!--js-->
let draw = SVG('drawing').size(300, 300)
let rect = draw.rect(100, 100)
rect.rotate(45)  // 旋转45度


如图:



那么rect.rotate(45) 是怎么变成 上图中的 matrix 的呢? 如下:


<!--SVG.js 中的关键代码截取-->
rect.rotate(45)
=>
rotate: function(d, cx, cy) {
 return this.transform({ rotation: d, cx: cx, cy: cy })
}
transform: function(o, relative) {
 var target = this, matrix; // this 通过SVG.js new 出的一个react实例对象 
 matrix = new SVG.Matrix(target) // 获取当前元素的transform: matrix矩阵值,具体实现可以查阅SVG.js源码
 ... 此处省略部分代码
 ensureCentre(o, target)  // 通过svg原生api, element.node.getBBox()来计算元素的中心点o
  // 应用矩阵
  matrix = relative ? 
    // relative
    matrix.rotate(o.rotation, o.cx, o.cy) :
    // absolute
    matrix.rotate(o.rotation - matrix.extract().rotation, o.cx, o.cy)
}
rotate: function(r, cx, cy) {
  // convert degrees to radians
  r = SVG.utils.radians(r)
  // 计算对应的旋转矩阵, 对应a,b,c,d,e,f值如下
  return this.around(cx, cy, new SVG.Matrix(Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0))
}
// Transform around a center point 以中心点来进行旋转
around: function(cx, cy, matrix) {
 //这里很重要:svg以某个参考点变换时 => 通过先平移translate(cx,cy), 然后transform目标matrix值, 再进行反平移translate(-cx,-cy)
 return this
   .multiply(new SVG.Matrix(1, 0, 0, 1, cx || 0, cy || 0))
   .multiply(matrix)
   .multiply(new SVG.Matrix(1, 0, 0, 1, -cx || 0, -cy || 0))
}
multiply: function(matrix) {
  // 这里是把元素当前的transform: matrix属性值与目标矩阵相乘
  return new SVG.Matrix(this.native().multiply(parseMatrix(matrix).native()))
}
native: function() { 
  // SVG.js 中的矩阵相乘, 利用的是svg元素的原生api, createSVGMatrix()来实现
  // create new matrix
  var matrix = SVG.parser.native.createSVGMatrix()
  // update with current values
  for (var i = abcdef.length - 1; i >= 0; i--)
    matrix[abcdef[i]] = this[abcdef[i]]
  return matrix
}
//最后把最终计算的matrix变换值设置到react元素上就完成了
this.attr('transform', matrix)


相关文章
|
前端开发
无处不在的前端矩阵变换(下)
在前端开发中不论CSS3也好,SVG也好,还是Canvas,无论多复杂的图形,都是由一个个点组成的。一个元素渲染后就可以得到一张位图,然后对这个位图上每一点进行变换,就可以得到新的一张位图,从而产生了视觉上的平移translate、旋转rotate、缩放scale、拉伸skew 等效果。这一切都是变换矩阵的功劳。
|
1月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
131 2
|
1月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
38 0
|
1月前
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。
|
1月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
1月前
|
机器学习/深度学习 弹性计算 自然语言处理
前端大模型应用笔记(二):最新llama3.2小参数版本1B的古董机测试 - 支持128K上下文,表现优异,和移动端更配
llama3.1支持128K上下文,6万字+输入,适用于多种场景。模型能力超出预期,但处理中文时需加中英翻译。测试显示,其英文支持较好,中文则需改进。llama3.2 1B参数量小,适合移动端和资源受限环境,可在阿里云2vCPU和4G ECS上运行。
|
1月前
|
前端开发 算法 测试技术
前端大模型应用笔记(五):大模型基础能力大比拼-计数篇-通义千文 vs 文心一言 vs 智谱 vs 讯飞vsGPT
本文对比测试了通义千文、文心一言、智谱和讯飞等多个国产大模型在处理基础计数问题上的表现,特别是通过链式推理(COT)提示的效果。结果显示,GPTo1-mini、文心一言3.5和讯飞4.0Ultra在首轮测试中表现优秀,而其他模型在COT提示后也能显著提升正确率,唯有讯飞4.0-Lite表现不佳。测试强调了COT在提升模型逻辑推理能力中的重要性,并指出免费版本中智谱GLM较为可靠。
前端大模型应用笔记(五):大模型基础能力大比拼-计数篇-通义千文 vs 文心一言 vs 智谱 vs 讯飞vsGPT
|
2月前
|
SpringCloudAlibaba JavaScript 前端开发
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
分布式组件、nacos注册配置中心、openfegin远程调用、网关gateway、ES6脚本语言规范、vue、elementUI
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
|
3月前
|
存储 前端开发 JavaScript
前端语言串讲 | 青训营笔记
前端语言串讲 | 青训营笔记
41 0
|
5月前
|
JSON 前端开发 JavaScript
前端Ajax、Axios和Fetch的用法和区别笔记
前端Ajax、Axios和Fetch的用法和区别笔记
94 2