你所不知道的 css 动画技巧与细节 -pg电子游戏网站

0顶
0踩

你所不知道的 css 动画技巧与细节

2017-09-19 14:00 by 副主编 jihong10102006 评论(0) 有14700人浏览
css
怕标题起的有点大,下述技巧如果你已经掌握了看看就好,欢迎斧正,本文希望通过介绍一些 css 不太常用的技巧,辅以一些实践,让读者可以更加深入的理解掌握 css 动画。

废话少说,直接进入正题,本文提到的动画不加特殊说明,皆指 css 动画。

正负旋转相消

嗯。名字起的很奇怪,好像数学概念一样。

在动画中,旋转是非常常用的属性,
{
  transform: rotate(90deg);
}

那旋转有一些什么高级点的技巧呢?当然是可以改变 transfrom-origin ,改变旋转中心点啦。


开个玩笑,改变旋转中心点这个估计大家都知道了,这里要介绍的技巧是利用父级元素正反两个方向的旋转,来制作一些酷炫的 3d 效果。

首先假设一下场景,我们有这样的一层 html 结构:
正负旋转相消3d动画

样式如下:

.content 内是我们的主要内容,好了,现在想象一下,如果祖先元素 .rotate 进行正向 linear 360° 旋转,父级元素 .reverserotate 进行反向 linear 360° 旋转,效果回是啥样?
.rotate {
    animation: rotate 5s linear infinite; 
}
.reverserotate {
    animation: reverserotate 5s linear infinite; 
}
@keyframes rotate {
    100% {
        transform: rotate(360deg);
    }
}
@keyframes reverserotate {
    100% {
        transform: rotate(-360deg);
    }
}

神奇!因为一正一反的旋转,且缓动函数一样,所以整个 content 看上去依然是静止的!注意,这里整个 content 静止的非常重要。

有读者看到这里就要骂街了,作者你个智障,静止了不就没动画了吗?哪来的动画技巧?

别急,虽然看上去是静止的,但是其实祖先两个元素都是在旋转的!这会看上去风平浪静的效果底下其实是暗流涌动。用开发者工具选取最外层祖先元素是这样的:

既然如此,我们继续思考,如果我在其中旋转的一个祖先元素上,添加一些别的动画会是什么效果?想想就很刺激啊。

为了和文案里面的 3d 动画扯上关系,我们先给这几个元素添加 3d 转换:
div {
    transform-style: preserve-3d;
    perspective: 500px;
}

接着,尝试修改上面的旋转动画,在内层旋转上额外添加一个 rotatex:
@keyframes rotate {
    0% {
        transform: rotatex(0deg) rotatez(0deg);
    }
    50% {
        transform: rotatex(40deg) rotatez(180deg);
    }
    100% {
        transform: rotatex(0deg) rotatez(360deg);
    }
}

效果如下:

wow,这里需要好好理解一下。由于内容 content 层是静止的但其实外层两个图层都在旋转,通过设置额外的 rotatex(40deg) ,相当于叠加多了一个动画,由于正反旋转抵消了,所有整个动画只能看到旋转的 rotatex(40deg) 这个动画,产生了上述的效果。



动画相同,缓动不同

好的,继续下一个小技巧。

有的时候我们页面存在一些具有相同动画的元素,为了让动画不那么死板,我们可以给相同的动画,赋予不同的缓动函数,来达到动画效果。

假设我们有如下的结构:

样式如下:

我们给它们相同的动画,但是赋予不一样的缓动函数(animation-timing-function),就像这样:
.ball1 {
    animation: move 1s ease-in infinite alternate;
}
.ball2 {
    animation: move 1s linear infinite alternate;
}
.ball3 {
    animation: move 1s ease-out infinite alternate;
}
@keyframes move {
    100% {
        transform: translatey(5vw);
    }
}

这样,一个简单的 loading 效果就制作好了。(当然这个技巧比较简单,学会合理运用是关键)



奇妙的缓动

缓动函数 timing-function 在动画中占据了非常重要的地位。

当你不想使用 css 默认提供的 linear、ease-in、ease-out 之类缓动函数的,可以自定义 cubic-bezier(1, 1, 0, 0),这里有个非常好用的工具推荐,下面这个网站,可以方便的调出你需要的缓动函数并且拿到对应的 cubic-bezier 。



过渡取消
我们在制作页面的时候,为了让页面更加有交互感,会给按钮,阴影,颜色等样式添加过渡效果,配合 hover 一起使用。

这个是常规思维,如果我们的元素一开始是没有过渡效果,只有 hover 上去才给它添加一个过渡,又或者一开始元素是有过渡效果的,当我们 hover 上去时,取消它的过渡,会碰撞出什么样的火花呢?

