AbsoluteOrientationSensor: AbsoluteOrientationSensor() constructor - Web APIs

AbsoluteOrientationSensor: AbsoluteOrientationSensor() constructor
==================================================================

The **`AbsoluteOrientationSensor()`** constructor creates a new `AbsoluteOrientationSensor` object which describes the device's physical orientation in relation to the Earth's reference coordinate system.

Syntax
------

```js
new AbsoluteOrientationSensor()
new AbsoluteOrientationSensor(options)
```

### Parameters

`options` Optional

Options are as follows:

`frequency`

The desired number of times per second a sample should be taken, meaning the number of times per second that the `reading` event will be called. A whole number or decimal may be used, the latter for frequencies less than a second. The actual reading frequency depends on the device hardware and consequently may be less than requested.

`referenceFrame`

Either `'device'` or `'screen'`. The default is `'device'`.

Specifications
--------------

| Specification |
| --- |
| Orientation Sensor # dom-absoluteorientationsensor-absoluteorientationsensor |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `reading` event


SourceBufferList: length property - Web APIs

SourceBufferList: length property
=================================

 The **`length`** read-only property of the
 `SourceBufferList` interface returns the number of
 `SourceBuffer` objects in the list.

Value
-----

An unsigned long number.

Examples
--------

TBD

Specifications
--------------

| Specification |
| --- |
| Media Source Extensions™ # dom-sourcebufferlist-length |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `MediaSource`
* `SourceBuffer`


Using the Storage Access API - Web APIs

Using the Storage Access API
============================

The Storage Access API can be used by embedded cross-site documents to verify whether they have access to third-party cookies and, if not, to request access. We'll briefly look at a common storage access scenario.

**Note:** When we talk about third-party cookies in the content of the Storage Access API, we implicitly mean *unpartitioned* third-party cookies.

Usage notes
-----------

The Storage Access API is designed to allow embedded content to request access to third-party cookies — most modern browsers block such access by default to protect user privacy. Since embedded content won't know what a browser's behavior is going to be in this regard, it's best to always check whether the embedded `<iframe>` has storage access before attempting to read or write a cookie. This is particularly true for `Document.cookie` access, as browsers will often return an empty cookie jar when third-party cookie access is blocked.

In the example below, we show how an embedded cross-site `<iframe>` can access third-party cookies under a browser storage access policy that would otherwise block access to them.

Allowing a sandboxed <iframe> to use the API
--------------------------------------------

First of all, if the `<iframe>` is sandboxed, the embedding website needs to add the `allow-storage-access-by-user-activation` sandbox token to allow Storage Access API requests to be successful, along with `allow-scripts` and `allow-same-origin` to allow it to execute a script to call the API and execute it in an origin that can have cookies:

```html
<iframe
 sandbox="allow-storage-access-by-user-activation
 allow-scripts
 allow-same-origin">
  …
</iframe>
```

Checking and requesting storage access
--------------------------------------

Now on to the code executed inside the embedded document. In this code:

1. We first use feature detection (`if (document.hasStorageAccess) {}`) to check whether the API is supported. If not, we run our code that accesses cookies anyway, and hope that it works. It should be coded defensively to deal with such eventualities anyway.
2. If the API is supported, we call `document.hasStorageAccess()`.
3. If that call returns `true`, it means this `<iframe>` has already obtained access, and we can run our code that accesses cookies right away.
4. If that call returns `false`, we then call `Permissions.query()` to check whether permission to access third-party cookies has already been granted (i.e., to another same-site embed). We wrap this whole section in a `try...catch` block because some browsers don't support the `"storage-access"` permission, which can cause the `query()` call to throw. If it throws, we report that to the console and try running the cookie code anyway.
5. If the permission state is `"granted"`, we immediately call `document.requestStorageAccess()`. This call will automatically resolve, saving the user some time, then we can run our code that accesses cookies.
6. If the permission state is `"prompt"`, we call `document.requestStorageAccess()` after user interaction. This call may trigger a prompt to the user. If this call resolves, then we can run our code that accesses cookies.
7. If the permission state is `"denied"`, the user has denied our requests to access third-party cookies, and our code cannot use them.

```js
function doThingsWithCookies() {
  document.cookie = "foo=bar"; // set a cookie
}

async function handleCookieAccess() {
  if (!document.hasStorageAccess) {
    // This browser doesn't support the Storage Access API
    // so let's just hope we have access!
    doThingsWithCookies();
  } else {
    const hasAccess = await document.hasStorageAccess();
    if (hasAccess) {
      // We have access to third-party cookies, so let's go
      doThingsWithCookies();
    } else {
      // Check whether third-party cookie access has been granted
      // to another same-site embed
      try {
        const permission = await navigator.permissions.query({
          name: "storage-access",
        });

        if (permission.state === "granted") {
          // If so, you can just call requestStorageAccess() without a user interaction,
          // and it will resolve automatically.
          await document.requestStorageAccess();
          doThingsWithCookies();
        } else if (permission.state === "prompt") {
          // Need to call requestStorageAccess() after a user interaction
          btn.addEventListener("click", async () => {
            try {
              await document.requestStorageAccess();
              doThingsWithCookies();
            } catch (err) {
              // If there is an error obtaining storage access.
              console.error(`Error obtaining storage access: ${err}.
 Please sign in.`);
            }
          });
        } else if (permission.state === "denied") {
          // User has denied third-party cookie access, so we'll
          // need to do something else
        }
      } catch (error) {
        console.log(`Could not access permission state. Error: ${error}`);
        doThingsWithCookies(); // Again, we'll have to hope we have access!
      }
    }
  }
}
```

**Note:** `requestStorageAccess()` requests are automatically denied unless the embedded content is currently processing a user gesture such as a tap or click (transient activation), or if permission was already granted previously. If permission was not previously granted, `requestStorageAccess()` requests must be run inside a user gesture-based event handler, as shown above.

### Related website sets

The Chrome-only related website sets feature can be considered a progressive enhancement mechanism that works alongside the Storage Access API — supporting browsers grant default third-party cookie access between websites in the same set. This means not having to go through the usual user permission prompt workflow described above, meaning a more user-friendly experience for users of sites in the set.

Requesting storage access from the top-level site on behalf of embedded resources
---------------------------------------------------------------------------------

The Storage Access API features above allow an embedded document to request its own third-party cookie access. There is an additional experimental method available, `Document.requestStorageAccessFor()`, a proposed extension to the Storage Access API that allows top-level sites to request storage access on behalf of specific related origins.

The `requestStorageAccessFor()` method addresses challenges in adopting the Storage Access API on top-level sites that use cross-site images or scripts requiring cookies. It can enable third-party cookie access for cross-site resources directly embedded into the top-level site that are unable to request their own storage access, for example via `<img>` or `<script>` elements.

For `requestStorageAccessFor()` to work, both the calling top-level page and the embedded resource it is requesting storage access for need to be part of the same related website set.

Typical usage of `requestStorageAccessFor()` looks like this (this time written in regular promise-style rather than async/await):

```js
navigator.permissions
  .query({
    name: "top-level-storage-access",
    requestedOrigin: "https://example.com",
  })
  .then((permission) => {
    if (permission.state === "granted") {
      // Permission has already been granted
      // No need to call requestStorageAccessFor() again, just start using cookies
      doThingsWithCookies();
    } else if (permission.state === "prompt") {
      // Need to call requestStorageAccessFor() after a user interaction
      btn.addEventListener("click", () => {
        // Request storage access
        rSAFor();
      });
    } else if (permission.state === "denied") {
      // User has denied third-party cookie access, so we'll
      // need to do something else
    }
  });

function rSAFor() {
  if ("requestStorageAccessFor" in document) {
    document.requestStorageAccessFor("https://example.com").then(
      (res) => {
        doThingsWithCookies();
      },
      (err) => {
        // Handle errors
      },
    );
  }
}
```

**Note:** Unlike with `requestStorageAccess()`, Chrome doesn't check for an interaction in a top-level document within the last 30 days when `requestStorageAccessFor()` is called because the user is already on the page. See Browser-specific variations > Chrome for more details of this behavior.

When querying permission status for storage access requests made on behalf of another origin, the permission name used is different from the rest of the Storage Access API: `"top-level-storage-access"` rather than `"storage-access"`. In the above code, we use the following call:

```js
navigator.permissions.query({
  name: "top-level-storage-access",
  requestedOrigin: "https://example.com",
});
```

to discover if the origin has previously been granted permission or if cookie access still needs to be requested.

* If the permission status is `"granted"` we can start using cookies; `requestStorageAccessFor()` was already called, so there is no need to call it again.
* If the permission status is `"prompt"` we need to call `document.requestStorageAccessFor("https://example.com")` from within a user gesture, such as a button click.

