首页 > 网页教程 > CSS > CSS动画 VS Web动画API 那个更好?

CSS动画 VS Web动画API 那个更好?

时间:2017-07-12    来源:igeekbar

众所周知,JavaScript有一个原生动画API,叫做Web Animations API。在接下来的文章中,我们将简称为WAAPI。

在本文中,我们将从各个方面来比较WAPPI和CSS中的动画。各位看官可自行判断其中哪个更好,哪个有所欠缺。

WAAPI的基础知识

如果你曾经使用jQuery  .animate(),WAAPI的基本语法应该看起来很熟悉。 

var element = document.querySelector('.animate-me');
element.animate(keyframes, 1000);

animate方法接受两个参数:keyframes和duration。与jQuery不同的是,它不仅具有内置在浏览器中的优点,而且性能也更好。

第一个参数,keyframes应该是一个对象数组。每个对象都是我们动画中的一个keyframe。这是一个简单的例子:

var keyframes = [
  { opacity: 0 },
  { opacity: 1 }
];

第二个参数,duration,是我们想要动画持续多久。在上面的例子中是1000毫秒。我们来看一个更令人兴奋的例子。

#用WAAPI重新创建animista CSS动画

有一些被称为"模糊的幻灯片"入场动画的东西。看起来很可爱。

以下是CSS中的keyframes:

0% {
  transform: translateY(-1000px) scaleY(2.5) scaleX(.2);
  transform-origin: 50% 0;
  filter: blur(40px);
  opacity: 0;
}
100% {
  transform: translateY(0) scaleY(1) scaleX(1);
  transform-origin: 50% 50%;
  filter: blur(0);
  opacity: 1;
}

WAAPI中的代码相同:

var keyframes = [
  { 
    transform: 'translateY(-1000px) scaleY(2.5) scaleX(.2)', 
    transformOrigin: '50% 0', filter: 'blur(40px)', opacity: 0 
  },
  { 
    transform: 'translateY(0) scaleY(1) scaleX(1)',
    transformOrigin: '50% 50%',
    filter: 'blur(0)',
    opacity: 1 
  }
];

我们已经看到将keyframes应用到要动画的任何元素是多么容易:

element.animate(keyframes, 700);

为了简单起见,我只指定了duration。但是,我们可以使用这个第二个参数来传递更多的选项。至少我们也应该指定一个easing。以下是可用选项的完整列表,其中包含一些示例值:

var options = {
  iterations: Infinity,
  iterationStart: 0,
  delay: 0,
  endDelay: 0,
  direction: 'alternate',
  duration: 700,
  fill: 'forwards',
  easing: 'ease-out',
}
element.animate(keyframes, options);

有了这些选项,我们的动画将从头开始,没有任何延迟,循环永远在向前和向后播放。

   点我查看代码以及效果!!!

令人烦恼的是,对于我们熟悉CSS动画的人来说,一些术语与我们习惯的不同。虽然在往正面想,这可以让我们打字稍微快点!

  • 是easing而不是animation-timing-function
  • 是iterations而不是animation-iteration-count。如果我们希望动画永远重复,是Infinity而不是infinite的。有点混乱,无限不是引用。Infinity是一个JavaScript关键字,而其他值是字符串。
  • 我们使用毫秒而不是秒,对于之前编写过许多JavaScript的人来说,这应该是熟悉的。(你可以在CSS动画中使用毫秒数,但很少有人使用。)

当我第一次尝试iterationStart的时候我遇到了问题。为什么要从指定的迭代开始,而不仅仅是减少迭代次数?当你使用十进制数时,此选项非常有用。例如,你可以将其设置为  .5,动画将从中间开始播放。将整段动画分为两段,所以如果你的迭代次数设置为1,并且你的iterationStart设置为  .5,动画将从一半到动画结束播放,然后从动画开头开始,结束于中间! 

值得注意的是,你也可以将迭代次数设置为小于1。例如:

var option = {
  iterations: .5,
  iterationStart: .5
}

这将从中间到最后播放动画。 

endDelay:endDelay如果要将多个动画串在一起,但是希望在一个动画的结尾和任何后续动画的开始之间存在差距。

#Easing

Easing是任何动画中最重要的元素之一。WAAPI为我们提供了两种不同的方式设置easing- 在我们的keyframes阵列或我们的选项对象内。

在CSS中,如果你应用了,animation-timing-function: ease-in-out你可能会假设你的动画的淡入和淡出。实际上,这些easing应用在keayframes之间,而不是整个动画。这可以对动画的感觉进行细粒度的控制。WAAPI还提供这种能力。

var keyframes = [
  { opacity: 0, easing: 'ease-in' }, 
  { opacity: 0.5, easing: 'ease-out' }, 
  { opacity: 1 }
]

值得注意的是,在CSS和WAAPI中,你不应该传入最后一帧的easing值,因为这将不起作用。这是很多人犯的错误。

有时候,在整个动画中添加easing效果更为直观。这在CSS中是不可能的,但现在可以在WAAPI中实现。

var options = {
  duration: 1000,
  easing: 'ease-in-out',
}

你可以看到这两种easing的区别:

点击我查看代码及效果!!!!!!!

Ease vs线性

