Web动画API简介

朋友们,美好的一天!

Web API不断发展。所有浏览器都很好地支持其中的某些控制台和控制台,例如Console或Canvas,其他仍在开发中。

正在开发的API之一是Web Animations API或WAAPI。尽管该规范的第一版于2012年发布,并且API本身于2014年在Firefox和Chrome浏览器中首次实现,但我最近才发现它(之前也没有听说过-大约Per​​。)。

它允许开发人员使用JavaScript处理CSS动画。它的语法类似于传统CSS动画的语法,但是它具有一些使开发人员更容易创建和修改动画的功能。

让我们通过一个简单的示例来看一下这个API。

在下方,我们看到一个旋转的正方形,其颜色随每转而变化。



CSS可能如下所示:

#cube {
    width: 40px;
    height: 40px;
    margin: 50%;
    background-color: pink;
    animation: rotateCube 1s infinite;
}

@keyframes rotateCube {
    0% {
        transform: rotate(0deg);
    }

    30% {
        background-color: purple;
    }

    100% {
        transform: rotate(180deg);
    }
}

现在对WAAPI执行相同的操作。

创建动画


这一切都始于创建一个Keyframes对象,该对象包含与CSS @keyframes指令中包含的信息类似的信息:

let cubeRotating = [
    {transform: 'rotate(0deg)', backgroundColor: 'pink'},
    {backgroundColor: 'purple', offset: 0.3},
    {transform: 'rotate(180deg)', backgroundColor: 'pink'}
]

我们看到两个主要区别:

  • 我们需要将backgroundColor添加到其他步骤。
  • 我们不需要确定完成每个步骤的时间(以百分比表示)。

WAAPI会根据关键帧的数量自动将动画分为相等的部分,因此在我们的情况下,背景颜色将更改为动画的大约一半。

但是,我们希望这种情况发生30%,因此在第二步中将offset属性的值添加为0.3。

有一件重要的事情要记住:Keyframes对象必须至少具有两个键。否则,将引发NotSupportedError。

接下来,创建一个包含动画属性的对象,这些动画属性负责重复的持续时间和次数:

let cubeTiming = {
    duration: 1000,
    iterations: Infinity
}

动画的持续时间以毫秒为单位设置。

我们使用关键字“ Infinity”代替“ infinite”。

最后,要运行动画,我们使用Element.animate方法:

document.getElementById('cube').animate(
    cubeRotating,
    cubeTiming
)

还有其他几种语法选项。示例可以在这里找到

但这还不是全部。事实是,使用WAAPI,我们可以控制动画的播放!

动画播放控制


调用animate方法会立即启动动画,但这并不总是我们想要的。因此,我们可以分别调用pause和play方法来停止和启动动画:

let cubeAnimation = document.getElementById('cube').animate(
    cubeRotating,
    cubeTiming
)

cubeAnimation.pause()

document.body.onclick = () => cubeAnimation.play()

在我们的示例中,我们使用一个动画,但是您可以向页面添加多个“动画”并根据需要进行管理。

在可用的WAAPI方法中,还有finish,cancel和reverse方法。

我们还可以控制动画的播放速度:

let cubeAnimation = document.getElementById('cube').animate(
    cubeRotating,
    cubeTiming
)

document.body.onclick = () => cubeAnimation.playbackRate *= 1.5

此代码使单击时正方形旋转更快。



到目前为止,我们一直在学习如何创建一个动画并控制其播放。WAAPI的另一个功能是一次访问所有动画。

管理多个动画


WAAPI有一个getAnimations方法,允许您访问所有创建的动画。

假设我们要放慢页面上所有动画的速度,如果用户启用了“ preferred-reduced-motion”(CSS媒体功能“ preferred-reduced-motion”可用于确定用户是否已要求操作系统将其使用的动画或移动量减至最少) -大约):

const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)')

if(mediaQuery.matches){
    document.getAnimations().forEach(animation => {
        animation.playbackRate *= 0.5
    })
}

在上面的示例中,我们寻找媒体功能偏好“ reduced-motion”,如果其值减小,则获取页面上的所有动画并将其播放速度降低一半。

这是使WAAPI非常有用的事情之一。我们可以通过更改一个属性来更改多个动画。

依存关系


WAAPI的另一个有趣的功能是能够确定一个动画的属性对另一个动画的属性的依赖性。

例如,如果我们有两个正方形,并且我们希望第二个正方形旋转得比第一个正方形快两倍,我们可以通过两种方式做到这一点。

第一种方式:

let cube1Animation = document.getElementById('cube').animate(
    cubeRotating,
    {
        duration: 1000,
        iterations: Infinity
    }
)

let cube2Animation = document.getElementById('cube2').animate(
    cubeRotating,
    {
        duration: 500,
        iterations: Infinity
    }
)

第一个方块的动画时间为1秒,第二个为500毫秒。

但是,使用这种方法时,当我们更改第一个正方形的动画时间时,我们需要对第二个正方形执行相同的操作。

想象一下,当有许多动画或大量动画对象时,它会变得多么困难?

解决我们问题的最好方法是建立第二个正方形的旋转对第一个正方形的依赖性:

let cube1Animation = document.getElementById('cube').animate(
    cubeRotating,
    {
        duration: 1000,
        iterations: Infinity
    }
)

let cube2Animation = document.getElementById('cube2').animate(
    cubeRotating,
    {
        duration: cube1Animation.effect.timing.duration / 2,
        iterations: Infinity
    }
)

因此,我们使用第一个方块的动画时间来确定第二个方块的动画时间。现在,更改第一个方框的动画时间时,第二个方框将始终以两倍快的速度旋转!



性能


说到性能,我没有发现使用CSS和WAAPI之间有太大区别。但这可能是由于我的示例简单。

与在JS中创建动画的其他方法相比,WAAPI的一个重要优点是它在单独的线程中运行,这使主线程可以“忘记”动画并执行其余的代码。

浏览器支持


WAAPI当前处于草稿状态,并且在Firefox和Chrome的最新版本以及主要的移动浏览器中部分受WAAPI的支持。

部分支持意味着浏览器支持播放,暂停,倒退,完成和播放速率等方法,但不支持getAnimations。



有一个polyphile在所有浏览器的WAAPI。

这就是我的全部!

进一步阅读:

使用Web动画API
Web动画API示例
Dan Wilson的

精彩系列“让我们来谈谈Web动画API”谢谢您的关注。

Source: https://habr.com/ru/post/undefined/


All Articles