After the `"top-level-storage-access"` permission is granted, cross-site requests will include cookies if they include CORS / `crossorigin`, so sites may want to wait before triggering a request. Such requests must use the `credentials: "include"` option and resources must include the `crossorigin="use-credentials"` attribute.

For example:

```js
function checkCookie() {
  fetch("https://example.com/getcookies.json", {
    method: "GET",
    credentials: "include",
  })
    .then((response) => response.json())
    .then((json) => {
      // Do something
    });
}
```


Related Website Sets - Web APIs

Related Website Sets
====================

Related website sets are a mechanism for defining a set of related sites that share trusted content. As a result, browsers will grant default access for these sites to third-party cookies when they have content embedded in other set members.

Concepts and usage
------------------

Let's consider situations where you have a series of related websites with different domain names, and you want to give site content access to third-party cookies when loaded in a third-party context inside other related sites (i.e., embedded in an `<iframe>`). Typical use cases are:

* App sites: A single application may be deployed over multiple sites, aiming to allow users to navigate between them seamlessly in a single session.
* Brand sites: A set of brand assets may be contained in a single site but then deployed over multiple domains, including session data relating to user preferences, customization, etc.

Third-party cookie access is commonly blocked by browser cookie-blocking policies. Still, you can work around it using the Storage Access API — see Using the Storage Access API for details.

Related website are a progressive enhancement mechanism that works alongside the Storage Access API. Supporting browsers grant third-party cookie access between websites in the same set *without* having to go through the usual user permission prompt workflow, once `Document.requestStorageAccess()` (or `Document.requestStorageAccessFor()`) is called. This results in a more user-friendly experience for users of sites in the set.

You should bear in mind that:

* The Chrome-only `Document.requestStorageAccessFor()` method — which allows top-level sites to request storage access on behalf of embedded origin content — is only supported on domains within a related website set. See Using the Storage Access API for an example.
* When Chrome first supported the standard Storage Access API (that is, the `Document.hasStorageAccess()` and `Document.requestStorageAccess()`methods), it required calling sites to be part of a related website set. This is no longer the case.
How does RWS work?
------------------

A related website set consists of one primary site and up to five associated sites.

### JSON structure

A set is represented by a JSON structure. A hypothetical example is as follows:

```json
{
  "sets": [
    {
      "contact": "email address or group alias if available",
      "primary": "https://primary1.com",
      "associatedSites": [
        "https://associateA.com",
        "https://associateB.com",
        "https://associateC.com"
      ],
      "serviceSites": ["https://servicesiteA.com"],
      "rationaleBySite": {
        "https://associateA.com": "Explanation of affiliation with primary site",
        "https://associateB.com": "Explanation of affiliation with primary site",
        "https://associateC.com": "Explanation of affiliation with primary site",
        "https://serviceSiteA.com": "Explanation of service functionality support"
      },
      "ccTLDs": {
        "https://associateA.com": [
          "https://associateA.ca",
          "https://associateA.co.uk"
        ],
        "https://associateB.com": [
          "https://associateB.ru",
          "https://associateB.co.kr"
        ],
        "https://primary1.com": ["https://primary1.co.uk"]
      }
    }
  ]
}
```

**Note:** The affiliation explanations must include a clear description of how the affiliation to the primary site is presented to users of those sites.

To use a set, its JSON must be added to the `related_website_sets.JSON` file available on the Related Website Sets GitHub repository, which Chrome then consumes to get the list of sets to apply RWS behavior to.

### `.well-known` files

Each site in the set must also serve a `.well-known` file at `/.well-known/related-website-set.json`, which serves to verify the set structure and the relationship between the sites in the set.

The primary site's `.well-known` file must explicitly list out the full set structure. `https://primary1.com` in the above example would need a `https://primary1.com/.well-known/related-website-set.json` file similar to the following:

```json
{
  "primary": "https://primary1.com",
  "associatedSites": [
    "https://associateA.com",
    "https://associateB.com",
    "https://associateC.com"
  ],
  "serviceSites": ["https://servicesiteA.com"],
  "rationaleBySite": {
    "https://associateA.com": "Explanation of affiliation with primary site",
    "https://associateB.com": "Explanation of affiliation with primary site",
    "https://associateC.com": "Explanation of affiliation with primary site",
    "https://serviceSiteA.com": "Explanation of service functionality support"
  },
  "ccTLDs": {
    "https://associateA.com": [
      "https://associateA.ca",
      "https://associateA.co.uk"
    ],
    "https://associateB.com": [
      "https://associateB.ru",
      "https://associateB.co.kr"
    ],
    "https://primary1.com": ["https://primary1.co.uk"]
  }
}
```

Each associate and service site needs to specify its primary site in a `.well-known` file. Each non-primary site in the above example (e.g. `https://associateA.com`) would need a `/.well-known/related-website-set.json` file like this:

```json
{
  "primary": "https://primary1.com"
}
```

For full details of the process, JSON syntax, and other requirements for submitting sets, see the submission guidelines. Only domain administrators can create a set containing their sites.

Bear in mind that the `.well-known` files are also verified as part of the submission process, so they need to be put in place before the associated set is submitted.

### Active set benefits

Once a set is active:

* Requests from sites in the set (via `Document.requestStorageAccess()`) to access third-party cookies that belong to sites in the set are automatically granted, and no user permission step is required.
* `Document.requestStorageAccessFor()` calls can be made from top-level sites in the set to request third-party cookie access for other sites in the set.
RWS security
------------

RWS has been designed with security in mind. It would be disastrous if a bad actor site were able to claim to be part of a set and gain the privileges that entails. Lets consider a theoretical bad actor site, `evilsite.example.com`, and look at some examples of attacks it could try to make, all of which would fail:

* **`evilsite.example.com` claims to be an associated site in another set**: If a site claiming to be in a set (`i.e.` by listing a primary in a `.well-known` file) is not included in the set submission and/or primary's `.well-known` file, it won't get the benefits of being in the set.
* **`evilsite.example.com` claims to be a primary site, and submits a set that includes some would-be victim sites**: The submission process requires that `.well-known` files hosted by non-primary sites explicitly list out their primary. If this primary doesn't match the set submission (i.e. if the associated/service sites expect to have a different primary, or don't expect to be in a set at all), the submission will be rejected.
* **`site1.example.com` and `site2.example.com` are intentionally in the same set, but `site1.example.com` gets hijacked by `evilsite.example.com`**: The impact of a site hijacking attack within a set isn't any worse than it would usually be, once the other sites are updated accordingly:
    + The regular Storage Access API requires an active opt-in by the embedded site, so `site2.example.com` can stop calling `document.requestStorageAccess()` when it's embedded in `site1.example.com`, avoiding a CSRF attack.
    + Use of `requestStorageAccessFor()` requires CORS, so `site2.example.com` could choose not to respond with the appropriate CORS headers when network requests are coming from `site1.example.com`, thereby avoiding a CSRF attack.
Examples
--------

* The Related Website Sets demo demonstrates how RWS is used.
* Also see Using the Storage Access API.
Specifications
--------------

| Specification |
| --- |
| User Agent Interaction with Related Website Sets  |

### Standards positions

One or more vendors oppose this specification. Known positions are as follows:

* Mozilla (Firefox): Negative
* Apple (Safari): Negative
See also
--------

* Storage Access API
* Related Website Sets on developer.chrome.com (2023)
* Related Website Sets: developer guide on developer.chrome.com (2023)


DeviceOrientationEvent: gamma property - Web APIs

DeviceOrientationEvent: gamma property
======================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`gamma`** read-only property of the `DeviceOrientationEvent` interface returns the rotation of the device around the Y axis; that is, the number of degrees,
 ranged between `-90` and `90`, by which the device is tilted left
 or right.
 See Orientation and motion data explained for details.

Value
-----

A number.

Specifications
--------------

| Specification |
| --- |
| DeviceOrientation Event Specification # ref-for-dom-deviceorientationevent-gamma② |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Detecting device orientation
* Orientation and motion data explained
* `deviceorientation` event
* `deviceorientationabsolute` event


DeviceOrientationEvent: absolute property - Web APIs

