搜尋
首頁web前端css教學我如何使用Waapi構​​建動畫庫

How I Used the WAAPI to Build an Animation Library

The Web Animations API lets us construct animations and control their playback with JavaScript. The API opens the browser’s animation engine to developers and was designed to underlie implementations of both CSS animations and transitions, leaving the door open to future animation effects. It is one of the most performant ways to animate on the Web, letting the browser make its own internal optimizations without hacks, coercion, or window.requestAnimationFrame().

With the Web Animations API, we can move interactive animations from stylesheets to JavaScript, separating presentation from behavior. We no longer need to rely on DOM-heavy techniques such as writing CSS properties and scoping classes onto elements to control playback direction. And unlike pure, declarative CSS, JavaScript also lets us dynamically set values from properties to durations. For building custom animation libraries and creating interactive animations, the Web Animations API might be the perfect tool for the job. Let’s see what it can do!

For the rest of this article, I will sometimes refer to the Web Animation API as WAAPI. When searching for resources on the Web Animation API, you might be led astray by searching “Web Animation API” so, to make it easy to find resources, I feel we should adopt the term WAAPI; tell me what you think in the comments below.

This is the library I made with the WAAPI

@okikio/animate is an animation library for the modern web. It was inspired by animateplus, and animejs; it is focused on performance and developer experience, and utilizes the Web Animation API to deliver butter-smooth animations at a small size, weighing in at ~5.79 KB (minified and gzipped).

The story behind @okikio/animate

In 2020, I decided to make a more efficient PJAX library, similar to Rezo Zero’s – Starting Blocks project, but with the ease of use of barbajs. I felt starting blocks was easier to extend with custom functionality, and could be made smoother, faster, and easier to use.

Note: if you don’t know what a PJAX library is I suggest checking out MoOx/pjax; in short, PJAX allows for smooth transitions between pages using fetch requests and switching out DOM Elements.

Over time my intent shifted, and I started noticing how often sites from awwwards.com used PJAX, but often butchered the natural experience of the site and browser . Many of the sites looked cool at first glance, but the actual usage often told a different story — scrollbars were often overridden, prefetching was often too eager, and a lack of preparation for people without powerful internet connections, CPUs and/or GPUs. So, I decided to progressively enhance the library I was going to build. I started what I call the “native initiative” stored in the GitHub repo okikio/native; a means of introducing all the cool and modern features in a highly performant, compliant, and lightweight way.

For the native initiative I designed the PJAX library @okikio/native; while testing on an actual project, I ran into the Web Animation API, and realized there were no libraries that took advantage of it, so, I developed @okikio/animate, to create a browser compliant animation library. (Note: this was in 2020, around the same time use-web-animations by wellyshen was being developed. If you are using react and need some quick animate.css like effects, use-web-animations is a good fit.) At first, it was supposed to be simple wrapper but, little by little, I built on it and it’s now at 80% feature parity with more mature animation libraries.

Note: you can read more on the native initiative as well as the @okikio/native library on the Github repo okikio/native. Also, okikio/native, is a monorepo with @okikio/native and @okikio/animate being sub-packages within it.

Where @okikio/animate fits into this article

The Web Animation API is very open in design. It is functional on its own but it’s not the most developer-friendly or intuitive API, so I developed @okikio/animate to act as a wrapper around the WAAPI and introduce the features you know and love from other more mature animation libraries (with some new features included) to the high-performance nature of the Web Animation API. Give the project’s README a read for much more context.

Now, let’s get started

@okikio/animate creates animations by creating new instances of Animate (a class that acts as a wrapper around the Web Animation API).

import { Animate } from"@okikio/animate";

new Animate({
  target: [/* ... */],
  duration: 2000,
  // ... 
});

The Animate class receives a set of targets to animate, it then creates a list of WAAPI Animation instances, alongside a main animation (the main animation is a small Animation instance that is set to animate over a non-visible element, it exists as a way of tracking the progress of the animations of the various target elements), the Animate class then plays each target elements Animation instance, including the main animation, to create smooth animations.

The main animation is there to ensure accuracy in different browser vendor implementations of WAAPI. The main animation is stored in Animate.prototype.mainAnimation, while the target element’s Animation instances are stored in a WeakMap, with the key being its KeyframeEffect. You can access the animation for a specific target using the Animate.prototype.getAnimation(el).

