animations
本文由特约作者Dudley Storey撰写。 SitePoint访客帖子旨在为您带来来自JavaScript社区的杰出作家和演讲者的引人入胜的内容。
一种API统治一切
长期以来,网络上的动画被分为四个不同的阵营:
- CSS过渡和动画非常高效,可以提供关键帧,但是构建起来也很耗时,并且仅提供CSS和JavaScript中的基本开始和结束控件。 这倾向于将它们委托给简单的UI响应动画,循环和页面加载动画。
- SMIL (同步多媒体集成语言)功能非常强大,但语法繁重且对浏览器的支持不完整。 它还仅限于仅在SVG上下文中控制元素。
- JavaScript提供对元素的直接控制,但是对关键帧或缓动之类的设计器友好功能不了解,并且缺少CSS的本机优化和性能。 Canvas API动画很棒,但是仍然缺乏对动画基础的理解,并且不能为任意DOM元素设置动画。
- 诸如Greensock之类的JavaScript动画框架试图弥补 动画方面传统JavaScript缺陷,但具有框架的所有相关缺点:页面加载,性能和学习新语法。
Web Animations API试图将所有这些的最佳功能集成到一个统一的规范中 ,同时消除缺点,在JavaScript中创建对关键帧,缓动和元素控制的原生理解,并在屏幕上获得与CSS相同的性能。 。 现在 ,该规范的核心组件已在Chrome和Firefox中得到支持 ,并且已在其他浏览器(包括Safari和Edge)中宣布或正在进行开发,以及强大的polyfill的可用性 ,现在应该认真考虑Web Animations API带来的Web生活的页面。
Web Animations API有助于使动画成为Web设计的主要内容,从而为厂商优化性能和第三方工具打开了大门。 — Rachel Nabors(@rachelnabors) 2016年9月29日
JavaScript中的关键帧
让我们来看一个关键帧动画的最简单示例:将红色的球元素从页面的一侧移到另一侧。 无论我们使用哪种技术, 元素都将相同:
<div id="redball"></div>
和最初CSS一样:
body {
margin: 0;
background: #000;
overflow: hidden;
min-height: 100vh;
}
#redball {
background: red;
width: 30vmin;
height: 30vmin;
border-radius: 50%;
}
我使用了vmin
单位 ,以使元素在响应视口大小时始终保持对称。
在CSS中,将球从页面的一侧移到另一侧将需要执行以下操作:
@keyframes moveBall {
from {
transform: translateX(-20vw);
}
to {
transform: translateX(100vw);
}
}
该动画将从红色球元素的声明中调用:
#redball {
animation: moveBall 3s infinite;
}
结果显示在Codepen中:
请参阅CodePen上的SitePoint ( @SitePoint )的Pen Basic CSS红球动画 。
此时,需要注意一些有关动画的事情,包括自动内置了缓动(开始时加快和结束时放慢)的事实。
输入Web动画API
保留HTML和初始样式,让我们删除CSS动画,并替换使用Web Animation API完成相同功能JavaScript:
var moveBall = document.getElementById('redball').animate([{
transform: 'translateX(-20vw)'
}, {
transform: 'translateX(100vw)'
}], {
duration: 3000,
iterations: Infinity,
easing: 'ease'
});
您可以看到该动画采用了与CSS大部分相同的语法,但是将其表示为带有数组的对象,该数组表示关键帧。 我们不必在关键帧之间明确声明或from
关键帧中声明to
JavaScript会自动为我们平均分配关键帧,尽管声明也是完全可能的。
动画尚未播放; 就像在CSS中一样,我们必须调用它:
moveBall.play();
语法的关键帧部分将成为即使在未来的浏览器更容易,因为CSS的方面变换语法以前值成为可用的属性 :
translateX: -20vw;
对此规范的更改已在Chrome Canary中提供,但要一到两年后,新语法才能在所有现代浏览器中使用。
免费学习PHP!
全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。
原价$ 11.95 您的完全免费
关于脚本还有其他一些注意事项:
- JavaScript将动画计时的时间以毫秒为单位,而不是标准CSS秒(毫秒也可以在CSS中使用,只要将
ms
附加到计时值上即可)。 - Web Animations API将迭代次数指定为
iterations
,而不是interation-count
CSS属性(当单独定义时); 关键字是Infinity
(大写I)代表重复的次数,而不是CSS的infinite
。 - 在Web Animations API中,默认的缓动是
linear
,因此在我们的演示中,我们为CSS Animations指定了ease
的默认值。
结果在功能上等同于CSS动画。
请参阅CodePen上的SitePoint ( @SitePoint ) 在Web Animation API中使用Pen Basic Red Ball Anim 。
当然,在JavaScript中复制这样CSS动画并不会真正发挥脚本语言的动态性,而几乎不能发挥其最大能力。 为了说明这一点,我们将创建功能更强大的动画。
图像处理
前段时间,我很有趣地创建了一个动画,该动画将一系列图像发布到网页上,例如将扑克牌滑到桌子上。 在传统CSS中为每张卡编写单独的动画将花费大量时间,并且始终会获得相同的结果。 相反,我将Web Animations API用作完成此工作的理想工具。
渐进卡
我们希望无论是否启用JavaScript或Web动画API都可以看到图像,因此我们从向页面添加一系列图像开始:
<div class="shuffle expose">
<img src="bridgefog.jpg" alt>
<img src="daisyface.jpg" alt>
<img src="drowninghand.jpg" alt>
<img src="firefigure.jpg" alt>
<img src="shellhand.jpg" alt>
<img src="waterfeet.jpg" alt>
</div>
为了使代码清晰,我将图像的alt
值留为空白。 在生产版本中,将充满描述。 这些照片是由.tafo制作的。 ,根据知识共享署名-NoDerivs 2.0通用许可使用 。
如果没有JavaScript的条件仍然成立,我们可以添加一些CSS来使图像带有动画:
@keyframes reveal {
to {
opacity: 1;
}
}
.shuffle {
min-height: 100vh;
position: relative;
}
.shuffle img {
width: 33%;
opacity: 0;
}
.expose img {
animation: reveal 1s forwards;
}
单个图像传递可能会因以下原因而延迟:
.expose img:nth-child(1) { animation-delay: 1s; }
.expose img:nth-child(2) { animation-delay: 2s; }
.expose img:nth-child(3) { animation-delay: 3s; }
…
当然,这些声明可以使用Sass或其他预处理器自动执行。
如果父元素具有webanim
class
, 则图像将带有边框, webanim
将与JavaScript一起应用:
div.webanim img {
border: 1.4vw solid #eee;
}
JavaScript
我们将脚本添加到页面的末尾。 我将在动画中需要几个随机值,因此我将创建一个函数来产生这些值:
function getRandom(min, max) {
return Math.random() * (max - min) + min;
}
然后,我将收集图像容器及其中的所有图像,并设置一个增量变量:
var imgContainer = document.querySelector(".expose"),
imgSeq = document.querySelectorAll(".shuffle img"),
i = 1;
然后,我将删除expose
类(将图像的不透明度设置为0
并进行动画处理(因为CSS动画仅在容器具有expose
类的情况下才起作用:
imgContainer.classList.remove("expose");
imgContainer.classList.add("webanim");
webanim
类将图像放置在边框上。
该脚本的大部分发生在函数内部的forEach
循环中。 一旦确保使用David DeSandro出色的imagesLoaded
脚本加载了所有图像数据(而不是仅出现在DOM中的图像节点),便会调用该函数:
function racknstack() {
Array.prototype.forEach.call(imgSeq, function(photo) {
setTimeout(function() {
photo.style.position = "absolute";
photo.style.width = getRandom(33, 45) + "%";
photo.style.left = getRandom(-5, 65) + "%";
photo.style.top = getRandom(-6, 60) + "vh";
var animate = photo.animate([{
opacity: '0',
transform: 'rotate(' + getRandom(-12, 12) + 'deg) scale(1.2)',
boxShadow: '0 0 12px 12px rgba(0,0,0,.3)'
}, {
opacity: '1',
transform: 'rotate(' + getRandom(-8, 8) + 'deg)',
boxShadow: '0 0 6px 6px rgba(0,0,0,.3)'
}], {
duration: 2000,
fill: 'forwards'
});
}, 1800 * i)
i++;
})
}
和以前一样,我们必须调用该函数以开始操作:
imagesLoaded(imgSeq, racknstack);
结果:
请参阅CodePen上带有 SitePoint( @SitePoint )的带有WebAnim API和Progressive JS的钢笔随机堆积图像 。
反过来,该函数:
- 将每个图像设置到绝对位置;
- 生成图像的随机宽度(以百分比表示,因此图像保持流畅且响应Swift)
- 为图像生成一个随机位置(包括可能的负位置,这意味着它可能会稍微离开视口的边缘)
- 使用Web动画API对照片进行动画处理。 关键帧在旋转图像时将图像从
0
淡入到不透明
前forwards
填充是必要的,因为我们希望图像在动画完成后保持在其最终状态 。
从力量到力量
Web Animation API的开发仍在继续进行:
- 当前的工作草案正在稳步建立,Chrome和Firefox支持越来越多的组件。
- 有一个出色的,无依赖的polyfill ,可以将其简单地放入页面中,以为尚未实现该规范的浏览器提供支持。
- Rachel Nabors 在Mozilla Developer博客上对该主题做了出色的介绍 ,并提供了几场会议演示和一套CodePen演示供您探索,这比任何人都更能公开或支持该规范的可能性。 。 这是她在规范中的工作概述 。
结论
如您所见,Web Animations API允许我们从CSS动画的特定的,声明性的,逐步的特性过渡到动态,命令式JavaScript方法,该方法允许表达,随机,高性能的动画。
我希望看到您在Web Animation API中的探索,尤其是在生产站点中:在下面的评论中让我知道!
翻译自: https://www.sitepoint.com/bringing-pages-to-life-web-animations-api/
animations