专栏首页偏前端工程师的驿站CSS魔法堂:更丰富的前端动效by CSS Animation
原创

CSS魔法堂:更丰富的前端动效by CSS Animation

前言

 在《CSS魔法堂:Transition就这么好玩》中我们了解到对于简单的补间动画,我们可以通过transition实现。那到底多简单的动画适合用transtion来实现呢?答案就是——我们只需定义动画起始和结束帧的状态的动画。一旦关键帧数大于2时,我们必须转向CSS Animation了。本文为这段时间学习的记录,欢迎拍砖。

简单粗暴介绍CSS Animation 规则和属性

定义关键帧动画

语法:

@keyframes <Animation Name> {

  [<Animation Time Offset> {

    /\* CSS Properties \*/

  }]\*

}

示例:

@keyframes rotate {

  from { transform: rotate(0deg); }

  to { transform: rotate(360deg); }

}

**注意项:**

1.<Animation Name>的命名规范

// 命名需要遵循以下规则

const rIsInvalid = /^--|^[0-9]+-|^(?:unset|initial|inherit|none)$/

    , rIsValid = /^[0-9a-z-\_\\]+$/i

function isValidAnimationName(animationName: string): boolean{

  return !rIsInvalid.test(animationName) && rIsValid(animationName)

}

2.<Animation Time Offset>取值

0-100%from,等价与0%to,等价与100%

3.<Animation Name>重复怎么办

@keyframes CSS规则不支持层叠样式,因此当出现多个同名keyframes,那么仅最后出现的那个有效。

/\* 无效 \*/

@keyframes rotate {

  from { transform: rotate(0deg); }

  to { transform: rotate(360deg); }

}

/\* 生效 \*/

@keyframes rotate {

  from { transform: rotate(90deg); }

  to { transform: rotate(-360deg); }

}

4.<Animation Time Offset>重复怎么办

与@keyframes CSS规则一样,标准规定相同的关键帧不产生层叠,仅最后出现的认定为有效。

但实际上FireFox14+和Chrome均将关键帧设计为可层叠的。

@keyframes rotate {

  from { transform: rotate(0deg); }

  from { background: red; }

  /\* 上述两条time offset实际上等价于

   \* from { transform: rotate(0deg); background: red; }

   \*/

  to {

    transform: rotate(360deg);

    background: yellow;

  }

}

5.!important导致属性失效

一般情况下使用!important会让CSS属性获得最高权重,但在@keyframes下却会导致该CSS属性失效。

@keyframes rotate {

  from {

    transform: rotate(90deg);

    background: red!important; /\* background属性无效 \*/

  }

  to { transform: rotate(-360deg); }

}

6.必须提供至少两个关键帧

/\* 不会根据缓动函数产生动画效果,而是在动画持续时间的最后瞬间移动过去 \*/

@keyframes move-left{

   to {

       left: 100px;

   }

}

使用动画

<css-selector> {

  animation: <animation-name>

             <animation-duration>

             <animation-timing-function>

             <animation-delay>

             <animation-iteration-count>

             <animation-direction>

             <animation-fill-mode>

             <animation-play-state>;

}

示例:

.box.rotate {

  animation: rotate 10s infinite alternate;

}

子属性介绍

<animation-name>,指定通过@keyframes定义的补间动画名称。

<animation-duration>,动画持续时长,默认为0s。单位为s和ms。

<animation-delay>,动画播放延迟,默认为0s。单位为s和ms。

<animation-iteration-count>,动画重复播放次数,默认为1,infinite表示无限循环。动画播放总时长为<animation-duration>\*<animation-iteration-count>

<animation-direction>,可选值为normal | reverse | alternate | alternate-reverse,分别表示动画播放顺序是从from到to从to到from从from到to再从to到from从to到from再从from到to。**注意:设置alternate|alternate-reverse时,animation-iteration-count必须大于1才能看到效果**

<animation-fill-mode>,可选值为none | forwards | backwards | both,用于设置动画开始前和结束后是否应用0%100%的样式对元素上。分别表示不应用应用100%的样式延迟播放期间应用0%的样式0%和100%的样式均应用

**注意:**

  1. 默认情况下(none),动画结束后会恢复动画前的样式;
  2. 设置backwards时,<animation-delay>值大于0才能看到效果。

<animation-play-state>,可选值running | paused,获取和设置播放状态。**注意:通过这个属性,我们仅能实现暂停和继续播放的效果,无法实现重播,更别说回放了**

<animation-timing-function>,用于设置缓动函数类型,值为ease | ease-in | ease-out | ease-in-out | linear | step-start | step-end | steps(<integer>, <flag>) | frames(<integer>) | cubic-bezier(<number>,<number>,<number>,<number>)

其中ease | ease-in | ease-out | ease-in-out | linear | cubic-bezier(<number>,<number>,<number>,<number>)的效果均为连续渐变的,而step-start | step-end | steps(<integer>, <flag>) | frames(<integer>)则为突变效果。下面我们深入理解后者吧。

缓动函数-step解疑专题

step-start实际上等价于steps(10, start),而step-end则等价于steps(10),所以我们只要理解好steps(<integer>, <flag>)即可。