You don‘t need to fully understand the prior sentences, but they will aid your understanding of what @okikio/animate does. If you want to learn more about how WAAPI works, check out MDN, or if you would like to learn more about the @okikio/animate library, I’d suggest checking out the okikio/native project on GitHub.

Usage, examples and demos

By default, creating a new instance of Animate is very annoying, so, I created the animate function, which creates new Animate instances every time it’s called.

import animate from "@okikio/animate";
// or
import { animate } from "@okikio/animate";

animate({ 
  target: [/* ... */],
  duration: 2000,
  // ... 
});

When using the @okikio/animate library to create animations you can do this:

import animate from "@okikio/animate";

// Do this if you installed it via the script tag: const { animate } = window.animate;

(async () => {
  let [options] = await animate({
    target: ".div",

    // Units are added automatically for transform CSS properties
    translateX: [0, 300],
    duration: 2000, // In milliseconds
    speed: 2,
  });

  console.log("The Animation is done...");
})();

You can also play with a demo with playback controls:

Try out Motion Path:

Try different types of Motion by changing the Animation Options:

I also created a complex demo page with polyfills:

View demo

You can find the source code for this demo in the animate.ts and animate.pug files in the GitHub repo. And, yes, the demo uses Pug, and is a fairly complex setup. I highly suggest looking at the README as a primer for getting started.

The native initiative uses Gitpod, so if you want to play with the demo, I recommend clicking the “Open in Gitpod” link since the entire environment is already set up for you — there’s nothing to configure.

You can also check out some more examples in this CodePen collection I put together. For the most part, you can port your code from animejs to @okikio/animate with few-to-no issues.

I should probably mention that @okikio/animate supports both the target and targets keywords for settings animation targets. @okikio/animate will merge both list of targets into one list and use Sets to remove any repeated targets. @okikio/animate supports functions as animation options, so you can use staggering similar to animejs. (Note: the order of arguments are different, read more in the “Animation Options & CSS Properties as Methods” section of the README file.)

Restrictions and limitations

@okikio/animate isn’t perfect; nothing really is, and seeing as the Web Animation API is a living standard constantly being improved, @okikio/animate itself still has lots of space to grow. That said, I am constantly trying to improve it and would love your input so please open a new issue, create a pull request or we can have a discussion over at the GitHub project.

The first limitation is that it doesn’t really have a built-in timeline. There are a few reasons for this:

  1. I ran out of time. I am still only a student and don’t have lots of time to develop all the projects I want to.
  2. I didn’t think a formal timeline was needed, as async/await programming was supported. Also, I added timelineOffset as an animation option, should anyone ever need to create something similar to the timeline in animejs.
  3. I wanted to make @okikio/animate as small as possible.
  4. With group effects and sequence effects coming soon, I thought it would be best to leave the package small until an actual need comes up. On that note, I highly suggest reading Daniel C. Wilson’s series on the WAAPI, particularly the fourth installment that covers group effects and sequence effects.

Another limitation of @okikio/animate is that it lacks support for custom easings, like spring, elastic, etc. But check out Jake Archibald’s proposal for an easing worklet. He discusses multiple standards that are currently in discussion. I prefer his proposal, as it’s the easiest to implement, not to mention the most elegant of the bunch. In the meanwhile, I’m taking inspiration from Kirill Vasiltsov article on Spring animations with WAAPI and I am planning to build something similar into the library.

The last limitation is that @okikio/animate only supports automatic units on transform functions e.g. translateX, translate, scale, skew, etc. This is no longer the case as of @okikio/[email protected], but there are still some limitations on CSS properties that support color. Check the GitHub release for more detail.

For example:

animate({
  targets: [".div", document.querySelectorAll(".el")],

  // By default "px", will be applied
  translateX: 300,
  left: 500,
  margin: "56 70 8em 70%",

  // "deg" will be applied to rotate instead of px
  rotate: 120, 

  // No units will be auto applied
  color: "rgb(25, 25, 25)",
  "text-shadow": "25px 5px 15px rgb(25, 25, 25)"
});

Looking to the future

Some future features, like ScrollTimeline, are right around the corner. I don’t think anyone actually knows when it will release but since the ScrollTimeline in Chrome Canary 92, I think it’s safe to say the chances of a release in the near future look pretty good.

I built the timeline animation option into @okikio/animate to future-proof it. Here’s an example:

Thanks to Bramus for the demo inspiration! Also, you may need the Canary version of Chrome or need to turn on Experimental Web Platform features in Chrome Flags to view this demo. It seems to work just fine on Firefox, though, so… ?.