使用这个技巧(也许算不上技巧,纯粹好玩),我们可以制作出一些有趣的效果,例如下面这个感觉是利用就 js 才完成的动画,其实是纯 css 动画:

其实就小圆圈是元素默认是带有 transition 的,只有在 hover 上去的时候,取消它的过渡,简单的过程:
  • 由于一开始它的颜色的透明的,而 hover 的时候会赋予它颜色值,但是由于 hover 时过渡被取消了,所有它会直接显示。
  • hover 离开的时候,它的原本的过渡又回来了,这个时候它会从有颜色到透明值缓慢渐变消失。
可以戳这里感受一下:


动画层级的控制,保持动画层级在最上方

这个问题可能有一点难理解。需要了解 css 动画渲染优化的相关知识。

先说结论,动画层级的控制的意思是尽量让需要进行 css 动画的元素的 z-index 保持在页面最上方,避免浏览器创建不必要的图形层(graphicslayer),能够很好的提升渲染性能。

ok,再一次提到了图形层(graphicslayer),这是一个浏览器渲染原理相关的知识(webkit/blink内核下)。

简单来说,浏览器为了提升动画的性能,为了在动画的每一帧的过程中不必每次都重新绘制整个页面。在特定方式下可以触发生成一个合成层,合成层拥有单独的 graphicslayer。

需要进行动画的元素包含在这个合成层之下,这样动画的每一帧只需要去重新绘制这个 graphics layer 即可,从而达到提升动画性能的目的。

那么一个元素什么时候会触发创建一个 graphics layer 层?从目前来说,满足以下任意情况便会创建层:
  • 硬件加速的 iframe 元素(比如 iframe 嵌入的页面中有合成层)
  • 硬件加速的插件,比如 flash 等等
  • 使用加速视频解码的 元素
  • 3d 或者 硬件加速的 2d canvas 元素
  • 3d 或透视变换(perspective、transform) 的 css 属性
  • 对自己的 opacity 做 css 动画或使用一个动画变换的元素
  • 拥有加速 css 过滤器的元素
  • 元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)
  • 元素有一个 z-index 较低且包含一个复合层的兄弟元素
本题中说到的动画层级的控制,原因就在于上面生成层的最后一条:
元素有一个 z-index 较低且包含一个复合层的兄弟元素。

这里是存在坑的地方,首先我们要明确两点:
  • 我们希望我们的动画得到 gpu 硬件加速,所以我们会利用类似 transform: translate3d() 这样的方式生成一个 graphics layer 层。
  • graphics layer 虽好,但不是越多越好,每一帧的渲染内核都会去遍历计算当前所有的 graphics layer ,并计算他们下一帧的重绘区域,所以过量的 graphics layer 计算也会给渲染造成性能影响。
记住这两点之后,回到上面我们说的坑。

假设我们有一个轮播图,有一个 ul 列表,结构如下:
轮播图
  • 列表li
  • 列表li
  • 列表li
  • 列表li

假设给他们定义如下 css:
.swiper {
    position: static;
    animation: 10s move infinite;
}
    
.list {
    position: relative;
}
@keyframes move {
    100% {
        transform: translate3d(10px, 0, 0);
    }
}

由于给 .swiper 添加了 translate3d(10px, 0, 0) 动画,所以它会生成一个 graphics layer,如下图所示,用开发者工具可以打开层的展示,图形外的黄色边框即代表生成了一个独立的复合层,拥有独立的 graphics layer 。

但是!在上面的图中,我们并没有给下面的 list 也添加任何能触发生成 graphics layer 的属性,但是它也同样也有黄色的边框,生成了一个独立的复合层。

原因在于上面那条元素有一个 z-index 较低且包含一个复合层的兄弟元素。我们并不希望 list 元素也生成 graphics layer ,但是由于 css 层级定义原因,下面的 list 的层级高于上面的 swiper,所以它被动的也生成了一个 graphics layer 。

使用 chrome,我们也可以观察到这种层级关系,可以看到 .list 的层级高于 .swiper:

所以,下面我们修改一下 css ,改成:
.swiper {
    position: relative;
    z-index: 100;
}
    
.list {
    position: relative;
}

这里,我们明确使得 .swiper 的层级高于 .list ,再打开开发者工具观察一下:

可以看到,这一次,.list 元素已经没有了黄色外边框,说明此时没有生成 graphics layer 。再看看层级图:

此时,层级关系才是我们希望看到的,.list 元素没有触发生成 graphics layer 。而我们希望需要硬件加速的 .swiper 保持在最上方,每次动画过程中只会独立重绘这部分的区域。

总结