/\* 通过设置在一个动画周期内(<animation-duration>)的平均刷新帧数,实现突变动效。具体应用有:游戏精灵行走、打字效果等

 \* <number\_of\_steps> - 两个关键帧间的刷新次数

 \* <direction> - 方向,可选值为 end | start。

 \*               end为默认值,表示动画一结束,动画效果就结束;

 \*               start表示动画一开始就马上执行完第一个关键帧的效果。

 \*/

steps(<number\_of\_steps>, <direction>)

从张旭鑫那偷来的解释:

start:表示直接开始。也就是时间才开始,就已经执行了一个距离段。于是,动画执行的5个分段点是下面这5个,起始点被忽略,因为时间一开始直接就到了第二个点:

end:表示戛然而止。也就是时间一结束,当前距离位移就停止。于是,动画执行的5个分段点是下面这5个,结束点被忽略,因为等要执行结束点的时候已经没时间了:

另外通过将<animation-fill-mode>设置为forwards,那么当<direciton>设置为end时,也会显示(保持)动画最后一个关键帧的样式。

事件

const target = document.getElementById("target")

target.addEventListener("animationstart", e => {

  // 动画开始时触发

})

target.addEventListener("animationiteration", e => {

  // 每次重复执行动画时触发

  // 当<animation-iteration-count>为1时,不会触发。

})

target.addEventListener("animationend", e => {

  // 当动画结束时触发

})

搞尽脑汁实现重播效果

到这里我们已经可以通过@keyframes定义和应用CSS Animation了,但我们能否获取对动画效果更多的控制权呢?如开始、暂停、继续、重播。通过<animation-play-state>我们能轻易实现开始、暂停和继续的效果,但重播却没那么容易。

function pause (target: HTMLElement):boolean {

  const isRunning = target.style.animationPlayState == "running"

  if (isRunning) {

    target.style.animationPlayState = "paused"

  }

  

  return isRunning

}



function play (target: HTMLElement):boolean {

  const isStop = target.style.animationPlayState == "paused"

  if (isStop) {

    target.style.animationPlayState = "running"

  }

  

  return isStop

}



function replay (target: HTMLElement, animationClassName: string):void {

  // 先移除动画效果

  target.classList.remove(animationName)

  // requestAnimationFrame的回调函数会在下一次界面渲染前执行

  requestAnimationFrame(\_ => {

    // 这时动画的影响还在,所以要等界面渲染完后再重新启用动画效果,才能实现重播

    requestAnimationFrame(\_ => {

      target.classList.add(animationName)

    })

  })

}

总结

CSS3为我们提供了动画效果,除了提供比Transition更丰富的可控性,比JavaScript更简易的API,还让我们可以使用GPU来加速呢^_^

尊重原创,转载请注明来自:https://www.cnblogs.com/fsjohnhuang/p/9289618.html ^_^肥仔John

参考

https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes

https://designmodo.com/steps-css-animations/

http://lea.verou.me/2011/09/pure-css3-typing-animation-with-steps/

http://jsfiddle.net/simurai/CGmCe/

https://www.zhangxinxu.com/wordpress/2018/06/css3-animation-steps-step-start-end/

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • CSS魔法堂:更丰富的前端动效by CSS Animation

    ^_^肥仔John
  • CSS3魔法堂:CSS3滤镜及Canvas、SVG和IE滤镜替代方案详解

    一、前言                                  IE特有的滤镜常常作为CSS3各种新特性的降级处理补充,而Adobe转向HTML5后...

    ^_^肥仔John
  • Vim杂记:Sublime的配色方案

    一、前言                                       爱美之心人皆有之,sublime的配色实在好看,于是希望Vim也能这样。 ...

    ^_^肥仔John
  • CSS魔法堂:更丰富的前端动效by CSS Animation

    ^_^肥仔John
  • CSS3实现loading点点点动画效果

    利用CSS content内容生成技术以及CSS3 animation实现的,并且几乎没有任何的不足,这里给大家展示下如何实现的。

    javascript.shop
  • Android高级动画(4)完结篇目录回顾封装库总结

    Android高级动画(1)http://www.jianshu.com/p/48554844a2db Android高级动画(2)http://www.ji...

    大公爵
  • 系统集成模式介绍

    在当今的mashup-driven(混搭驱动)的世界中,使用集成来提取、转换和利用数据是大多数软件工程师的首要任务。理解经过验证的集成模式很重要,它可以帮助简化...

    程序你好
  • 使用LinqToExcel读取Excel

    我们读取和写入Excel 经常使用NPOI工具,如果我们的需求只是需要读取Excel,可以考虑使用LinqToExcel这个组件。这个组件用起来简单,实用,操作...

    张善友
  • 虚拟主机怎么挑选?

    选择虚拟主机建网站,预装了网站应用环境就和数据库环境,提供可视化操作的控制面板环境,操作简单。所以,很多站长和企业现在还是会首先使用虚拟主机。在挑选时,要注意以...

    用户6049522
  • 面对手机游戏,男女习惯大不同–信息图

    在传统印象里,女性玩家无疑属于稀有动物,即使在网游大行其道之后这个观念也只是稍有改观。如今,许多数据调查机构的报告却显示,随着手机游戏的日益崛起,女性玩家在游戏...

    小莹莹

扫码关注云+社区

领取腾讯云代金券