If you want to read more on the ScrollTimeline, Bramus wrote an excellent article on it. I would also suggest reading the Google Developers article on Animation Worklets.

My hope is to make the library smaller. It’s currently ~5.79 KB which seems high, at least to me. Normally, I would use a bundlephobia embed but that has trouble bundling the project, so if you want to verify the size, I suggest using bundle.js.org because it actually bundles the code locally on your browser. I specifically built it for checking the bundle size of @okikio/animate, but note it’s not as accurate as bundlephobia.

Polyfills

One of the earlier demos shows polyfills in action. You are going to need web-animations-next.min.js from web-animations-js to support timelines. Other modern features the KeyframeEffect constructor is required.

The polyfill uses JavaScript to test if the KeyframeEffect is supported and, if it isn’t, the polyfill loads and does its thing. Just avoid adding async/defer to the polyfill, or it will not work the way you expect. You’ll also want to polyfill Map, Set, and Promise.

  
    <!-- Async -->
    <script src=",es2015,es2018,Array.prototype.includes,Map,Set,Promise" async></script>
    <!-- NO Async/Defer -->
    <script src="./js/webanimation-polyfill.min.js"></script>
  
  
    <!-- Content -->
  

And if you’re building for ES6+, I highly recommend using esbuild for transpiling, bundling, and minifying. For ES5, I suggest using esbuild (with minify off), Typescript (with target of ES5), and terser; as of now, this is the fastest setup to transpile to ES5, it’s faster and more reliable than babel. See the Gulpfile from the demo for more details.

Conclusion

@okikio/animate is a wrapper around the Web Animation API (WAAPI) that allows you to use all the features you love from animejs and other animation libraries, in a small and concise package. So, what are your thoughts after reading about it? Is it something you think you’ll reach for when you need to craft complex animations? Or, even more important, is there something that would hold you back from using it? Leave a comment below or join the discussion on Github Discussions.

This article originally appeared on dev.to, it also appeared on hackernoon.com and my blog blog.okikio.dev.
Photo by Pankaj Patel on Unsplash.

以上是我如何使用Waapi構​​建動畫庫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
什麼是CSS網格?什麼是CSS網格?Apr 30, 2025 pm 03:21 PM

CSS網格是創建複雜,響應式Web佈局的強大工具。它簡化了設計,提高可訪問性並提供了比舊方法更多的控制權。

什麼是CSS Flexbox?什麼是CSS Flexbox?Apr 30, 2025 pm 03:20 PM

文章討論了CSS FlexBox,這是一種佈局方法,用於有效地對齊和分佈響應設計中的空間。它說明了FlexBox用法,將其與CSS網格進行了比較,並詳細瀏覽了瀏覽器支持。

我們如何使用CSS使網站迅速響應?我們如何使用CSS使網站迅速響應?Apr 30, 2025 pm 03:19 PM

本文討論了使用CSS創建響應網站的技術,包括視口元標籤,靈活的網格,流體媒體,媒體查詢和相對單元。它還涵蓋了使用CSS網格和Flexbox一起使用,並推薦CSS框架

CSS盒裝屬性有什麼作用?CSS盒裝屬性有什麼作用?Apr 30, 2025 pm 03:18 PM

本文討論了CSS盒裝屬性,該屬性控制了元素維度的計算方式。它解釋了諸如Content-Box,Border-Box和Padding-Box之類的值,以及它們對佈局設計和形式對齊的影響。

我們如何使用CSS動畫?我們如何使用CSS動畫?Apr 30, 2025 pm 03:17 PM

文章討論使用CSS,關鍵屬性並與JavaScript結合創建動畫。主要問題是瀏覽器兼容性。

我們可以使用CSS向我們的項目添加3D轉換嗎?我們可以使用CSS向我們的項目添加3D轉換嗎?Apr 30, 2025 pm 03:16 PM

文章討論了Web項目的3D轉換,關鍵屬性,瀏覽器兼容性和性能注意事項的討論。 (角色計數:159)

我們如何在CSS中添加梯度?我們如何在CSS中添加梯度?Apr 30, 2025 pm 03:15 PM

文章討論了使用CSS梯度(線性,徑向,重複)來增強網站視覺效果,添加深度,焦點和現代美學。

CSS中的偽元素是什麼?CSS中的偽元素是什麼?Apr 30, 2025 pm 03:14 PM

文章討論了CSS中的偽元素,它們在增強HTML樣式方面的使用以及與偽級的差異。提供實用的例子。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具