这个坑最早见于张云龙发布的这篇文章,这里还要总结补充的是:
  • gpu 硬件加速也会有坑,当我们希望使用利用类似 transform: translate3d() 这样的方式开启 gpu 硬件加速,一定要注意元素层级的关系,尽量保持让需要进行 css 动画的元素的 z-index 保持在页面最上方。
  • graphics layer 不是越多越好,每一帧的渲染内核都会去遍历计算当前所有的 graphics layer ,并计算他们下一帧的重绘区域,所以过量的 graphics layer 计算也会给渲染造成性能影响。
  • 可以使用 chrome ,用上面介绍的两个工具对自己的页面生成的 graphics layer 和元素层级进行观察然后进行相应修改。
  • 上面观察页面层级的 chrome 工具非常吃内存?好像还是一个处于实验室的功能,分析稍微大一点的页面容易直接卡死,所以要多学会使用第一种观察黄色边框的方式查看页面生成的 graphics layer 这种方式。
数字动画
很多技巧单独拿出来可能都显得比较单薄,我觉得最重要的是平时多积累,学会融会贯通,在实际项目中灵活组合运用,最近项目需要一个比较富有科技感的数字计数器,展示在线人数的不断增加。因为是内部需求,没有设计稿,靠前端自由发挥。

运用了上面提到的一些小技巧,参考了一些 codepen 上的效果,整了个下述的 3d 数字计数效果,纯 css 实现,效果图如下:

  • 大小: 47.1 kb
  • 大小: 16.3 kb
  • 大小: 5.4 kb
  • 大小: 41.1 kb
  • 大小: 981.2 kb
  • 大小: 621.2 kb
  • 大小: 600 bytes
  • 大小: 116 kb
  • 大小: 1.5 mb
  • 大小: 69.7 kb
  • 大小: 76.2 kb
  • 大小: 36.5 kb
  • 大小: 14 kb
  • 大小: 32.5 kb
  • 大小: 1.7 mb
