前端——正儿八经的CSS动画实战向(四)

写在开头:目前对于对于前端整个行业来说,数据可视化的概念越来越宽泛了。用户以及PM的追求与重心也开始逐步从功能上面的强大,偏向到页面是否足够美观,使用是否足够“无摩擦”等方方面面。这个时候,本被认为仅做点缀使用的CSS,也开始逐步发力。在高效便易的条件下,展现着他独有的魅力

CSS3的新成员:动画属性

本人没有经历过用js写简单动画的时代,但是能够“放过”dom元素,仅在CSS上添加属性,便能够实现简单动画效果这一特性,还是很值得大家去讨论和研究的。在经过一定的实践和总结,以及查阅了不少的资料的前提下,开始我们本篇文章中CSS动画之旅吧。

CSS3中的动画特性,可以分为两类:

  • transition(过渡):仅有起始节点、与结束节点。含有四个属性,分别为CSS属性(默认all)、花费时间(默认0)、效果曲线(默认ease)、延迟时间(默认0);看到这四个属性,相信很多人脑袋里就会产生很多的疑惑,例如变化的属性值在在哪里?是怎样触发这个过渡效果的?这一系列问题,稍后都会一一说明
  • animation(动画):可以自定义多个时间节点,即状态内容。较transition属性而言,其包含了多达六种属性:keyframe 名称(默认none)、花费时间(默认0)、效果曲线(默认ease)、延迟时间(默认0)、播放次数(默认1)、动画方向(默认normal)。更为复杂的状态内容及属性,也就早就了animation更为广泛的实际用途。在深入了解之前,我们再来一张对比表格加深各熟悉的记忆。
transition属性描述animation属性描述
transition-propertyCSS属性(默认all)animation-namekeyframe名称(默认none)
transition-duration花费时间(默认0)animation-duration花费时间(默认0)
transition-timing-function效果曲线(默认ease)animation-timing-function效果曲线(默认ease)
transition-delay延迟时间(默认0)animation-delay延迟时间(默认0)
animation-iteration-count播放次数(默认1)
animation-direction动画方向(默认normal)

通过上述描述及表格中的对比,虽然你可能还不知道transition和animation的具体应用场景,但是对于两者的属性以及差异化应该能有一个很清晰的认识了。接下来,我们就开始更深层次的去了解transition与animation的特性了。

transition(过渡)我们至少要明确以下几点:

  1. 根据属性默认值,对于transition属性而言,我们至少需要设置一个花费时间,如:transition:1s。
  2. 需要一个触发事件,这个事件可以是鼠标悬浮、鼠标点击、焦点获取等等~
  3. 根据表格中与animation属性对比,我们可以了解到transition属于一次性,若想要重复动画效果,需要反复地触发其事件。且只含有开始时间节点与结束时间节点,仅能实现一个状态到另一个状态的转变,这也是其过渡的本质(注:并不是指只能实现一种CSS属性的变化,其实从默认值为all即可看出,所以阮一峰老师对于这里的理解应该是有些误差的,这也导致了有些copyer中也出现了“一条transition规则,只能定义一个属性的变化,不能涉及多个属性”这种结论)
  4. 由于第二点(需事件触发),所以我们还需要注意的是元素的重叠问题,需要触发的事件元素的层级必须要高于其重叠元素的。
  5. 在transition-property属性中,并不是所有的CSS属性都支持transition的,最常用的便是display属性,虽然事件是可以触发的,但是其过渡效果并没有实现。还有能够在实用场景下无法触发的,应该就是background-image属性了。其实这也很好理解,让我们把他和第六点放在一起进行形象解读。
  6. 对于触发事件当中的属性值,我们需要一个能够让浏览器可以明白的参数,而由于auto这个参数的独特性(在position遇到他时,也是会遇到位置问题,详情可见第三篇CSS布局里面定位布局)也是会导致transition无效。现在再结合第五点,可以简单的解释为无过渡状态情况的CSS属性,即会导致transition无效,其实animation在这一点上可以是一样的。
  7. 需要注意隐式过渡的情况出现,即虽然过渡属性中无该CSS属性,但由于继承或者其他关联原因,该属性依然也会有过渡状态的发生。接下来我们可以用一个?结合其他几点来进行实践说明。

html代码:

<div class="demo">
  关于transition的过渡属性,我们常用的“搭配”CSS属性有以下这些:
  width、height、background-color、opacity、margin、padding、box-shadow、text-shadow、transfrom当中的属性等等。
  这些都会显示在同一个?中,但是由于本人不擅长gif图制作,具体效果还是只有大家自行再运行一下代码。
</div>
复制代码

CSS代码:

.demo {
  width: 300px;
  margin: 0 auto;
  background-color: aqua;
  border: 1em solid; //em继承了元素字体的大小,代表倍数,会出现隐式过渡
  min-height: 300px;//rem则是继承的根元素,因为rem对于连锁反应的影响较小,所以应用较em更广泛
  transition: 2s;
  position: relative;
  &:hover{
    transform: translateX(-20px);//transform包含了不少的属性
    transform: rotate(30deg);//只要是属性不同,不会造成覆盖现象
    margin-top: 10px;
    font-size: 24px;
    box-shadow: 10px 0 10px -8px, -10px 0 10px -8px;//阴影的尺寸可以为负值,box阴影属性下一篇文章会有详解
    text-shadow: 1px 1px 1px #000,-1px -1px 1px #fff;//凹凸文字,下一篇CSS技巧篇文章会有详解
  }
  &::before {
    content: "";
    position: absolute;//在不确定“父元素”大小的前提下,使用定位布局,来设置伪元素大小
    top: 0;//伪元素不会出现在dom树当中,所以常见的百分比大小设置是无效的。
    bottom: 0;
    left: 0;
    right: 0;
    background-color: rgba(255, 255, 255, 0.3);
    transform: scale(0, 1);
    transition: .6s;
  }
  &:hover::before {//顺便在这里将伪元素与伪类结合使用
    transform: scale(1,1);//虽然scale(1,1)与scale(1)效果类似,但是建议使用正规写法
  }
}
复制代码

说完transition(过渡),我们再说回到animation(动画)。若是上面的所有内容都已经了解了个七七八八,那么对于可以被看做是复杂版transition的animation应该有大体上有了个初印象了。不多废话,直接总结其概念。

  1. 先说说animation-name这一属性,可以简单的与之transition-property(CSS属性)相对应,只不过对于transition-property来说默认值是all,绝大部分时候我们都是可以省略不写的,但是对于animation-name(默认为none)该属性来说,是必须进行说明的。
  2. 既然对于animation来说,animation-name是必选熟悉,那么我们就更应该较深入地去了解一下keyframes这一规则。对于这一规则来说,我们至少需要知道规则名称(帧列表的名称)、开始(0%或from)及结束(100%或to)时的节点状态、中间状态(可选)
  3. 作为transition的增强版,animation不仅在状态变化的数量上有所增加,对于其执行机制也有着本质性的不同,并不强制需要一个事件去触发,这也就意味着,在用户打开网页的第一时间,即可看到一个较为复杂炫酷的动画效果。(其实transition对于起始页面也可以通过一些奇淫技巧,例如自动获取焦点事件来触发过渡效果,但不是很建议这样使用)
  4. 对比animation包含的属性默认值,我们可以很清晰的理解到,想要实现animation要表达的效果,至少需要两个属性,(1)animation-name(2)animation-duration。所以其最简洁的写法便是animation:demo 1s;
  5. 通过上述表格对比,我们可以发现除了在状态与执行机制方面,animation比之transition来说还多出了两个属性来,分别是animation-iteration-count(播放次数)、animation-direction(动画方向)。其中animation-iteration-count可选的属性值为n(数值)或infinite(无限次);animation-direction可选属性值为normal或alternate(轮流反向播放)
  6. 与transition相同,对于压根就没有过度状态或者很难去计算过度状态的CSS属性,animation也无法对其产生动画作用,例如display、background-image、margin中的auto值。
  7. 同样的animation也是会涉及到隐式动画这一概念的,对于某些继承或者关联元素来说,我们在使用animation属性的时候,一定要多加注意。
  8. 对于较为属性animation这一CSS3特性的人来说,是不是在看到这里后会有种怪怪的东西,总觉得少了些什么一样。甚至可能有人会直接嘀咕着animation不是包含有八种属性吗?没错,其实除了之前讲到的六种属性,对于部分浏览器来说还支持了animation的其余两种属性animation-fill-modeanimation-play-state。由于其还处于实验当中,且兼容性还不算明朗,就不多说了,其实对于animation-fill-mode:forwards在实际应用当中算是比较常见的。

好了,总结了这么一大堆,我们直接上代码来看一下,仍然没有效果图,通过理解和领悟后,可自行编写或者copy运行查看。

html代码:

<div class="demo">
  <div class="demo-top">
    其实animation可以做出许多炫酷的效果来的,但是因为是只是个demo演示,且没有那么多的素材
    所以该?,只是在transition的基础上稍稍复杂了些许的比较常见的动画效果,其实只要熟练了该用法,
    在真正遇到需求的时候,自然有机会去编写自己想要的炫酷动画的。
  </div>
  <div class="demo-bottom">
    <div class="demo1 demo0"></div>
    <div class="demo2 demo0"></div>
    <div class="demo3 demo0"></div>
    <div class="demo4 demo0"></div>
    <div class="demo5 demo0"></div>
    <div class="demo6 demo0"></div>
  </div>
</div>
复制代码

CSS代码:

.demo {
  margin: 0 auto;
  width: 600px;
  .demo-top {
    font-size: 24px;
    width: 100%;
    -webkit-text-stroke: 1px; //虽然必须加上webkit引擎(webkit内核)前缀,但是除IE外的主流浏览器,
    //都是可以识别的仅有细微差别,实现效果为镂空文字,样式还算美观
    -webkit-text-fill-color: transparent; 
    text-shadow: 1px 1px 5px; 
    //color:initial即可(关于initial后面技巧篇也会有说明)
  }
  .demo-bottom {
    height: 400px; //给一个外层div,便于伪类选择器的使用
    background-color: #ccc;
    //如果父元素设置了3D转换属性,由于2D平面背景颜色的缘故,可能会造成截断现象
    display: flex;
    transform-style: preserve-3d;//不过反之,我们也可以利用截断现象,实现意想不到的动画效果
    .demo0 {
      width: 100px;
      height: 100%;
      &:nth-child(1) {
        //一般来说实际开发当中,是不建议使用伪类选择器的。
        background-color: aquamarine; //伪类选择器、无论是在性能还是在复用性上都不是最优解
      }
      &:nth-child(2) {
        //但是是有例外,具体需求具体解决方法
        background-color: blanchedalmond;
      }
      &:nth-child(3) {
        background-color: blueviolet;
      }
      &:nth-child(4) {
        background-color: aqua;
      }
      &:nth-child(5) {
        background-color: red;
      }
      &:nth-child(6) {
        background-color: blue;
      }
    }
    &:hover {
      // perspective: 400px;//透视属性对于3D效果实现还是比较有必要的
      //设置透视属性(perspective)而实现方式上其实也是有两种写法的,并且这两种写法下有不小的区别。
      .demo0 {
        transform: perspective(400px);
        //如果是给当前元素设置透视属性,则是以当前元素为“视点”实现3D效果
        animation: animate-demo 1s;//为了避免覆盖现象,统一的animation属性设置,最好是写在最前面
      }
      .demo1 {
        animation-delay: 0s;
        //如果给父元素设置透视属性,则是以整个父元素为“视点”实现3D效果的;
      }
      .demo2 {
        animation-delay: 0.2s; //当然具体需求具体实现,比如我想要实现的就是一个类似手风琴的动画
      }
      .demo3 {
        animation-delay: 0.4s; //为了保证每一片手风琴的叶片都能有独立效果,所以我采用的就是单个元素透视属性
      }
      .demo4 {
        animation-delay: 0.6s;
      }
      .demo5 {
        animation-delay: 0.8s;
      }
      .demo6 {
        animation-delay: 1s;
      }
    }
  }
}
@keyframes animate-demo {
  form {
    transform: rotateY(0deg);
  }
  to {
    transform: rotateY(180deg);
  }
}
复制代码

虽然不是什么复杂炫酷的?,但是我相信这些已经足够平时的日常使用了。代码中也较为详细的说明了3D效果的实现。但是本人还是再将可能会搞混的、出场次数且算是最多的transform(转换)属性进行一次总结。

  1. 首先transform包含的属性相当的多,如果一一进行说明,还是挺不现实的。在实战向当中,本人以2D动画与3D动画效果进行区分来进行简单总结。
  2. 2D动画效果上面,我们先来看下平面放大及缩小的熟悉:transform:scaleX(n)、transform:scaleY(n)依次分别为平面X轴和Y轴的放大倍数。若双边皆有页面空隙,则是以元素中心点来放大倍数,若是其中一边贴近了页面边际,就会出现一些小“BUG”,所以一定要注意使用场景。当然综合使用transform:scale(n,n)也是可以的。
  3. 2D动画效果上面,我们再来看下平面上面元素的移动情况:transform:translateX(x)、transform:translateY(x),依次分别为平面沿X轴及Y轴的移动情况,x可为负值,为负值时则向左、向上移动(这两个方向移动并不会出现滚动条),正值时向右、向下移动。当然也是可以综合使用transform:translate(x,x)。
  4. 2D动画效果上面,我们最后再看下平面上面元素的旋转情况:绝大部分情况下,transform:rotate(angle)与transform:rotateZ(angle)效果类似。
  5. 最后我们再来看一下3D动画效果,一部分属性是需要作用在父元素上面的,例如:perspective(透视属性很是必要的3D实现属性)、perspective-origin(透视或者说视点属性“原点”)、transform-style: preserve-3d(3D样式转换)、backface-visibility:hidden(层级屏蔽)
  6. 3D动画效果,需要作用在当前元素上面的,transform:perspective(n)(透视属性,与作用在父元素的区别,以在上面?的代码注释中进行说明了),transform:rotateX(angle)(沿透视原点的X轴进行3D旋转),ransform:rotateY(angle)(沿透视原点的Y轴进行3D旋转)
  7. 最后,CSS动画如果深究的话,不夸张地说,恐怕可以写半本小书了,所以更多的内容详解,还是建议个人实践及多做思考为好

最后说两句,前端个人认为可以大致分为两个方面。一、数据可视化,二、业务逻辑功能实现。虽然看似只有只有这两个方面,但是本篇文章所讲述的,仅仅是数据可视化当中的一小部分:CSS动画实现。且这短短篇幅,只来得及简单介绍了CSS动画罢了。学海无涯、各位前端工程师共勉吧。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值