当前位置: 首页 > news >正文

tranform知多少

transform是变换,包括旋转rotate、扭曲skew、缩放scale和移动translate,可以改变对象的外形和位置。transform的转换,并不是动态的,而是最终时刻的状态。

transform: rotate | scale | skew | translate | matrix

CSS3中的坐标系如图所示。后续介绍会用上。

(1)rotate

可进行2D或者3D旋转。其中常用的rotate(angle)定义2D旋转,angle定义旋转的角度,正数表示顺时针旋转,负数表示逆时针旋转。

  • 定义
描述
rotate(angle)定义 2D 旋转,在参数中规定角度(正数顺时针、负数逆时针)
rotate3d(x,y,z,angle)定义 3D 旋转
rotateX(angle)定义沿着 X 轴的 3D 旋转
rotateY(angle)定义沿着 Y 轴的 3D 旋转
rotateZ(angle)定义沿着 Z 轴的 3D 旋转
  • 使用方法
div
{
    transform: rotate(30deg);
    -ms-transform: rotate(30deg); /* IE 9 */
    -webkit-transform: rotate(30deg); /* Safari and Chrome */
}
复制代码
  • 效果

(2) scale

scale(x,y)方法让元素可以在x,y轴方向上进行拉伸或缩放。伸缩程度由x,y参数决定。scale的参数如果只有一个,则默认为等比例变化。(例如scale(1.5)代表放大1.5倍)。

  • 定义
描述
scale(x[,y]?)定义 2D 缩放转换
scale3d(x,y,z)定义 3D 缩放转换
scaleX(x)通过设置 X 轴的值来定义缩放转换
scaleY(y)通过设置 Y 轴的值来定义缩放转换
scaleZ(z)通过设置 Z 轴的值来定义 3D 缩放转换
  • 使用方法
div
{
    transform: scale(2,3); /* 标准语法 */
    -ms-transform:scale(2,3); /* IE 9 */
    -webkit-transform: scale(2,3); /* Safari */
}
复制代码
  • 效果

(3) translate

translate(x,y)方法,让元素相对当前位置在x、y方向上偏移给定参数的距离。它是translateX()和translateY()的结合。

  • 定义
描述
translate(x,y)定义 2D 转换
translate3d(x,y,z)定义 3D 转换
translateX(x)定义转换,只是用 X 轴的值
translateY(y)定义转换,只是用 Y 轴的值
translateZ(z)定义 3D 转换,只是用 Z 轴的值
  • 使用方法
div
{
    transform: translate(50px,100px);
    -ms-transform: translate(50px,100px); /* IE 9 */
    -webkit-transform: translate(50px,100px); /* Safari and Chrome */
}
复制代码
  • 效果

Q:tranlateZ(0)为什么可以提高浏览器渲染的性能?

      在这里要特别提出tranlateZ(0),可以利用GPU加速,提高浏览器渲染的性能。为什么translateZ(0)可以提升渲染的性能呢??这得从浏览器的渲染原理说起。

浏览器渲染原理

在从服务器拿到数据后,浏览器会先解析三类东西:

  • 解析html,xhtml,svg这三类文档,形成dom树。
  • 解析css,产生css rule tree。
  • 解析js,js会通过api来操作dom tree和css rule tree。

      解析完成之后,浏览器引擎会通过dom tree和css rule tree来构建rendering tree:

  • rendering tree和dom tree并不完全相同,例如:或display:none的东西就不会放在渲染树中
  • css rule tree主要是完成匹配,并把css rule附加给rendering tree的每个element

      在渲染树构建完成后,

  • 浏览器会对这些元素进行定位和布局,这一步也叫做reflow(回流)或者layout
  • 浏览器绘制这些元素的样式,颜色,背景,大小及边框等,这一步也叫做repaint(重绘)
  • 然后浏览器会将各层的信息发送给GPU,GPU会将各层合成;显示在屏幕上

即渲染树构建完成后,浏览器要做的步骤是: reflow ---> repaint ---> composite

reflow和repaint都是耗费浏览器性能的操作,为了仅发生composite,我们做动画的css property必须满足以下三个条件:

  1. 不影响文档流。
  2. 不依赖文档流。
  3. 不会造成重绘。