来自:
0
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 简单的介绍了一下软件构造中两个比较重要的外部属性:可维护性和可复用性,他们的一些概念。

  • 维护的主要定义是保持或维持特定状态的过程。软件的可维护性由开发人员负责,他们定期修改软件以满足不断变化的客户需求并解决客户提出的问题。软件维护需要增强软件的功能,以包含客户需要的新功能,修改代码以避免将来出现问题,修复代码中的缺陷或错误,并确保不存在安全漏洞。此外,软件维护通常包括发布更新,以提高适应性和有效性,并替换不受欢迎的功能。软件维护在很大程度上受到软件和代码质量的影响。质量较低的软件需要更多的维护。对于低质量软件,增加新需求或扩展现有代码的工作量和成本要高得多。

  • 5.1 metrics and construction principles for maintainability 可维护性的度量与构造原则 1. 可维护性的指标 软件维护的类型:纠错性维护(25%)、适应性维护(21%)、完善性维护(50%)、预防性维护(4%) 可维护性(maintainability)、可扩展性(extensibility)、灵活性(flexibility)、可适应性(adaptability)、可管理性(manageability)、支持性(supportabil...

  • 好的软件总是需要可维护性,那么这究竟需要遵循哪些原则呢? 众所周知,一个好的软件需要有好的可维护性。但是我们构造的软件系统往往有 着许多问题,导致一个软件的可维护性较低的原因有四个: 1.过于僵硬(rigidity):很难在系统中加入新功能。因为会波及其它模块,最后会变成跨越几个模块的大改动。         2.过于脆弱(fragility):与过于僵硬同时存在。对一个地方的修改,往往导致看上去没有什么关系...

  • 什么是可维护的代码 可维护的代码有以下特点: 1、可理解性——其他人可以接手代码并理解它的意图和一般途径,而无需开发人员的完全解释。 2、直观性——代码中的东西一眼就能明白,不管其操作过程多么复杂。 3、可适应性——代码以一种数据上的变化不要求完全重写的方法撰写。 4、可扩展性——在代码架构上已考虑到在未来允许对核心功能进行扩展。 5、可调试性——当有地方出错时,代码可以给予你...

  • 软件可维护性综述 1. 软件维护的目标,任务,分类与特点 软件维护的目标: 通过必要的维护工作使得系统持久的满足用户的需要。 各类维护活动的根本目的是:延长软件生存期 软件维护的分类: 1 )改正性维护;2 )适应性维护; 3 )完善性维护;4 )预防性维护。 改正性维护:是改正在系统开发阶段已发生而系统测试阶段尚未发现的错误。 任务:为了识别和纠正软件错误、改正软件性能上的缺陷、排除实施中的误...

  • 从infoq上面看到的一个讨论,国外的牛人在抱怨nhibernate 2.1的“可维护性”太差,改个东西要牵动全身。接着有人回应,说nhibernate 2.1其实很好维护。争论到最后,就变成了对“可维护性”的定义了,毕竟大家各执一词,可能只是因为标准不同。 原文的链接:[url]http://www.infoq.com/cn/news/2009/08/what-is-maintainabl...

  • 本文介绍软件的可维护性

  • 软件工程中把软件开发大概分了六步:可行性分析、需求分析、设计、编码、测试、运行与维护,在这几大部分中,维护占有重要地位,一般我们不想把大分分精力、财力花费在维护上,这就需要我们提高软件的可维护性。 一个好的程序应该是可理解的、可靠的、可测试...

  • 一.可理解性:可理解性表明人们通过阅读源代码和相关文档,了解程序功能及其如何运行的容易程度。 二.可靠性:可靠性表明一个程序按照用户的要求和设计目标,在给定的一段时间内正确执行的概率。 三.可测试性可测试性表明论证程序正确性的容易程度。程序越简单,证明其正确性就越容易。而且设计合用的测试用例,取决于对程序的全面理解。一个可测试的程序应当是可理解的,可靠的,简单的。用于可

  • - 平时我们在写html、css时会为类的命名耗费脑汁,本文总结了一下平时编码的心得css结构化组织思想 目的是讲用户界面划分为独立的块,即使使用复杂的ui,这也使界面开发变得简单快捷,并且允许重复使用现有的代码,而无需复制和粘贴。 css(块 元素 修饰符) 块所谓的“块”其实就是该dom元素共有的最基本的特性,在其命名上我们可以采取按照其目的来取名(btn或者search-f

  • 论软件的可维护性设计 [摘要] 2008年3月1日至12月20日,我参加了“数据安全访问平台”项目的开发,担任系统分析员的工作。该项目是某行业用户“数据中心二期”建设的主要内容,目标是:建立数据统一访问接口及其使用标准,规范、约束和审计数据应用访问数据库的行为,对数据应用提供强制审计的技术手段。 由于系统交付后,存在较长维护期,同时系统存在升级与扩展的情况,因此本项目对系统的可维护性设计要求较高。...

  •   我的心态变化 第一次接触编程,学习c语言,交换两个数的值:  c = a  a = b  b = c  后来我我从师兄那学到了下面这段代码,觉得写的比我之前的更漂亮: a = a b  b = a - b  a = a - b  最后参加工作了,看到很多别人的代码,最后又觉得最漂亮的代码是这样的:  c = a  a = b  b = c  请问大家,为什么我的...

  • 大多数文章中,我们并未特别注意css文件的可维护与可读性的问题,当完成一项前端的工作之后,许多人都会忘记该项目的结构与细节。然而代码并不是马上就能完全定型,在余下的时间里还有不断的维护工作,而这些工作也许不会是你自己完成。所以,结构优良的代码能很大程度上优化它的可维护性。下面列出四则技巧提高css文件可维护性的方法,以此作为指南,以一种较好的css样式组织习惯来进行web前端开发。 一、c...


  •     一个软件产品在release后就会安装到客户的计算机上去运行,在开发过程中出现程序错误我们可以在自己的电脑中利用丰富的工具定位问题,但是一旦程序到了客户的环境,当运行出现问题时,则不是开发组说想怎么调试就怎么调试了,可能因为生产环境管理制度,也可能是系统内已经存在保密信息,在客户的机器上装个调试器、诊断工具什么的一般是不太可行的,这个时候如果事前缺乏相关设计,则可能陷入一摸黑的境况,没有相关环境信息,无法定位故障原因,就引起客户不满。因此,每个程序在事前都应该有充分的可维护性设计,包括日

  • 平均无故障时间 mttf 可靠性 = mttf/(1 mttf) 无失效运作的概率 平均失效间隔时间 mtbf 可用性 = mtbf/(1 mtbf) 正确运作的概率 平均修复时间 mttr 可维护性 = 1/(1 mttr) 完成维护的概率

  • 可靠性 什么时候需要关注可靠性? 涉及人身安全财产安全的时候 医疗 金融 客户的信息 ,资源等 关注点 ? ...

  • 对于简单的一个for循环,如: for(int i =1; i { //proceeding } 从语法上来讲,上述语句完全没有问题。但是可读性及可扩展性差,为什么呢? 因为使用了100这个具体的值作为循环上届,其意义不明确,i与100比较究竟是什么意义,不知道,所以不方便他人理解你的程序 另一方面,如果程序中有多处这样的100,一旦程序将来发生更改(假设100要改为1000),那么

  • 本文是对软件构造课程软件可维护性相关内容的整理与理解,使用的编程语言为 java。

global site tag (gtag.js) - google analytics
网站地图