DeviceOrientationEvent: absolute property
=========================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`absolute`** read-only property of the `DeviceOrientationEvent` interface indicates whether or not the device is providing orientation data absolutely (that is,
 in reference to the Earth's coordinate frame) or using some arbitrary frame determined
 by the device.
 See Orientation and motion data explained for details.

Value
-----

* `true` if the orientation data in `instanceOfDeviceOrientationEvent` is provided as the difference between the Earth's coordinate frame and the device's coordinate frame
* `false` if the orientation data is being provided in reference to some arbitrary, device-determined coordinate frame.
Specifications
--------------

| Specification |
| --- |
| DeviceOrientation Event Specification # ref-for-dom-deviceorientationevent-absolute |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Detecting device orientation
* Orientation and motion data explained
* `deviceorientation` event
* `deviceorientationabsolute` event


DeviceOrientationEvent: alpha property - Web APIs

DeviceOrientationEvent: alpha property
======================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`alpha`** read-only property of the `DeviceOrientationEvent` interface returns the rotation of the device around the Z axis; that is, the number of degrees by
 which the device is being twisted around the center of the screen.
 See Orientation and motion data explained for details.

Value
-----

A number.

Specifications
--------------

| Specification |
| --- |
| DeviceOrientation Event Specification # ref-for-dom-deviceorientationevent-alpha③ |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Detecting device orientation
* Orientation and motion data explained
* `deviceorientation` event
* `deviceorientationabsolute` event


DeviceOrientationEvent: DeviceOrientationEvent() constructor - Web APIs

DeviceOrientationEvent: DeviceOrientationEvent() constructor
============================================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

The **`DeviceOrientationEvent()`** constructor creates a new `DeviceOrientationEvent` object.

Syntax
------

```js
new DeviceOrientationEvent(type)
new DeviceOrientationEvent(type, options)
```

### Parameters

`type`

 A string with the name of the event.
 It is case-sensitive and browsers set it to `deviceorientation` or `deviceorientationabsolute`.
 In the latter case, `options.absolute` is always `true`.

`options` Optional

An object that, *in addition of the properties defined in `Event()`*, can have the following properties:

`alpha` Optional

 A number representing the motion of the device around the z axis,
 expressed in degrees with values ranging from 0 to 360.
 It defaults to `null`.

`beta` Optional

 A number representing the motion of the device around the x axis,
 expressed in degrees with values ranging from -180 to 180.
 This represents a front to back motion of the device.
 It defaults to `null`.

`gamma` Optional

 A number representing the motion of the device around the y axis,
 expressed in degrees with values ranging from -90 to 90.
 This represents a left to right motion of the device.
 It defaults to `null`.

`absolute`

 A boolean value that indicates whether or not the device is providing orientation data absolutely.
 It defaults to `false`.

Return value
------------

A new `DeviceOrientationEvent` object.

Specifications
--------------

| Specification |
| --- |
| DeviceOrientation Event Specification # dom-deviceorientationevent-deviceorientationevent |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


DeviceOrientationEvent: beta property - Web APIs

DeviceOrientationEvent: beta property
=====================================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`beta`** read-only property of the `DeviceOrientationEvent` interface returns the rotation of the device around the X axis; that is, the number of degrees,
 ranged between -180 and 180, by which the device is tipped forward or backward.
 See Orientation and motion data explained for details.

Value
-----

A number.

Specifications
--------------

| Specification |
| --- |
| DeviceOrientation Event Specification # ref-for-dom-deviceorientationevent-beta② |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Detecting device orientation
* Orientation and motion data explained
* `deviceorientation` event
* `deviceorientationabsolute` event


LockManager: query() method - Web APIs

LockManager: query() method
===========================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

The **`query()`** method of the `LockManager` interface returns a `Promise` that resolves with an object containing information about held and pending locks.

**Note:** This feature is available in Web Workers

Syntax
------

```js
query()
```

### Parameters

None.

### Return value

 A `Promise` that resolves with an object containing a snapshot of the `LockManager` state.
 The object has the following properties:

`held`

An array of `LockInfo` objects for held locks.

`pending`

An array of `LockInfo` objects for pending lock requests.

The `LockInfo` object can have the following properties:

`name`

The name passed to `LockManager.request()` when the lock was requested.

`mode`

The access mode passed to `LockManager.request()` when the lock was requested. The mode is either `"exclusive"` or `"shared"`.

`clientId`

The unique identity of the context where `LockManager.request()` is called. This is the same value as `Client.id`.

### Exceptions

This method may return a promise rejected with a `DOMException` of one of the following types:

`InvalidStateError` `DOMException`

Thrown if the environments document is not fully active.

`SecurityError` `DOMException`

Thrown if a lock manager cannot be obtained for the current environment.

Examples
--------

```js
const state = await navigator.locks.query();
for (const lock of state.held) {
  console.log(`held lock: name ${lock.name}, mode ${lock.mode}`);
}
for (const request of state.pending) {
  console.log(`requested lock: name ${request.name}, mode ${request.mode}`);
}
```

Specifications
--------------

| Specification |
| --- |
| Web Locks API # api-lock-manager-query |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


LockManager: request() method - Web APIs

LockManager: request() method
=============================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`request()`** method of the `LockManager` interface requests a `Lock` object with parameters specifying its name and characteristics.
 The requested `Lock` is passed to a callback, while the function itself returns a `Promise` that resolves (or rejects) with the result of the callback after the lock is released, or rejects if the request is aborted.

The `mode` property of the `options` parameter may be either `"exclusive"` or `"shared"`.

 Request an `"exclusive"` lock when it should only be held by one code instance at a time.
 This applies to code in both tabs and workers. Use this to represent mutually exclusive access to a resource.
 When an `"exclusive"` lock for a given name is held, no other lock with the same name can be held.

 Request a `"shared"` lock when multiple instances of the code can share access to a resource.
 When a `"shared"` lock for a given name is held, other `"shared"` locks for the same name can be granted, but no `"exclusive"` locks with that name can be held or granted.

 This shared/exclusive lock pattern is common in database transaction architecture, for example to allow multiple simultaneous readers (each requests a `"shared"` lock) but only one writer (a single `"exclusive"` lock).
 This is known as the readers-writer pattern.
 In the IndexedDB API, this is exposed as `"readonly"` and `"readwrite"` transactions which have the same semantics.

**Note:** This feature is available in Web Workers

Syntax
------

```js
request(name, callback)
request(name, options, callback)
```

### Parameters

`name`

An identifier for the lock you want to request.

`options` Optional

 An object describing characteristics of the lock you want to create.
 Valid values are:

`mode` Optional

 Either `"exclusive"` or `"shared"`.
 The default value is `"exclusive"`.

`ifAvailable` Optional

 If `true`, the lock request will only be granted if it is not already held.
 If it cannot be granted, the callback will be invoked with `null` instead of a `Lock` instance.
 The default value is `false`.

`steal` Optional

 If `true`, then any held locks with the same name will be released, and the request will be granted, preempting any queued requests for it.
 The default value is `false`.

**Warning:** Use with care!
 Code that was previously running inside the lock continues to run, and may clash with the code that now holds the lock.

`signal` Optional

 An `AbortSignal` (the `signal` property of an `AbortController`);
 if specified and the `AbortController` is aborted, the lock request is dropped if it was not already granted.

`callback`

 Method called when the lock is granted.
 The lock is automatically released when the callback returns (or an exception is thrown).
 Usually the callback is an async function, which causes the lock to be released only when the async function has completely finished.

### Return value

A `Promise` that resolves (or rejects) with the result of the callback after the lock is released, or rejects if the request is aborted.

### Exceptions

This method may return a promise rejected with a `DOMException` of one of the following types:

`InvalidStateError` `DOMException`

Thrown if the environments document is not fully active.

`SecurityError` `DOMException`

Thrown if a lock manager cannot be obtained for the current environment.

`NotSupportedError` `DOMException`

Thrown if `name` starts with a hyphen (`-`), both options `steal` and `ifAvailable` are `true`, or if option `signal` exists and *either* option `steal` or `ifAvailable` is `true`.

`AbortError` `DOMException`

Thrown if the option `signal` exists and is aborted.

Examples
--------

### General Example

 The following example shows the basic use of the `request()` method with an asynchronous function as the callback.
 Once the callback is invoked, no other running code on this origin can hold `my_resource` until the callback returns.

```js
await navigator.locks.request("my\_resource", async (lock) => {
  // The lock was granted.
});
```

### `mode` example

The following example shows how to use the `mode` option for readers and writers.

 Notice that both functions use a lock called `my_resource`.
 The `do_read()` requests a lock in `'shared'` mode meaning that multiple calls may occur simultaneously across different event handlers, tabs, or workers.

```js
async function do\_read() {
  await navigator.locks.request(
    "my\_resource",
    { mode: "shared" },
    async (lock) => {
      // Read code here.
    },
  );
}
```

 The `do_write()` function use the same lock but in `'exclusive'` mode which will delay invocation of the `request()` call in `do_read()` until the write operation has completed.
 This applies across event handlers, tabs, or workers.

```js
async function do\_write() {
  await navigator.locks.request(
    "my\_resource",
    { mode: "exclusive" },
    async (lock) => {
      // Write code here.
    },
  );
}
```

### `ifAvailable` example

 To grab a lock only if it isn't already being held, use the `ifAvailable` option.
 In this function `await` means the method will not return until the callback is complete.
 Since the lock is only granted if it was available, this call avoids needing to wait on the lock being released elsewhere.

```js
await navigator.locks.request(
  "my\_resource",
  { ifAvailable: true },
  async (lock) => {
    if (!lock) {
      // The lock was not granted - get out fast.
      return;
    }

    // The lock was granted, and no other running code in this origin is holding
    // the 'my\_res\_lock' lock until this returns.
  },
);
```

### `signal` example

To only wait for a lock for a short period of time, use the `signal` option.

```js
const controller = new AbortController();
// Wait at most 200ms.
setTimeout(() => controller.abort(), 200);

try {
  await navigator.locks.request(
    "my\_resource",
    { signal: controller.signal },
    async (lock) => {
      // The lock was acquired!
    },
  );
} catch (ex) {
  if (ex.name === "AbortError") {
    // The request aborted before it could be granted.
  }
}
```

Specifications
--------------

| Specification |
| --- |
| Web Locks API # api-lock-manager-request |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


SpeechRecognitionResultList: length property - Web APIs

SpeechRecognitionResultList: length property
============================================

 The **`length`** read-only property of the
 `SpeechRecognitionResultList` interface returns the length of the
 "array" — the number of `SpeechRecognitionResult` objects in the
 list.

Value
-----

A number.

Examples
--------

 This code is excerpted from our
 Speech color changer example.

```js
recognition.onresult = (event) => {
  // The SpeechRecognitionEvent results property returns a SpeechRecognitionResultList object
  // The SpeechRecognitionResultList object contains SpeechRecognitionResult objects.
  // It has a getter so it can be accessed like an array
  // The first [0] returns the SpeechRecognitionResult at position 0.
  // Each SpeechRecognitionResult object contains SpeechRecognitionAlternative objects
  // that contain individual results.
  // These also have getters so they can be accessed like arrays.
  // The second [0] returns the SpeechRecognitionAlternative at position 0.
  // We then return the transcript property of the SpeechRecognitionAlternative object
  const color = event.results[0][0].transcript;
  diagnostic.textContent = `Result received: ${color}.`;
  bg.style.backgroundColor = color;

  console.log(event.results.length);
};
```

Specifications
--------------

| Specification |
| --- |
| Web Speech API # dom-speechrecognitionresultlist-length |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Speech API


SpeechRecognitionResultList: item() method - Web APIs

SpeechRecognitionResultList: item() method
==========================================

 The **`item`** getter of the
 `SpeechRecognitionResultList` interface is a standard getter — it allows
 `SpeechRecognitionResult` objects in the list to be accessed via array
 syntax.

Syntax
------

```js
item(index)
```

### Parameters

`index`

Index of the item to retrieve.

### Return value

A `SpeechRecognitionResult` object.

Examples
--------

 This code is excerpted from our
 Speech color changer example.

```js
recognition.onresult = (event) => {
  // The SpeechRecognitionEvent results property returns a SpeechRecognitionResultList object
  // The SpeechRecognitionResultList object contains SpeechRecognitionResult objects.
  // It has a getter so it can be accessed like an array
  // The first [0] returns the SpeechRecognitionResult at position 0.
  // Each SpeechRecognitionResult object contains SpeechRecognitionAlternative objects
  // that contain individual results.
  // These also have getters so they can be accessed like arrays.
  // The second [0] returns the SpeechRecognitionAlternative at position 0.
  // We then return the transcript property of the SpeechRecognitionAlternative object
  const color = event.results[0][0].transcript;
  diagnostic.textContent = `Result received: ${color}.`;
  bg.style.backgroundColor = color;
};
```

Specifications
--------------

| Specification |
| --- |
| Web Speech API # dom-speechrecognitionresultlist-item |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Speech API


CSSScale: z property - Web APIs

CSSScale: z property
====================

 The **`z`** property of the
 `CSSScale` interface representing the z-component of the translating
 vector. A positive value moves the element towards the viewer, and a negative value
 farther away.

 If this value is present then the transform is a 3D transform and the `is2D`
 property will be set to false.

Value
-----

A double integer or a `CSSNumericValue`

Examples
--------

To Do

Specifications
--------------

| Specification |
| --- |
| CSS Typed OM Level 1 # dom-cssscale-z |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


CSSScale: x property - Web APIs

CSSScale: x property
====================

 The **`x`** property of the
 `CSSScale` interface gets and sets the abscissa or x-axis of the
 translating vector.

Value
-----

A double integer or a `CSSNumericValue`

Examples
--------

To Do

Specifications
--------------

| Specification |
| --- |
| CSS Typed OM Level 1 # dom-cssscale-x |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


CSSScale: y property - Web APIs

CSSScale: y property
====================

 The **`y`** property of the
 `CSSScale` interface gets and sets the ordinate or y-axis of the
 translating vector.

Value
-----

A double integer or a `CSSNumericValue`

Examples
--------

To Do

Specifications
--------------

| Specification |
| --- |
| CSS Typed OM Level 1 # dom-cssscale-y |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


CSSScale: CSSScale() constructor - Web APIs

CSSScale: CSSScale() constructor
================================

 The **`CSSScale()`** constructor creates a new
 `CSSScale` object representing the scale() and scale3d() values of the
 individual `transform` property in CSS.

Syntax
------

```js
new CSSScale(x, y)
new CSSScale(x, y, z)
```

### Parameters

`x`

 A value for the x-axis of the `CSSScale` object to be constructed. This
 must either be a double integer or a `CSSNumericValue`.

`y`

 A value for the y-axis of the `CSSScale` object to be constructed. This
 must either be a double integer or a `CSSNumericValue`.

`z` Optional

 A value for the z-axis of the `CSSScale` object to be constructed. This
 must either be a double integer or a `CSSNumericValue`. If a value is
 passed for the `z-axis` this is a 3d transform. The value of
 `is2D` will be set to false.

Examples
--------

To do

Specifications
--------------

| Specification |
| --- |
| CSS Typed OM Level 1 # dom-cssscale-cssscale |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCEncodedVideoFrame: timestamp property - Web APIs

RTCEncodedVideoFrame: timestamp property
========================================

The readonly **`timestamp`** property of the `RTCEncodedVideoFrame` interface indicates the time at which frame sampling started.

Value
-----

A positive integer containing the sampling instant of the first byte in this frame, in microseconds.

Specifications
--------------

| Specification |
| --- |
| WebRTC Encoded Transform # dom-rtcencodedvideoframe-timestamp |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using WebRTC Encoded Transforms


RTCEncodedVideoFrame: data property - Web APIs

RTCEncodedVideoFrame: data property
===================================

The **`data`** property of the `RTCEncodedVideoFrame` interface returns a buffer containing the frame data.

Value
-----

An `ArrayBuffer`.

Examples
--------

This example WebRTC encoded transform shows how you might get the frame data in a `TransformStream` `transform()` function and negate all the bits.

 The `transform()` function constructs a `DataView` on the buffer in the frame `data` property, and also creates a view on a new `ArrayBuffer`.
 It then writes the inverted bytes in the original data to the new buffer, assigns the buffer to the encoded frame `data` property, and enqueues the modified frame on the stream.

```js
addEventListener("rtctransform", (event) => {
  const transform = new TransformStream({
    async transform(encodedFrame, controller) {
      // Reconstruct the original frame.
      const view = new DataView(encodedFrame.data);

      // Construct a new buffer
      const newData = new ArrayBuffer(encodedFrame.data.byteLength);
      const newView = new DataView(newData);

      // Negate all bits in the incoming frame
      for (let i = 0; i < encodedFrame.data.byteLength; ++i) {
        newView.setInt8(i, ~view.getInt8(i));
      }

      encodedFrame.data = newData;
      controller.enqueue(encodedFrame);
    },
  });
  event.transformer.readable
    .pipeThrough(transform)
    .pipeTo(event.transformer.writable);
});
```

Note that the surrounding code shown here is described in Using WebRTC Encoded Transforms.

Specifications
--------------

| Specification |
| --- |
| WebRTC Encoded Transform # dom-rtcencodedvideoframe-data |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using WebRTC Encoded Transforms


RTCEncodedVideoFrame: getMetadata() method - Web APIs

RTCEncodedVideoFrame: getMetadata() method
==========================================

The **`getMetadata()`** method of the `RTCEncodedVideoFrame` interface returns an object containing the metadata associated with the frame.

This includes information about the frame, including its size, video encoding, other frames needed to construct a full image, timestamp, and other information.

Syntax
------

```js
getMetadata()
```

### Parameters

None.

### Return value

An object with the following properties:

`frameId`

A positive integer value indicating the id of this frame.

`dependencies`

 An `Array` of positive integers indicating the frameIds of frames on which this frame depends.
 For a key frame this will be empty, as a key frame contains all the information it needs to construct the image.
 For a delta frame this will list all the frames needed to render this frame.
 The type of frame can be determined using `RTCEncodedVideoFrame.type`.

`width`

 A positive integer indicating the width of the frame.
 The maximum value is 65535.

`height`

 A positive integer indicating the height of the frame.
 The maximum value is 65535.

`spatialIndex`

 A positive integer indicating the spatial index of the frame.
 Some codecs allow generation of layers of frames with different layers of resolutions.
 Frames in higher layers can be selectively dropped in order to reduce bit rate when needed, while maintaining acceptable video quality.

`temporalIndex`

 A positive integer indicating the temporal index of the frame.
 Some codecs group frames in layers, based on whether dropping the a frame will prevent others from being decoded.
 Frames in higher layers can be selectively dropped in order to reduce bit rate when needed, while maintaining acceptable video quality.

`synchronizationSource`

 A positive integer value indicating synchronization source ("ssrc") of the stream of RTP packets that are described by this encoded video frame.
 A source might be something like a camera or microphone, or some kind of mixer app that combines multiple sources.
 All packets from the same source share the same time source and sequence space, and so can be ordered relative to each other.
 Note two frames with the same value refer to the same source (for more information see `RTCRtpStreamStats.ssrc`).

`payloadType`

 A positive integer value in the range from 0 to 127 that describes the format of the RTP payload.
 The mappings of values to formats is defined in RFC3550.

`contributingSources`

 An `Array` of sources (ssrc) that have contributed to the frame.
 Consider the case of a conferencing application that combines the audio and video from multiple users.
 The `synchronizationSource` would include the ssrc of the application, while `contributingSources` would include the ssrc values of all the individual video and audio sources.

`timestamp`

 The media presentation timestamp (PTS) in microseconds of raw frame, matching the timestamp for raw frames which correspond to this frame.
 This is used to synchronize separate video, audio, subtitle and other streams belonging to the same presentation.

Examples
--------

This example WebRTC encoded transform implementation shows how you might get the frame metadata in a `transform()` function and log it.

```js
addEventListener("rtctransform", (event) => {
  const async transform = new TransformStream({
    async transform(encodedFrame, controller) {

      // Get the metadata and log
      const frameMetaData = encodedFrame.getMetadata();
      console.log(frameMetaData)

      // Enqueue the frame without modifying
      controller.enqueue(encodedFrame);
    },
  });
  event.transformer.readable
    .pipeThrough(transform)
    .pipeTo(event.transformer.writable);
});
```

 The resulting object from a local webcam might look like the one shown below.
 Note that there are no contributing sources because there is just one source.

```js
{
  "contributingSources": [],
  "dependencies": [
    405
  ],
  "frameId": 406,
  "height": 480,
  "payloadType": 120,
  "spatialIndex": 0,
  "synchronizationSource": 3956716931,
  "temporalIndex": 0,
  "width": 640
}
```

Specifications
--------------

| Specification |
| --- |
| WebRTC Encoded Transform # dom-rtcencodedvideoframe-getmetadata |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using WebRTC Encoded Transforms


RTCEncodedVideoFrame: type property - Web APIs

RTCEncodedVideoFrame: type property
===================================

The readonly **`type`** property of the `RTCEncodedVideoFrame` interface indicates whether this frame is a key frame, delta frame, or empty frame.

Value
-----

The type can have one of the following values:

`key`

 This is a "key frame", which contains all the information needed to render an image.
 It can be decoded without reference to any other frames.

`delta`

 This is a "delta frame", which contains changes to an image relative to some previous frame.
 The frame cannot be decoded without access to the frame(s) that it references.

`empty`

 This frame contains no data.
 This value is unexpected, and may indicate that the transform is holding a reference to frames after they have been transformed and piped to `RTCRtpScriptTransformer.writable` (after transferring back to the main-thread WebRTC pipeline the worker side frame object will have no data).

Examples
--------

The implementation of a `transform()` function in a WebRTC Encoded Transform can look at the `type` and modify the transform code based on whether it is dealing with a key frame or delta frame:

```js
const transformer = new TransformStream({
  transform: async (encodedFrame, controller) => {
    if (encodedFrame.type === "key") {
      // Apply key frame transformation
    } else if (encodedFrame.type === "delta") {
      // Apply delta frame transformation
    } else {
      // Empty
      // Check transform is not holding reference to frames after processing!
    }
    controller.enqueue(encodedFrame);
  },
});
```

Specifications
--------------

| Specification |
| --- |
| WebRTC Encoded Transform # dom-rtcencodedvideoframe-type |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using WebRTC Encoded Transforms


Animation: reverse() method - Web APIs

Animation: reverse() method
===========================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`Animation.reverse()`** method of the `Animation` Interface reverses the playback direction, meaning the animation ends at its beginning. If called on an unplayed animation, the whole animation is played backwards. If called on a paused animation, the animation will continue in reverse.

Syntax
------

```js
reverse()
```

### Parameters

None.

### Return value

None (`undefined`).

Examples
--------

In the Growing/Shrinking Alice Game example, clicking or tapping the bottle causes Alice's growing animation (`aliceChange`) to play backwards, causing her to get smaller. It is done by setting `aliceChange`'s `Animation.playbackRate` to `-1` like so:

```js
const shrinkAlice = () => {
  // play Alice's animation in reverse
  aliceChange.playbackRate = -1;
  aliceChange.play();

  // play the bottle's animation
  drinking.play();
};
```

But it could also have been done by calling `reverse()` on `aliceChange` like so:

```js
const shrinkAlice = () => {
  // play Alice's animation in reverse
  aliceChange.reverse();

  // play the bottle's animation
  drinking.play();
};
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-reverse |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation` for other methods and properties you can use to control web page animation.
* `Animation.pause()` to pause an animation.
* `Animation.play()` to move an animation forward.


Animation: id property - Web APIs

Animation: id property
======================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`Animation.id`** property of the Web Animations API returns or sets a string used to identify the animation.

Value
-----

A string which can be used to identify the animation, or `null` if the animation has no `id`.

Examples
--------

In the Follow the White Rabbit example, you can assign the `rabbitDownAnimation` an `id` like so:

```js
rabbitDownAnimation.id = "rabbitGo";
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-id |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `KeyframeEffect`
* Web Animations API
* `Animation`


Animation: finished property - Web APIs

Animation: finished property
============================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`Animation.finished`** read-only property of the Web Animations API returns a `Promise` which resolves once the animation has finished playing.

**Note:** Every time the animation leaves the `finished` play state (that is, when it starts playing again), a new `Promise` is created for this property. The new `Promise` will resolve once the new animation sequence has completed.

Value
-----

A `Promise` object which will resolve once the animation has finished running.

Examples
--------

The following code waits until all animations running on the element `elem` have finished, then deletes the element from the DOM tree:

```js
Promise.all(elem.getAnimations().map((animation) => animation.finished)).then(
  () => elem.remove(),
);
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-finished |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `KeyframeEffect`
* Web Animations API
* `Animation`


Animation: Animation() constructor - Web APIs

Animation: Animation() constructor
==================================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`Animation()`** constructor of the Web Animations API returns a new `Animation` object instance.

Syntax
------

```js
new Animation()
new Animation(effect)
new Animation(effect, timeline)
```

### Parameters

`effect` Optional

The target effect, as an object based on the `AnimationEffect` interface, to assign to the animation. Although in the future other effects such as `SequenceEffect`s or `GroupEffect`s might be possible, the only kind of effect currently available is `KeyframeEffect`. This can be `null` (which is the default) to indicate that there should be no effect applied.

`timeline` Optional

Specifies the `timeline` with which to associate the animation, as an object of a type based on the `AnimationTimeline` interface. Currently the only timeline type available is `DocumentTimeline`, but in the future there may be timelines associated with gestures or scrolling, for example. The default value is `Document.timeline`, but this can be set to `null` as well.

Examples
--------

In the Follow the White Rabbit example, the `Animation()` constructor is used to create an `Animation` for the `rabbitDownKeyframes` using the document's `timeline`:

```js
const rabbitDownAnimation = new Animation(
  rabbitDownKeyframes,
  document.timeline,
);
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-animation |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation`


Animation: commitStyles() method - Web APIs

Animation: commitStyles() method
================================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The `commitStyles()` method of the Web Animations API's `Animation` interface writes the computed values of the animation's current styles into its target element's `style` attribute. `commitStyles()` works even if the animation has been automatically removed.

`commitStyles()` can be used in combination with `fill` to cause the final state of an animation to persist after the animation ends. The same effect could be achieved with `fill` alone, but using indefinitely filling animations is discouraged. Animations take precedence over all static styles, so an indefinite filling animation can prevent the target element from ever being styled normally.

Using `commitStyles()` writes the styling state into the element's `style` attribute, where they can be modified and replaced as normal.

Syntax
------

```js
commitStyles()
```

### Parameters

None.

### Return value

None (`undefined`).

Examples
--------

### Committing the final state of an animation

In this example we have two buttons, labeled "Commit styles" and "Fill forwards". Both buttons animate when you click them, and both buttons persist the final state of the animation.

The difference, though, is that "Fill forwards" only uses `fill: "forwards"` to persist the animation's final state: this means that the browser has to maintain the animation's state indefinitely, or until it can be automatically removed.

However, the "Commit styles" button waits for the animation to finish, then calls `commitStyles()`, then cancels the animation, so the finished style is captured as the value of the `style` attribute, rather than as the animation state.

#### HTML

```html
<button class="commit-styles">Commit styles</button>
<br />
<button class="fill-forwards">Fill forwards</button>
```

```
button {
  margin: 0.5rem;
}
```

#### JavaScript

```js
const commitStyles = document.querySelector(".commit-styles");
let offset1 = 0;

commitStyles.addEventListener("click", async (event) => {
  // Start the animation
  offset1 = 100 - offset1;
  const animation = commitStyles.animate(
    { transform: `translate(${offset1}px)` },
    { duration: 500, fill: "forwards" },
  );

  // Wait for the animation to finish
  await animation.finished;
  // Commit animation state to style attribute
  animation.commitStyles();
  // Cancel the animation
  animation.cancel();
});

const fillForwards = document.querySelector(".fill-forwards");
let offset2 = 0;

fillForwards.addEventListener("click", async (event) => {
  // Start the animation
  offset2 = 100 - offset2;
  const animation = fillForwards.animate(
    { transform: `translate(${offset2}px)` },
    { duration: 500, fill: "forwards" },
  );
});
```

#### Result

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-commitstyles |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation` for other methods and properties you can use to control web page animation.


Animation: cancel() method - Web APIs

Animation: cancel() method
==========================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The Web Animations API's **`cancel()`** method of the `Animation` interface clears all `KeyframeEffect`s caused by this animation and aborts its playback.

**Note:** When an animation is cancelled, its `startTime` and `currentTime` are set to `null`.

Syntax
------

```js
cancel()
```

### Parameters

None.

### Return value

None (`undefined`).

### Exceptions

This method doesn't directly throw exceptions; however, if the animation's `playState` is anything but `"idle"` when cancelled, the current finished promise is rejected with a `DOMException` named `AbortError`.

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-cancel |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `KeyframeEffect`
* `Animation`
* `Animation.playState`
* `Animation.finished` returns the promise this action will reject if the animation's `playState` is not `"idle"`.


Animation: finish() method - Web APIs

Animation: finish() method
==========================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`finish()`** method of the Web Animations API's `Animation` Interface sets the current playback time to the end of the animation corresponding to the current playback direction.

That is, if the animation is playing forward, it sets the playback time to the length of the animation sequence, and if the animation is playing in reverse (having had its `reverse()` method called), it sets the playback time to 0.

Syntax
------

```js
finish()
```

### Parameters

None.

### Return value

None (`undefined`).

### Exceptions

`InvalidState`

The player's playback rate is 0 or the animation's playback rate is greater than 0 and the end time of the animation is infinity.

Examples
--------

The following example shows how to use the `finish()` method and catch an `InvalidState` error.

```js
interfaceElement.addEventListener("mousedown", () => {
  try {
    player.finish();
  } catch (e) {
    if (e instanceof InvalidState) {
      console.log("finish() called on paused or finished animation.");
    } else {
      logMyErrors(e); //pass exception object to error handler
    }
  }
});
```

The following example finishes all the animations on a single element, regardless of their direction of playback.

```js
elem.getAnimations().forEach((animation) => animation.finish());
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-finish |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation` for other methods and properties you can use to control web page animation.
* `Animation.play()` to play an animation forward.
* `Animation.reverse()` to play an animation backward.


Animation: persist() method - Web APIs

Animation: persist() method
===========================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The `persist()` method of the Web Animations API's `Animation` interface explicitly persists an animation, preventing it from being automatically removed when it is replaced by another animation.

Syntax
------

```js
persist()
```

### Parameters

None.

### Return value

None (`undefined`).

Examples
--------

### Using `persist()`

In this example, we have three buttons:

* "Add persistent animation" and "Add transient animation" each add a new transform animation to the red square. The animations alternate direction: so the first is left to right, the second is right to left, and so on. "Add persistent animation" calls `persist()` on the animation it creates.
* The third button, "Cancel an animation", cancels the most recently added animation.

The example displays a list of all animations that have not been canceled, in the order they were added, along with each animation's `replaceState`.

#### HTML

```html
<div id="animation-target"></div>
<button id="start-persistent">Add persistent animation</button>
<button id="start-transient">Add transient animation</button>
<button id="cancel">Cancel an animation</button>
<ol id="stack"></ol>
```

```
<template id="list-item-template">
  <li>
    <span class="replaceState"></span>,
    <span class="description"></span>
  </li>
</template>
```

#### CSS

```css
div {
  width: 100px;
  height: 100px;
  background: red;
  transform: translate(100px);
}
```

#### JavaScript

```js
const target = document.getElementById("animation-target");
const persistentButton = document.getElementById("start-persistent");
const transientButton = document.getElementById("start-transient");
const cancelButton = document.getElementById("cancel");
persistentButton.addEventListener("click", () => startAnimation(true));
transientButton.addEventListener("click", () => startAnimation(false));
cancelButton.addEventListener("click", cancelTop);
const stack = [];

let offset = -100;

function startAnimation(persist) {
  offset = -offset;
  const animation = target.animate(
    { transform: `translate(${100 + offset}px)` },
    { duration: 500, fill: "forwards" },
  );
  stack.push(animation);
  if (persist) {
    animation.persist();
  }
  // Add the animation to the displayed stack (implementation not shown)
  show(animation, offset);
}

function cancelTop() {
  stack.pop()?.cancel();
}
```

```
const stackDisplay = document.getElementById("stack");
const template =
  document.getElementById("list-item-template").content.firstElementChild;
const nodes = new Map();

function show(animation, offset) {
  const direction = offset < 0 ? "left" : "right";
  const li = template.cloneNode(true);
  const description = li.querySelector(".description");
  const replaceState = li.querySelector(".replaceState");
  description.textContent = direction;
  replaceState.textContent = animation.replaceState;
  nodes.set(animation, { li, description, replaceState });
  stackDisplay.append(li);
  animation.addEventListener("cancel", () => {
    nodes.get(animation).li.remove();
    nodes.delete(animation);
  });
  animation.addEventListener("remove", () => {
    nodes.get(animation).replaceState.textContent = animation.replaceState;
  });
}
```

#### Result

Note that adding a new transient animation will replace any previously added transient animation. Those animations will be automatically removed, and their `replaceState` will be `"removed"`. However, persistent animations will not be removed.

Also note that removed animations don't affect the display; the position of the `<div>` is determined by the most recent active or persisted animation.

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-persist |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation` for other methods and properties you can use to control web page animation.
* `Animation.replaceState`
* `remove` event


Animation: startTime property - Web APIs

Animation: startTime property
=============================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`Animation.startTime`** property of the `Animation` interface is a double-precision floating-point value which indicates the scheduled time when an animation's playback should begin.

An animation's **start time** is the time value of its `timeline` when its target `KeyframeEffect` is scheduled to begin playback. An animation's **start time** is initially unresolved (meaning that it's `null` because it has no value).

Value
-----

A floating-point number representing the current time in milliseconds, or `null` if no time is set. You can read this value to determine what the start time is currently set at, and you can change this value to make the animation start at a different time.

Examples
--------

In the Running on Web Animations API example, we can sync all new animated cats by giving them all the same `startTime` as the original running cat:

```js
const catRunning = document
  .getElementById("withWAAPI")
  .animate(keyframes, timing);

/\* A function that makes new cats. \*/
function addCat() {
  const newCat = document.createElement("div");
  newCat.classList.add("cat");
  return newCat;
}

/\* This is the function that adds a cat to the WAAPI column \*/
function animateNewCatWithWAAPI() {
  // make a new cat
  const newCat = addCat();

  // animate said cat with the WAAPI's "animate" function
  const newAnimationPlayer = newCat.animate(keyframes, timing);

  // set the animation's start time to be the same as the original .cat#withWAAPI
  newAnimationPlayer.startTime = catRunning.startTime;

  // Add the cat to the pile.
  WAAPICats.appendChild(newCat);
}
```

Reduced time precision
----------------------

 To offer protection against timing attacks and fingerprinting, the precision of `animation.startTime` might get rounded depending on browser settings.
 In Firefox, the `privacy.reduceTimerPrecision` preference is enabled by default and defaults to 20 µs in Firefox 59; in 60 it will be 2 ms.

```js
// reduced time precision (2ms) in Firefox 60
animation.startTime;
// 23.404
// 24.192
// 25.514
// …

// reduced time precision with `privacy.resistFingerprinting` enabled
animation.startTime;
// 49.8
// 50.6
// 51.7
// …
```

In Firefox, you can also enabled `privacy.resistFingerprinting`, the precision will be 100ms or the value of `privacy.resistFingerprinting.reduceTimerPrecision.microseconds`, whichever is larger.

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-starttime |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation`
* `Animation.currentTime` for the current time of the animation.


Animation: ready property - Web APIs

Animation: ready property
=========================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The read-only **`Animation.ready`** property of the Web Animations API returns a `Promise` which resolves when the animation is ready to play. A new promise is created every time the animation enters the `"pending"` play state as well as when the animation is canceled, since in both of those scenarios, the animation is ready to be started again.

**Note:** Since the same `Promise` is used for both pending `play` and pending `pause` requests, authors are advised to check the state of the animation when the promise is resolved.

Value
-----

A `Promise` which resolves when the animation is ready to be played. You'll typically use a construct similar to this when using the ready promise:

```js
animation.ready.then(() => {
  // Do whatever needs to be done when
  // the animation is ready to run
});
```

Examples
--------

In the following example, the state of the animation will be `running` when the **current ready Promise** is resolved because the animation does not leave the `pending` play state in between the calls to `pause` and `play` and hence the **current ready Promise** does not change.

```js
animation.pause();
animation.ready.then(() => {
  // Displays 'running'
  alert(animation.playState);
});
animation.play();
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-ready |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation`
* `Animation.playState`


Animation: playState property - Web APIs

Animation: playState property
=============================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The read-only **`Animation.playState`** property of the Web Animations API returns an enumerated value describing the playback state of an animation.

Value
-----

`idle`

The current time of the animation is unresolved and there are no pending tasks.

`running`

The animation is running.

`paused`

The animation was suspended and the `Animation.currentTime` property is not updating.

`finished`

The animation has reached one of its boundaries and the `Animation.currentTime` property is not updating.

Previously, Web Animations defined a **`pending`** value to indicate that some asynchronous operation such as initiating playback was yet to complete. This is now indicated by the separate `Animation.pending` property.

Examples
--------

In the Growing/Shrinking Alice Game example, players can get an ending with Alice crying into a pool of tears. In the game, for performance reasons, the tears should only be animating when they're visible. So they must be paused as soon as they are animated like so:

```js
// Setting up the tear animations

tears.forEach((el) => {
  el.animate(tearsFalling, {
    delay: getRandomMsRange(-1000, 1000), // randomized for each tear
    duration: getRandomMsRange(2000, 6000), // randomized for each tear
    iterations: Infinity,
    easing: "cubic-bezier(0.6, 0.04, 0.98, 0.335)",
  });
  el.pause();
});

// Play the tears falling when the ending needs to be shown.

tears.forEach((el) => {
  el.play();
});

// Reset the crying tears animations and pause them.

tears.forEach((el) => {
  el.pause();
  el.currentTime = 0;
});
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-playstate |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation` for other methods and properties you can use to control web page animation.


Animation: playbackRate property - Web APIs

Animation: playbackRate property
================================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`Animation.playbackRate`** property of the Web Animations API returns or sets the playback rate of the animation.

Animations have a **playback rate** that provides a scaling factor from the rate of change of the animation's `timeline` time values to the animation's current time. The playback rate is initially `1`.

Value
-----

Takes a number that can be 0, negative, or positive. Negative values reverse the animation. The value is a scaling factor, so for example a value of 2 would double the playback rate.

**Note:** Setting an animation's `playbackRate` to `0` effectively pauses the animation (however, its `playstate` does not necessarily become `paused`).

Examples
--------

In the Growing/Shrinking Alice Game example, clicking or tapping the bottle causes Alice's growing animation (`aliceChange`) to reverse, causing her to shrink:

```js
const shrinkAlice = () => {
  aliceChange.playbackRate = -1;
  aliceChange.play();
};

// On tap or click, Alice will shrink.
bottle.addEventListener("mousedown", shrinkAlice, false);
bottle.addEventListener("touchstart", shrinkAlice, false);
```

Contrariwise, clicking on the cake causes her to "grow," playing `aliceChange` forwards again:

```js
const growAlice = () => {
  aliceChange.playbackRate = 1;
  aliceChange.play();
};

// On tap or click, Alice will grow.
cake.addEventListener("mousedown", growAlice, false);
cake.addEventListener("touchstart", growAlice, false);
```

In another example, the Red Queen's Race Game, Alice and the Red Queen are constantly slowing down:

```js
setInterval(() => {
  // Make sure the playback rate never falls below .4

  if (redQueen_alice.playbackRate > 0.4) {
    redQueen_alice.playbackRate \*= 0.9;
  }
}, 3000);
```

But clicking or tapping on them causes them to speed up by multiplying their `playbackRate`:

```js
const goFaster = () => {
  redQueen_alice.playbackRate \*= 1.1;
};

document.addEventListener("click", goFaster);
document.addEventListener("touchstart", goFaster);
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-playbackrate |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation`


Animation: updatePlaybackRate() method - Web APIs

Animation: updatePlaybackRate() method
======================================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback

 The **`updatePlaybackRate()`** method of the Web Animations API's
 `Animation` Interface sets the speed of an animation after first
 synchronizing its playback position.

 In some cases, an animation may run on a separate thread or process and will continue
 updating even while long-running JavaScript delays the main thread. In such a case,
 setting the `playbackRate` on the animation
 directly may cause the animation's playback position to jump since its playback
 position on the main thread may have drifted from the playback position where it is
 currently running.

`updatePlaybackRate()` is an asynchronous method that sets the speed of an
 animation after synchronizing with its current playback position, ensuring that the
 resulting change in speed does not produce a sharp jump. After calling
 `updatePlaybackRate()` the animation's `playbackRate` is *not* immediately updated. It will be updated once the
 animation's `ready` promise is resolved.

Syntax
------

```js
updatePlaybackRate(playbackRate)
```

### Parameters

`playbackRate`

 The new speed to set. This may be a positive number (to speed up or slow down
 the animation), a negative number (to make it play backwards), or zero (to
 effectively pause the animation).

### Return value

None (`undefined`).

Examples
--------

 A speed selector component would benefit from smooth updating of
 `updatePlaybackRate()`, as demonstrated below:

```js
speedSelector.addEventListener("input", (evt) => {
  cartoon.updatePlaybackRate(parseFloat(evt.target.value));
  cartoon.ready.then(() => {
    console.log(`Playback rate set to ${cartoon.playbackRate}`);
  });
});
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-updateplaybackrate |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation.playbackRate` — read back the current playback rate or set
 it in a synchronous manner.
* `Animation.reverse()` — invert the playback rate and restart playback
 if necessary.
* `Animation` — contains other methods and properties you can use to
 control web page animation.


Animation: effect property - Web APIs

Animation: effect property
==========================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`Animation.effect`** property of the Web Animations API gets and sets the target effect of an animation. The target effect may be either an effect object of a type based on `AnimationEffect`, such as `KeyframeEffect`, or `null`.

Value
-----

A `AnimationEffect` object describing the target animation effect for the animation, or `null` to indicate no active effect.

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-effect |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `AnimationEffect`
* `Animation`


Animation: remove event - Web APIs

Animation: remove event
=======================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`remove`** event of the `Animation` interface fires when the animation is automatically removed by the browser.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener('remove', (event) => { })
onremove = (event) => { }
```

Event type
----------

An `AnimationPlaybackEvent`. Inherits from `Event`.

Event

AnimationPlaybackEventEvent properties
----------------

*In addition to the properties listed below, properties from the parent interface, `Event`, are available.*

`AnimationPlaybackEvent.currentTime` Read only

The current time of the animation that generated the event.

`AnimationPlaybackEvent.timelineTime` Read only

The time value of the timeline of the animation that generated the event.

Examples
--------

### Removing replaced animations

In this example we have a `<button id="start">` element, and an event listener that runs whenever the mouse moves. The `mousemove` event handler sets up an animation that animates the `<button>` to the position of the mouse pointer. This could result in a huge animations list, which could create a memory leak. For this reason, modern browsers automatically remove forwards-filling animations that are overridden by other animations.

The number of animations created is displayed. A `remove` event listener is used to count and display the number of animations removed as well.

All but one of the animations should eventually be removed.

#### HTML

```html
<button id="start">Click to drag</button>
<br />
<button id="reset">Reset example</button>
<p>
  Click the button to start the animation (disabled by default to protect those
  who suffer migraines when experiencing such animations).
</p>
<p>Animations created: <span id="count-created">0</span></p>
<p>Animations removed: <span id="count-removed">0</span></p>
```

#### CSS

```css
:root,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

button {
  margin: 0.5rem 0;
}
```

#### JavaScript

```js
const button = document.querySelector("#start");
let created = 0;
let removed = 0;

button.addEventListener(
  "click",
  () => {
    document.body.addEventListener("mousemove", (event) => {
      const animation = button.animate(
        { transform: `translate(${event.clientX}px, ${event.clientY}px)` },
        { duration: 500, fill: "forwards" },
      );
      created++;
      showCounts();

      // the remove event fires after the animation is removed
      animation.addEventListener("remove", () => {
        removed++;
        showCounts();
      });
    });
  },
  { once: true },
);

function showCounts() {
  document.getElementById("count-created").textContent = created;
  document.getElementById("count-removed").textContent = removed;
}

const reset = document.querySelector("#reset");
reset.addEventListener("click", () => {
  document.location.reload();
});
```

#### Result

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-onremove |
| Web Animations # remove-event |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation`, `AnimationPlaybackEvent`
* `Animation.replaceState`, to check whether an animation has been removed
* `Animation.persist()`, to prevent removal of an animation


Animation: play() method - Web APIs

Animation: play() method
========================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`play()`** method of the Web Animations API's `Animation` Interface starts or resumes playing of an animation. If the animation is finished, calling `play()` restarts the animation, playing it from the beginning.

Syntax
------

```js
play()
```

### Parameters

None.

### Return value

None (`undefined`).

Examples
--------

In the Growing/Shrinking Alice Game example, clicking or tapping the cake causes Alice's growing animation (`aliceChange`) to play forward, causing her to get bigger, as well as triggering the cake's animation. Two `Animation.play()`s, one `EventListener`:

```js
// The cake has its own animation:
const nommingCake = document
  .getElementById("eat-me\_sprite")
  .animate(
    [{ transform: "translateY(0)" }, { transform: "translateY(-80%)" }],
    {
      fill: "forwards",
      easing: "steps(4, end)",
      duration: aliceChange.effect.timing.duration / 2,
    },
  );

// Pause the cake's animation so it doesn't play immediately.
nommingCake.pause();

// This function will play when ever a user clicks or taps
const growAlice = () => {
  // Play Alice's animation.
  aliceChange.play();

  // Play the cake's animation.
  nommingCake.play();
};

// When a user holds their mouse down or taps, call growAlice to make all the animations play.
cake.addEventListener("mousedown", growAlice, false);
cake.addEventListener("touchstart", growAlice, false);
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-play |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation` for other methods and properties you can use to control web page animation.
* `Animation.pause()` to pause an animation.
* `Animation.reverse()` to play an animation backwards.
* `Animation.finish()` to finish an animation.
* `Animation.cancel()` to cancel an animation.


Animation: pending property - Web APIs

Animation: pending property
===========================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The read-only **`Animation.pending`** property of the Web Animations API indicates whether the animation is currently waiting for an asynchronous operation such as initiating playback or pausing a running animation.

Value
-----

**`true`** if the animation is pending, **`false`** otherwise.

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-pending |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Animation` for other methods and properties you can use to control web page animation.
* Web Animations API


Animation: currentTime property - Web APIs

Animation: currentTime property
===============================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`Animation.currentTime`** property of the Web Animations API returns and sets the current time value of the animation in milliseconds, whether running or paused.

If the animation lacks a `timeline`, is inactive, or hasn't been played yet, `currentTime`'s return value is `null`.

Value
-----

A number representing the current time in milliseconds, or `null` to deactivate the animation.

Examples
--------

In the Drink Me/Eat Me game, Alice's height is animated so it can go from small to large or large to small. At the start of the game, her height is set between the two extremes by setting her animation's `currentTime` to half her `KeyframeEffect`'s duration:

```js
aliceChange.currentTime = aliceChange.effect.timing.duration / 2;
```

A more generic means of seeking to the 50% mark of an animation would be:

```js
animation.currentTime =
  animation.effect.getComputedTiming().delay +
  animation.effect.getComputedTiming().activeDuration / 2;
```

Reduced time precision
----------------------

 To offer protection against timing attacks and fingerprinting, the precision of `animation.currentTime` might get rounded depending on browser settings.
 In Firefox, the `privacy.reduceTimerPrecision` preference is enabled by default and defaults to 20 microseconds in Firefox 59; in 60 it will be 2 milliseconds.

```js
// reduced time precision (2ms) in Firefox 60
animation.currentTime;
// 23.404
// 24.192
// 25.514
// …

// reduced time precision with `privacy.resistFingerprinting` enabled
animation.currentTime;
// 49.8
// 50.6
// 51.7
// …
```

In Firefox, you can also enabled `privacy.resistFingerprinting`, the precision will be 100ms or the value of `privacy.resistFingerprinting.reduceTimerPrecision.microseconds`, whichever is larger.

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-currenttime |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Animation` for other methods and properties you can use to control web page animation.
* `Animation.startTime` for the time an animation is scheduled to start.
* Web Animations API


Animation: timeline property - Web APIs

Animation: timeline property
============================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`Animation.timeline`** property of the `Animation` interface returns or sets the `timeline` associated with this animation. A timeline is a source of time values for synchronization purposes, and is an `AnimationTimeline`-based object. By default, the animation's timeline and the `Document`'s timeline are the same.

Value
-----

A timeline object to use as the timing source for the animation, or `null` to use the default, which is the `Document`'s timeline.

Examples
--------

Here we set the animation's timeline to be the same as the document's timeline (this is the default timeline for all animations, by the way):

```js
animation.timeline = document.timeline;
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-timeline |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation`
* `AnimationTimeline` the parent object all timelines inherit from.
* `DocumentTimeline` the only kind of timeline object available at this time.
* `Document.timeline` is the default timeline all animations are assigned.


Animation: replaceState property - Web APIs

Animation: replaceState property
================================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The read-only **`Animation.replaceState`** property of the Web Animations API indicates whether the animation has been removed by the browser automatically after being replaced by another animation.

Value
-----

A string that represents the replace state of the animation. The value can be one of:

`active`

The initial value of the animation's replace state when the animation is created.

`persisted`

The animation has been explicitly persisted by invoking `Animation.persist()` on it.

`removed`

The animation has been removed by the browser automatically.

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-replacestate |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation`
* `remove` event
* `Animation.persist()`


Animation: pause() method - Web APIs

Animation: pause() method
=========================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`pause()`** method of the Web Animations API's `Animation` interface suspends playback of the animation.

Syntax
------

```js
animation.pause();
```

### Parameters

None.

### Return value

None.

### Exceptions

`InvalidStateError` `DOMException`

Thrown if the animation's `currentTime` is `unresolved` (perhaps it hasn't started playing yet), and the end time of the animation is positive infinity.

Example
-------

`Animation.pause()` is used many times in the Alice in Web Animations API Land Growing/Shrinking Alice Game, largely because animations created with the `Element.animate()` method immediately start playing and must be paused manually if you want to avoid that:

```js
// animation of the cupcake slowly getting eaten up
const nommingCake = document
  .getElementById("eat-me\_sprite")
  .animate(
    [{ transform: "translateY(0)" }, { transform: "translateY(-80%)" }],
    {
      fill: "forwards",
      easing: "steps(4, end)",
      duration: aliceChange.effect.timing.duration / 2,
    },
  );

// doesn't actually need to be eaten until a click event, so pause it initially:
nommingCake.pause();
```

Additionally, when resetting:

```js
// An all-purpose function to pause the animations on Alice, the cupcake, and the bottle that reads "drink me."
const stopPlayingAlice = () => {
  aliceChange.pause();
  nommingCake.pause();
  drinking.pause();
};

// When the user releases the cupcake or the bottle, pause the animations.
cake.addEventListener("mouseup", stopPlayingAlice, false);
bottle.addEventListener("mouseup", stopPlayingAlice, false);
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-pause |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation` for other methods and properties you can use to control web page animation.
* `Animation.pause()` to pause an animation.
* `Animation.reverse()` to play an animation backwards.
* `Animation.finish()` to finish an animation.
* `Animation.cancel()` to cancel an animation.


Animation: cancel event - Web APIs

Animation: cancel event
=======================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`cancel`** event of the `Animation` interface is fired when the `Animation.cancel()` method is called or when the animation enters the `"idle"` play state from another state, such as when the animation is removed from an element before it finishes playing.

**Note:** Creating a new animation that is initially idle does not trigger a `cancel` event on the new animation.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("cancel", (event) => { })
oncancel = (event) => { }
```

Event type
----------

An `AnimationPlaybackEvent`. Inherits from `Event`.

Event

AnimationPlaybackEventEvent properties
----------------

*In addition to the properties listed below, properties from the parent interface, `Event`, are available.*

`AnimationPlaybackEvent.currentTime` Read only

The current time of the animation that generated the event.

`AnimationPlaybackEvent.timelineTime` Read only

The time value of the timeline of the animation that generated the event.

Examples
--------

If this animation is canceled, remove its element.

```js
animation.oncancel = (event) => {
  animation.effect.target.remove();
};
```

Specifications
--------------

| Specification |
| --- |
| Web Animations # dom-animation-oncancel |
| Web Animations # cancel-event |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `Animation`