满足以上以上条件的css property只有transform和opacity。

这样做有两个优势:

  1. 动画将会非常流畅
  2. 动画不在绑定到CPU,即使js执行大量的工作;动画依然流畅。

GPU有2个问题:

  1. 一个或多个没有自己复合层的元素要出现在有复合层元素的上方,它就会拥有自己的复合层;这种情况被称为隐式合成。
  2. 使用GPU动画需要发送多张渲染层的图像给GPU,GPU也需要缓存它们以便于后续动画的使用。

所以——

  • 保持动画的对象的z-index尽可能的高。理想的,这些元素应该是body元素的直接子元素。当然,这不是总可能的。所以你可以克隆一个元素,把它放在body元素下仅仅是为了做动画。

  • 将元素上设置will-change CSS属性,元素上有了这个属性,浏览器会提升这个元素成为一个复合层(不是总是)。这样动画就可以平滑的开始和结束。但是不要滥用这个属性,否则会大大增加内存消耗。

tranlateZ(0)为什么可以提高浏览器渲染的性能?

这个问题是因为使用transform和opacity做CSS动画的时候,会将元素提升为一个复合层;而使用js操作css属性做动画时,必须使用translateZ或will-change才能将元素强行提升至一个复合层。

元素本身使用transform和opacity做CSS动画的时候,会提前告诉GPU动画如何开始和结束及所需要的指令;所以会创建一个复合层(渲染层),并把页面所有的复合层发送给GPU;作为图像缓存,然后动画的发生仅仅是复合层间相对移动。当元素使用css动画时,在控制台中的layers可以看到,会有两个layer。

而使用js做动画,js必须在动画的每一帧计算元素的状态;发送给GPU,但不会将元素提升至一个复合层;所以想让元素提升至一个复合层,必须使用translateZ或will-change: transform, opacity。当我们使用js动画时,在控制台,可以看到只有一个layer,添加translateZ(0)的时候,可以看到又有两个layer了。

简而言之,是因为transform不会触发repaint,而是会创建composited layer, GPU会来执行transform的操作,将浏览器的渲染过程交给GPU处理,而不是使用自带的比较慢的渲染器。

原文出自本人博客:常用的CSS小技巧(二)

转载于:https://juejin.im/post/5b6ebf3be51d4535253b6729

相关文章:

  • Android酷炫实用的开源框架(UI框架)
  • Binder总结篇1-Binder原理
  • malloc()函数(Linux程序员手册)及函数的正确使用【转】
  • ListBean 排序
  • HYPER-V的安装和双机调试的配置(一)
  • java核心技术读书笔记
  • Android 9.0新特性
  • JS中逻辑运算符中 == 的问题
  • Apache2.2.x版本不支持PFS,无法通过ATS的问题
  • 惰性计算辨析
  • 洛谷P4016 负载平衡问题(费用流)
  • JavaWeb-JSPELJSTL
  • list、dict、str虽然是Iterable,却不是Iterator
  • jQuery(一)
  • C# 中类和结构的区别
  • 分享一款快速APP功能测试工具
  • [译] React v16.8: 含有Hooks的版本
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【Amaple教程】5. 插件
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • Apache的80端口被占用以及访问时报错403
  • cookie和session
  • eclipse的离线汉化
  • HashMap ConcurrentHashMap
  • Phpstorm怎样批量删除空行?
  • Redux系列x:源码分析
  • scrapy学习之路4(itemloder的使用)
  • 和 || 运算
  • 后端_MYSQL
  • 收藏好这篇,别再只说“数据劫持”了
  • 小程序开发中的那些坑
  • 以太坊客户端Geth命令参数详解
  • 在Unity中实现一个简单的消息管理器
  • 我们雇佣了一只大猴子...
  • #Linux(权限管理)
  • #stm32整理(一)flash读写
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (¥1011)-(一千零一拾一元整)输出
  • (52)只出现一次的数字III
  • (WSI分类)WSI分类文献小综述 2024
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (利用IDEA+Maven)定制属于自己的jar包
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (四)图像的%2线性拉伸
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • *1 计算机基础和操作系统基础及几大协议
  • .form文件_一篇文章学会文件上传
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .NET Remoting学习笔记(三)信道