值得注意的是CSS动画和WAAPI之间的另一个区别:CSS ease的默认值是WAAPI的默认值linear。Ease实际上是ease-in-out的一个版本,是一个非常好的选择。同时,线性是看起来很沉闷 - 一致的速度看起来机械和不自然。它可能被选为默认值,因为它是最中立的选项。然而,在使用WAAPI时,使用缓存时更重要的是使用CSS,以免你的动画看起来很乏味和机械。

性能

WAAPI提供与CSS动画相同的性能改进,尽管这并不意味着平滑的动画是不可避免的。 

我希望这个API的性能优化意味着我们可以逃避使用will-change和完全hack translateZ - 最终可能。但是,至少在目前的浏览器实现中,这些属性在处理jank问题方面仍然是有帮助和必要的。

但是,如果你的动画有延迟,至少无需担心使用will-change。网络动画规范的主要作者在Animation for Work Slack community上提出了一些有趣的建议,希望他不介意我在这里重复: 

如果你有一个积极的延迟,你不需要will-change了,因为浏览器将在延迟开始时进行分层,当动画启动时,它将准备就绪。

 WAAPI对战CSS动画?

WAAPI为我们提供了一个在JavaScript中可以在样式表中实现的语法。然而,他们不应该被视为对手。如果我们决定坚持使用CSS进行动画和转换,那么我们可以与WAAPI进行动画交互。

动画对象

.animate()方法不仅仅是动画我们的元素,它也返回一些东西。 

var myAnimation = element.animate(keyframes, options);

在控制台中查看的动画对象

如果我们看看控制台中的返回值,我们将看到它的一个动画对象。这为我们提供了各种各样的功能,其中一些是非常不言自明的myAnimation.pause()。通过更改animation-play-state属性,我们可以通过CSS动画实现类似的结果,但WAAPI语法比稍微简单element.style.animationPlayState = "paused"。我们也有权力轻松地扭转我们的动画myAnimation.reverse(),再次,animation-direction与使用我们的脚本更改CSS属性相比,稍微有点改进。

然而,到目前为止,@keyframe用JavaScript进行操作并不是世界上最简单的事情。即使像重新启动动画一样简单,这个技巧也有一些技巧。使用WAAPI,我们可以简单地使用myAnimation.play()它从一开始就重播动画,如果它已经完成,或者如果我们暂停播放,则从中间迭代播放动画。

我们甚至可以轻松地改变动画的速度。

myAnimation.playbackRate = 2; // speed it up
myAnimation.playbackRate = .4; // use a number less than one to slow it down

 getAnimations()

此方法将返回任何动画对象的数组,以便我们使用WAAPI定义的任何动画以及任何CSS转换或动画。

element.getAnimations() // returns any animations or transitions applied to our element using CSS or WAAPI

如果你对使用CSS定义和应用的动画感觉还不错的话,getAnimations()可以使用API​​与@keyframes 结合使用。你可以继续使用CSS进行大部分动画工作,并在需要API时获得API的优势。让我们看看这是多么简单。

即使一个DOM元素只有一个动画应用到它,getAnimations()将始终返回一个数组。我们来抓住那个单一的动画对象来处理。

var h2 = document.querySelector("h2");
var myCSSAnimation = h2.getAnimations()[0];

现在我们可以在我们的CSS动画中使用web动画API :)

myCSSAnimation.playbackRate = 4;
myCSSAnimation.reverse();

Promise和事件

我们已经有多种通过CSS触发的事件,我们可以在我们的JavaScript代码利用的:   animationstart,animationend,animationiteration和transitionend。我经常需要收听动画或转换的结尾,以便从DOM中删除它应用于的元素。

在WAAPI 中使用animationend或transitionend为此目的相当于再次使用动画对象:

myAnimation.onfinish = function() {
  element.remove();
}

WAAPI为我们提供了两项活动和promises的选择。.finished我们的动画对象的属性将返回在动画结束时解决的promise。以下是上面的例子,就像使用promise一样:

myAnimation.finished.then(() =>
  element.remove())

我们来看看Mozilla开发人员网络中的一个稍微有点的例子。Promise.all希望有一系列的promises,一旦所有这些promises得到解决,只会运行我们的回调函数。我们已经看到,element.getAnimations()返回一个动画对象数组。我们可以将数组中的所有动画对象映射到每个动画对象.finished上,为我们提供所需的一系列承诺。

在这个例子中,只有在页面上的所有动画完成后,我们的函数才能运行。

Promise.all(document.getAnimations().map(animation => 
  animation.finished)).then(function() {           
    // do something cool 
  })

未来

本文中提到的功能只是开始。目前的规范和实施看起来是一件伟大而有用的事情的开始。

via css-tricks.com

相关推荐
CSS3教程:创意独特漂亮的CSS动画导航菜单设计
网站策划:CSS网页动画运用的十二大原则
网页前端开发:微博CSS3适用细节初探
20个免费CSS框架推荐 网页设计web开发必备
Bootstrap:知名的开源前端框架中文翻译版上线
9种网页设计有用的CSS3属性和使用技巧
8个超棒的创建响应式网页设计框架推荐
高效CSS开发需要注意的要点以及提升性能的做法
8款网页前端开发有用的优秀CSS工具分享
Web前端开发框架Twitter BootStrap推荐
20款设计师和web开发人员最爱的开源CSS框架推荐
CSS工具之SASS样式开发指南
koala:LESS/Sass前端预处理器语言图形编译工具
7个精致实用的的web UI框架 开源CSS框架推荐

精彩推荐

热门教程