OffscreenCanvasRenderingContext2D - Web APIs

OffscreenCanvasRenderingContext2D
=================================

Baseline 2023
-------------

Newly availableSince March 2023, 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 **`OffscreenCanvasRenderingContext2D`** interface is a `CanvasRenderingContext2D` rendering context for drawing to the bitmap of an `OffscreenCanvas` object.
 It is similar to the `CanvasRenderingContext2D` object, with the following differences:

* there is no support for user-interface features (`drawFocusIfNeeded`, and `scrollPathIntoView`)
* its `canvas` attribute refers to an `OffscreenCanvas` object rather than a `<canvas>` element
* it has a `commit()` method for pushing rendered images to the context's `OffscreenCanvas` object's placeholder `<canvas>` element
Example
-------

 The following code snippet creates a `Worker` object using the `Worker()` constructor.
 The `transferControlToOffscreen()` method is used to transfer the `OffscreenCanvas` object to the worker:

```js
const canvas = document.getElementById("canvas");
const offscreen = canvas.transferControlToOffscreen();
const worker = new Worker("worker.js");
worker.postMessage({ canvas: offscreen }, [offscreen]);
```

In the worker thread, we can use the `OffscreenCanvasRenderingContext2D` to draw to the bitmap of the `OffscreenCanvas` object:

```js
onmessage = (event) => {
  const canvas = event.data.canvas;
  const offCtx = canvas.getContext("2d");
  // draw to the offscreen canvas context
  offCtx.fillStyle = "red";
  offCtx.fillRect(0, 0, 100, 100);
};
```

For a full example, see our OffscreenCanvas worker example (run OffscreenCanvas worker).

Additional methods
------------------

The following method is new to the `OffscreenCanvasRenderingContext2D` interface and does not exist in the `CanvasRenderingContext2D` interface:

`commit()`

Pushes the rendered image to the context's `OffscreenCanvas` object's placeholder `<canvas>` element.

Unsupported features
--------------------

The following user interface methods are **not supported** by the `OffscreenCanvasRenderingContext2D` interface:

`CanvasRenderingContext2D.drawFocusIfNeeded()`

If a given element is focused, this method draws a focus ring around the current path.

`CanvasRenderingContext2D.scrollPathIntoView()`
Experimental

Scrolls the current path or a given path into the view.

Inherited properties and methods
--------------------------------

*The following properties and methods are inherited from `CanvasRenderingContext2D`. They have the same usage as in `CanvasRenderingContext2D`*

### Context

`CanvasRenderingContext2D.isContextLost()`
Experimental

Returns `true` if the rendering context was lost.

### Drawing rectangles

`CanvasRenderingContext2D.clearRect()`

Sets all pixels in the rectangle defined by starting point *(x, y)* and size *(width, height)* to transparent black, erasing any previously drawn content.

`CanvasRenderingContext2D.fillRect()`

Draws a filled rectangle at *(x, y)* position whose size is determined by *width* and *height*.

`CanvasRenderingContext2D.strokeRect()`

Paints a rectangle which has a starting point at *(x, y)* and has a *w* width and an *h* height onto the canvas, using the current stroke style.

### Drawing text

The following methods and properties control drawing text. See also the `TextMetrics` object for text properties.

`CanvasRenderingContext2D.fillText()`

Draws (fills) a given text at the given (x, y) position.

`CanvasRenderingContext2D.strokeText()`

Draws (strokes) a given text at the given (x, y) position.

`CanvasRenderingContext2D.measureText()`

Returns a `TextMetrics` object.

`CanvasRenderingContext2D.textRendering`

Text rendering. Possible values: `auto` (default), `optimizeSpeed`, `optimizeLegibility`,

### Line styles

The following methods and properties control how lines are drawn.

`CanvasRenderingContext2D.lineWidth`

Width of lines. Default `1.0`.

`CanvasRenderingContext2D.lineCap`

Type of endings on the end of lines. Possible values: `butt` (default), `round`, `square`.

`CanvasRenderingContext2D.lineJoin`

Defines the type of corners where two lines meet. Possible values: `round`, `bevel`, `miter` (default).

`CanvasRenderingContext2D.miterLimit`

Miter limit ratio. Default `10`.

`CanvasRenderingContext2D.getLineDash()`

Returns the current line dash pattern array containing an even number of non-negative numbers.

`CanvasRenderingContext2D.setLineDash()`

Sets the current line dash pattern.

`CanvasRenderingContext2D.lineDashOffset`

Specifies where to start a dash array on a line.

### Text styles

The following properties control how text is laid out.

`CanvasRenderingContext2D.font`

Font setting. Default value `10px sans-serif`.

`CanvasRenderingContext2D.textAlign`

Text alignment setting. Possible values: `start` (default), `end`, `left`, `right`, `center`.

`CanvasRenderingContext2D.textBaseline`

Baseline alignment setting. Possible values: `top`, `hanging`, `middle`, `alphabetic` (default), `ideographic`, `bottom`.

`CanvasRenderingContext2D.direction`

Directionality. Possible values: `ltr`, `rtl`, `inherit` (default).

`CanvasRenderingContext2D.letterSpacing`

Letter spacing. Default: `0px`.

`CanvasRenderingContext2D.fontKerning`

Font kerning. Possible values: `auto` (default), `normal`, `none`.

`CanvasRenderingContext2D.fontStretch`

Font stretch. Possible values: `ultra-condensed`, `extra-condensed`, `condensed`, `semi-condensed`, `normal` (default), `semi-expanded`, `expanded`, `extra-expanded`, `ultra-expanded`.

`CanvasRenderingContext2D.fontVariantCaps`

Font variant caps. Possible values: `normal` (default), `small-caps`, `all-small-caps`, `petite-caps`, `all-petite-caps`, `unicase`, `titling-caps`.

`CanvasRenderingContext2D.textRendering`
Experimental

Text rendering. Possible values: `auto` (default), `optimizeSpeed`, `optimizeLegibility`, `geometricPrecision`.

`CanvasRenderingContext2D.wordSpacing`

Word spacing. Default value: `0px`

### Fill and stroke styles

Fill styling is used for colors and styles inside shapes and stroke styling is used for the lines around shapes.

`CanvasRenderingContext2D.fillStyle`

Color or style to use inside shapes. Default `#000` (black).

`CanvasRenderingContext2D.strokeStyle`

Color or style to use for the lines around shapes. Default `#000` (black).

### Gradients and patterns

`CanvasRenderingContext2D.createConicGradient()`

Creates a conic gradient around a point given by coordinates represented by the parameters.

`CanvasRenderingContext2D.createLinearGradient()`

Creates a linear gradient along the line given by the coordinates represented by the parameters.

`CanvasRenderingContext2D.createRadialGradient()`

Creates a radial gradient given by the coordinates of the two circles represented by the parameters.

`CanvasRenderingContext2D.createPattern()`

Creates a pattern using the specified image. It repeats the source in the directions specified by the repetition argument. This method returns a `CanvasPattern`.

### Shadows

`CanvasRenderingContext2D.shadowBlur`

Specifies the blurring effect. Default: `0`.

`CanvasRenderingContext2D.shadowColor`

Color of the shadow. Default: fully-transparent black.

`CanvasRenderingContext2D.shadowOffsetX`

Horizontal distance the shadow will be offset. Default: `0`.

`CanvasRenderingContext2D.shadowOffsetY`

Vertical distance the shadow will be offset. Default: `0`.

### Paths

The following methods can be used to manipulate paths of objects.

`CanvasRenderingContext2D.beginPath()`

Starts a new path by emptying the list of sub-paths. Call this method when you want to create a new path.

`CanvasRenderingContext2D.closePath()`

Causes the point of the pen to move back to the start of the current sub-path. It tries to draw a straight line from the current point to the start. If the shape has already been closed or has only one point, this function does nothing.

`CanvasRenderingContext2D.moveTo()`

Moves the starting point of a new sub-path to the (x, y) coordinates.

`CanvasRenderingContext2D.lineTo()`

Connects the last point in the current sub-path to the specified (x, y) coordinates with a straight line.

`CanvasRenderingContext2D.bezierCurveTo()`

Adds a cubic Bézier curve to the current path.

`CanvasRenderingContext2D.quadraticCurveTo()`

Adds a quadratic Bézier curve to the current path.

`CanvasRenderingContext2D.arc()`

Adds a circular arc to the current path.

`CanvasRenderingContext2D.arcTo()`

Adds an arc to the current path with the given control points and radius, connected to the previous point by a straight line.

`CanvasRenderingContext2D.ellipse()`

Adds an elliptical arc to the current path.

`CanvasRenderingContext2D.rect()`

Creates a path for a rectangle at position (x, y) with a size that is determined by *width* and *height*.

### Drawing paths

`CanvasRenderingContext2D.fill()`

Fills the current sub-paths with the current fill style.

`CanvasRenderingContext2D.stroke()`

Strokes the current sub-paths with the current stroke style.

`CanvasRenderingContext2D.clip()`

Creates a clipping path from the current sub-paths. Everything drawn after `clip()` is called appears inside the clipping path only. For an example, see Clipping paths in the Canvas tutorial.

`CanvasRenderingContext2D.isPointInPath()`

Reports whether or not the specified point is contained in the current path.

`CanvasRenderingContext2D.isPointInStroke()`

Reports whether or not the specified point is inside the area contained by the stroking of a path.

`CanvasRenderingContext2D.roundRect()`

Addition to CanvasPath that allows users to render rectangles with rounded corners.

### Transformations

Objects in the `CanvasRenderingContext2D` rendering context have a current transformation matrix and methods to manipulate it. The transformation matrix is applied when creating the current default path, painting text, shapes and `Path2D` objects. The methods listed below remain for historical and compatibility reasons as `DOMMatrix` objects are used in most parts of the API nowadays and will be used in the future instead.

`CanvasRenderingContext2D.getTransform()`

Retrieves the current transformation matrix being applied to the context.

`CanvasRenderingContext2D.rotate()`

Adds a rotation to the transformation matrix. The angle argument represents a clockwise rotation angle and is expressed in radians.

`CanvasRenderingContext2D.scale()`

Adds a scaling transformation to the canvas units by x horizontally and by y vertically.

`CanvasRenderingContext2D.translate()`

Adds a translation transformation by moving the canvas and its origin x horizontally and y vertically on the grid.

`CanvasRenderingContext2D.transform()`

Multiplies the current transformation matrix with the matrix described by its arguments.

`CanvasRenderingContext2D.setTransform()`

Resets the current transform to the identity matrix, and then invokes the `transform()` method with the same arguments.

`CanvasRenderingContext2D.resetTransform()`

Resets the current transform by the identity matrix.

### Compositing

`CanvasRenderingContext2D.globalAlpha`

Alpha value that is applied to shapes and images before they are composited onto the canvas. Default `1.0` (opaque).

`CanvasRenderingContext2D.globalCompositeOperation`

With `globalAlpha` applied this sets how shapes and images are drawn onto the existing bitmap.

### Drawing images

`CanvasRenderingContext2D.drawImage()`

Draws the specified image. This method is available in multiple formats, providing a great deal of flexibility in its use.

### Pixel manipulation

See also the `ImageData` object.

`CanvasRenderingContext2D.createImageData()`

Creates a new, blank `ImageData` object with the specified dimensions. All of the pixels in the new object are transparent black.

`CanvasRenderingContext2D.getImageData()`

Returns an `ImageData` object representing the underlying pixel data for the area of the canvas denoted by the rectangle which starts at *(sx, sy)* and has an *sw* width and *sh* height.

`CanvasRenderingContext2D.putImageData()`

Paints data from the given `ImageData` object onto the bitmap. If a dirty rectangle is provided, only the pixels from that rectangle are painted.

### Image smoothing

`CanvasRenderingContext2D.imageSmoothingEnabled`

Image smoothing mode; if disabled, images will not be smoothed if scaled.

`CanvasRenderingContext2D.imageSmoothingQuality`

Allows you to set the quality of image smoothing.

### The canvas state

The `CanvasRenderingContext2D` rendering context contains a variety of drawing style states (attributes for line styles, fill styles, shadow styles, text styles). The following methods help you to work with that state:

`CanvasRenderingContext2D.save()`

Saves the current drawing style state using a stack so you can revert any change you make to it using `restore()`.

`CanvasRenderingContext2D.restore()`

Restores the drawing style state to the last element on the 'state stack' saved by `save()`.

`CanvasRenderingContext2D.canvas`

A read-only reference to an `OffscreenCanvas` object.

`CanvasRenderingContext2D.getContextAttributes()`

Returns an object containing the actual context attributes. Context attributes can be requested with `HTMLCanvasElement.getContext()`.

`CanvasRenderingContext2D.reset()`

Resets the current drawing style state to the default values.

### Filters

`CanvasRenderingContext2D.filter`

Applies a CSS or SVG filter to the canvas; e.g., to change its brightness or blurriness.

Unsupported properties and methods
----------------------------------

The following methods are **not supported** in the `OffscreenCanvasRenderingContext2D` interface:

`CanvasRenderingContext2D.drawFocusIfNeeded()`

If a given element is focused, this method draws a focus ring around the current path.

`CanvasRenderingContext2D.scrollPathIntoView()`
Experimental

Scrolls the current path or a given path into the view.

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

| Specification |
| --- |
| HTML Standard # the-offscreen-2d-rendering-context |

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

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

See also
--------

* `HTMLCanvasElement`
* `<canvas>`


HTMLMetaElement - Web APIs

HTMLMetaElement
===============

 The **`HTMLMetaElement`** interface contains descriptive metadata about a document provided in HTML as `<meta>` elements.
 This interface inherits all of the properties and methods described in the `HTMLElement` interface.

EventTarget

Node

Element

HTMLElement

HTMLMetaElementInstance properties
-------------------

*Inherits properties from its parent, `HTMLElement`.*

`HTMLMetaElement.charset`

The character encoding for a HTML document.

`HTMLMetaElement.content`

The 'value' part of the name-value pairs of the document metadata.

`HTMLMetaElement.httpEquiv`

The name of the pragma directive, the HTTP response header, for a document.

`HTMLMetaElement.media`

The media context for a `theme-color` metadata property.

`HTMLMetaElement.name`

The 'name' part of the name-value pairs defining the named metadata of a document.

`HTMLMetaElement.scheme`
Deprecated

 Defines the scheme of the value in the `HTMLMetaElement.content` attribute.
 This is deprecated and should not be used on new web pages.

Instance methods
----------------

*No specific method; inherits methods from its parent, `HTMLElement`.*

Examples
--------

 The following two examples show a general approach to using the `HTMLMetaElement` interface.
 For specific examples, see the pages for the individual properties as described in the Instance properties section above.

### Setting the page description metadata

 The following example creates a new `<meta>` element with a `name` attribute set to `description`.
 The `content` attribute sets a description of the document and is appended to the document `<head>`:

```js
let meta = document.createElement("meta");
meta.name = "description";
meta.content =
  "The <meta> element can be used to provide document metadata in terms of name-value pairs, with the name attribute giving the metadata name, and the content attribute giving the value.";
document.head.appendChild(meta);
```

### Setting the viewport metadata

 The following example shows how to create a new `<meta>` element with a `name` attribute set to `viewport`.
 The `content` attribute sets the viewport size and is appended to the document `<head>`:

```js
var meta = document.createElement("meta");
meta.name = "viewport";
meta.content = "width=device-width, initial-scale=1";
document.head.appendChild(meta);
```

For more information on setting the viewport, see Viewport basics.

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

| Specification |
| --- |
| HTML Standard # htmlmetaelement |

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

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

See also
--------

* The HTML element implementing this interface: `<meta>`


ReadableStreamBYOBRequest - Web APIs

ReadableStreamBYOBRequest
=========================

The **`ReadableStreamBYOBRequest`** interface of the Streams API represents a "pull request" for data from an underlying source that will made as a zero-copy transfer to a consumer (bypassing the stream's internal queues).

`ReadableStreamBYOBRequest` objects are created in "BYOB mode" when a consumer makes a request for data and the stream's internal queue is *empty*.
 (The stream will resolve the consumer's request directly if it already has buffered data).
 An underlying byte source can access active BYOB requests through its controller's `ReadableByteStreamController.byobRequest` property, which will be set to `null` if there is no outstanding request.

 An underlying source that supports "BYOB mode" should check for `ReadableByteStreamController.byobRequest` and must use it for transferring data, if present.
 If data arrives from the underlying source when `ReadableByteStreamController.byobRequest` is `null`, it can be queued using `ReadableByteStreamController.enqueue()`.
 This might happen when an underlying push source receives new data when the stream's internal buffers are not empty.

 An underlying source uses the request by writing data to the BYOB request's `view` and then calling `respond()`, or by calling `respondWithNewView()` and passing a new view as an argument.
 Note that the "new view" must actually be a view over the *same* buffer as the original `view`, starting at the same offset.
 This might be used to return a shorter buffer if the underlying source is unable to fill the entire original view.

 Note that a `ReadableByteStreamController` is only created for underlying sources when `type="bytes"` is specified for the source in the `ReadableStream()` constructor.
 "BYOB mode" is enabled when either `autoAllocateChunkSize` is specified in the `ReadableController()` constructor or when using a `ReadableStreamBYOBReader` (typically constructed by calling `ReadableStream.getReader()` with the argument `{ mode: 'byob' }`).

Constructor
-----------

None. `ReadableStreamBYOBRequest` instance is created automatically by `ReadableByteStreamController` as needed.

Instance properties
-------------------

`ReadableStreamBYOBRequest.view` Read only

 Returns the current view.
 This is a view on a buffer that will be transferred to the consumer when `ReadableStreamBYOBRequest.respond()` is called.

Instance methods
----------------

`ReadableStreamBYOBRequest.respond()`

 Signals the associated readable byte stream that the specified number of bytes were written into the current `view`, which then causes the pending request from the consumer to be resolved.
 Note that after this method is called the `view` is transferred and no longer modifiable.

`ReadableStreamBYOBRequest.respondWithNewView()`

 Signals to the associated readable byte stream view passed as an argument should be transferred to the consumer of the readable byte stream.
 This new view must use the same buffer as the original `view`, start at the same offset, and be the same length or shorter.
 Note that after this method is called the `view` is transferred and no longer modifiable.

Examples
--------

The following code is taken from the live example in Using readable byte streams > Creating a readable socket push byte stream.

 A push underlying byte source with data to transfer should first check that `controller.byobRequest` is non-`null`. Pul
 A pull underlying byte source would only need this check if auto chunk allocation was not enabled and it was used with a default reader.

```js
if (controller.byobRequest) {
  /\* code to transfer data \*/
}
```

 There are two ways to read data into a `ReadableStreamBYOBRequest` and then transfer it.
 The first is to write the data into the `ReadableStreamBYOBRequest.view` property and then call `ReadableStreamBYOBRequest.respond()` to indicate the amount of data to be transferred.
 After the operation the `byobRequest.view` is detached and the request should be discarded.

The code below shows this case using a hypothetical `readInto()` method to copy data into the view:

```js
const v = controller.byobRequest.view;
bytesRead = socket.readInto(v.buffer, v.byteOffset, v.byteLength);
controller.byobRequest.respond(bytesRead);
```

 The other approach is to call `ReadableStreamBYOBRequest.respondWithNewView()` passing your own view on the same underlying backing data.
 Note that this just another way of specifying the range of the underlying buffer/memory backing that is actually transferred.
 The `respondWithNewView` equivalent to the code above would be:

```js
const v = controller.byobRequest.view;
bytesRead = socket.readInto(v.buffer, v.byteOffset, v.byteLength);
const newView = new Uint8Array(v.buffer, v.byteOffset, bytesRead);
controller.byobRequest.respondWithNewView(newView);
```

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

| Specification |
| --- |
| Streams Standard # rs-byob-request-class |

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

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

See also
--------

* Using readable byte stream


FileSystemHandle - Web APIs

FileSystemHandle
================

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

The **`FileSystemHandle`** interface of the `File System API` is an object which represents a file or directory entry. Multiple handles can represent the same entry. For the most part you do not work with `FileSystemHandle` directly but rather its child interfaces `FileSystemFileHandle` and `FileSystemDirectoryHandle`.

Interfaces based on FileSystemHandle
------------------------------------

Below is a list of interfaces based on the FileSystemHandle interface.

`FileSystemFileHandle`

Represents a handle to a file entry.

`FileSystemDirectoryHandle`

Provides a handle to a directory entry.

Instance properties
-------------------

`kind` Read only

Returns the type of entry. This is `'file'` if the associated entry is a file or `'directory'`.

`name` Read only

Returns the name of the associated entry.

Instance methods
----------------

`isSameEntry()`

Compares two `handles` to see if the associated entries (either a file or directory) match.

`queryPermission()`
Experimental

Queries the current permission state of the current handle.

`remove()`
Experimental

Non-standard

Requests removal of the entry represented by the handle from the underlying file system.

`requestPermission()`
Experimental

Requests read or readwrite permissions for the file handle.

Examples
--------

### Checking Type

The below code allows the user to choose a file from the file picker and then tests to see whether the handle returned is a file or directory

```js
// store a reference to our file handle
let fileHandle;

async function getFile() {
  // open file picker
  [fileHandle] = await window.showOpenFilePicker();

  if (fileHandle.kind === "file") {
    // run file code
  } else if (fileHandle.kind === "directory") {
    // run directory code
  }
}
```

### Query/Request Permissions

The following asynchronous function returns true if user has granted read or readwrite permissions to the file handle. Permission is requested if not.

```js
// fileHandle is a FileSystemFileHandle
// withWrite is a boolean set to true if write

async function verifyPermission(fileHandle, withWrite) {
  const opts = {};
  if (withWrite) {
    opts.mode = "readwrite";
  }

  // Check if we already have permission, if so, return true.
  if ((await fileHandle.queryPermission(opts)) === "granted") {
    return true;
  }

  // Request permission to the file, if the user grants permission, return true.
  if ((await fileHandle.requestPermission(opts)) === "granted") {
    return true;
  }

  // The user did not grant permission, return false.
  return false;
}
```

### Comparing Entries

The following function compares a single entry with an array of entries, and returns a new array with any matching entries removed.

```js
function removeMatches(fileEntry, entriesArr) {
  const newArr = entriesArr.filter((entry) => !fileEntry.isSameEntry(entry));

  return newArr;
}
```

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

| Specification |
| --- |
| File System Standard # api-filesystemhandle |

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

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

See also
--------

* File System API
* The File System Access API: simplifying access to local files


CSSConditionRule - Web APIs

CSSConditionRule
================

An object implementing the **`CSSConditionRule`** interface represents a single condition CSS at-rule, which consists of a condition and a statement block.

Three objects derive from `CSSConditionRule`: `CSSMediaRule`, `CSSContainerRule` and `CSSSupportsRule`.

CSSRule

CSSGroupingRule

CSSConditionRuleInstance properties
-------------------

*Inherits properties from its ancestors `CSSRule` and `CSSGroupingRule`.*

`CSSConditionRule.conditionText`

Represents the text of the condition of the rule.

Instance methods
----------------

No specific methods; inherits methods from its ancestors `CSSRule` and `CSSGroupingRule`.

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

| Specification |
| --- |
| CSS Conditional Rules Module Level 3 # the-cssconditionrule-interface |

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

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

See also
--------

* Using dynamic styling information


SVGEvent - Web APIs

SVGEvent
========

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

The `SVGEvent` interface represents the event object for most SVG-related events.

Instance properties
-------------------

| Property | Type | Description |
| --- | --- | --- |
| `target` Read only  | `EventTarget` | The event target (the topmost target in the DOM tree). |
| `type` Read only  | string | The type of event. |
| `bubbles` Read only  | A boolean value | Whether the event normally bubbles or not. |
| `cancelable` Read only  | A boolean value | Whether the event is cancellable or not. |


MIDIOutputMap - Web APIs

MIDIOutputMap
=============

The **`MIDIOutputMap`** read-only interface of the Web MIDI API provides the set of MIDI output ports that are currently available.

A `MIDIOutputMap` instance is a read-only `Map`-like object, in which each key is the ID string for MIDI output, and the associated value is the corresponding `MIDIOutput` object.

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

| Specification |
| --- |
| Web MIDI API # midiinputmap-interface |

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

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


Crypto - Web APIs

Crypto
======

 The **`Crypto`** interface represents basic cryptography features available in the current context.
 It allows access to a cryptographically strong random number generator and to cryptographic primitives.

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

The Web Crypto API is accessed through the global `crypto` property, which is a `Crypto` object.

Instance properties
-------------------

*This interface implements properties defined on `RandomSource`.*

`Crypto.subtle` Read only  Secure context

Returns a `SubtleCrypto` object providing access to common cryptographic primitives, like hashing, signing, encryption, or decryption.

Instance methods
----------------

*This interface implements methods defined on `RandomSource`.*

`Crypto.getRandomValues()`

Fills the passed `TypedArray` with cryptographically sound random values.

`Crypto.randomUUID()` Secure context

Returns a randomly generated, 36 character long v4 UUID.

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

 You should avoid using the Web Crypto API on insecure contexts, even though the `Crypto` interface is present on insecure contexts, as is the `crypto` property.
 In addition, the `Crypto` method `getRandomValues()` is available on insecure contexts, but the `subtle` property is not.

In general, you probably should just treat `Crypto` as available only on secure contexts.

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

| Specification |
| --- |
| Web Cryptography API # crypto-interface |

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

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

See also
--------

* Web security
* Secure contexts
* Features restricted to secure contexts
* Transport Layer Security
* Strict-Transport-Security


SVGRect - Web APIs

SVGRect
=======

The **`SVGRect`** represents a rectangle. Rectangles consist of an `x` and `y` coordinate pair identifying a minimum `x` value, a minimum `y` value, and a `width` and `height`, which are constrained to be non-negative.

An **`SVGRect`** object can be designated as read only, which means that attempts to modify the object will result in an exception being thrown.

Instance properties
-------------------

`SVGRect.x`

The exact effect of this coordinate depends on each element. If the attribute is not specified, the effect is as if a value of `0` were specified.

`SVGRect.y`

The exact effect of this coordinate depends on each element. If the attribute is not specified, the effect is as if a value of `0` were specified.

`SVGRect.width`

This represents the width of the rectangle. A value that is negative results to an error. A value of `0` disables rendering of the element

`SVGRect.height`

This represents the height of the rectangle. A value that is negative results to an error. A value of `0` disables rendering of the element.

Instance methods
----------------

None.

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

| Specification |
| --- |
| Geometry Interfaces Module Level 1 # DOMRect |

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

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


SVGPolygonElement - Web APIs

SVGPolygonElement
=================

The **`SVGPolygonElement`** interface provides access to the properties of `<polygon>` elements, as well as methods to manipulate them.

EventTarget

Node

Element

SVGElement

SVGGraphicsElement

SVGGeometryElement

SVGPolygonElementInstance properties
-------------------

*This interface also inherits properties from its parent, `SVGGeometryElement`.*

`SVGPolygonElement.animatedPoints` Read only

A `SVGPointList` representing the animated value of the element's `points` attribute. If the `points` attribute is not being animated, it contains the same value as the `points` property.

`SVGPolygonElement.points`

A `SVGPointList` representing the base (i.e., static) value of the element's `points` attribute. Modifications via the `SVGPointList` object are reflected in the `points` attribute, and vice versa.

Instance methods
----------------

*This interface doesn't implement any specific methods, but inherits methods from its parent, `SVGGeometryElement`.*

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

| Specification |
| --- |
| Scalable Vector Graphics (SVG) 2 # InterfaceSVGPolygonElement |

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

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

See also
--------

* `<polygon>`


XRQuadLayer - Web APIs

XRQuadLayer
===========

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

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`XRQuadLayer`** interface of the WebXR Device API is a layer that takes up a flat rectangular space in the virtual environment. An `XRQuadLayer` has no thickness. It is a two-dimensional object positioned and oriented in 3D space. The position of a quad refers to the center of the quad. Only the front of the layer is visible.

`XRQuadLayer` requires the `layers` feature to be enabled for the `XRSession`. You can request it in `XRSystem.requestSession()`.

To create a new `XRQuadLayer`, call either:

* `XRWebGLBinding.createQuadLayer()` for a WebGL opaque texture quad layer, or
* `XRMediaBinding.createQuadLayer()` for an HTML `<video>` playback quad layer.

To present layers to the XR device, add them to the `layers` render state using `XRSession.updateRenderState()`.

EventTarget

XRLayer

XRCompositionLayer

XRQuadLayerInstance properties
-------------------

*Inherits properties from its parent, `XRCompositionLayer`.*

`XRQuadLayer.height`
Experimental

Represents the height of the layer in meters.

`XRQuadLayer.space`
Experimental

An `XRSpace` representing the layer's spatial relationship with the user's physical environment.

`XRQuadLayer.transform`
Experimental

An `XRRigidTransform` representing the offset and orientation relative to `space`.

`XRQuadLayer.width`
Experimental

Represents the width of the layer in meters.

Instance methods
----------------

*Inherits methods from its parents, `XRCompositionLayer` and `EventTarget`*.

Events
------

`redraw`
Experimental

Sent to the `XRQuadLayer` object when the underlying resources of the layer are lost or when the XR Compositor can no longer reproject the layer. If this event is sent, authors should redraw the content of the layer in the next XR animation frame.

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

| Specification |
| --- |
| WebXR Layers API Level 1 # xrquadlayertype |

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

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

See also
--------

* `XRLayer`
* `EventTarget`
* `XRCompositionLayer`
* `XREquirectLayer`
* `XRCubeLayer`
* `XRCylinderLayer`
* `XRProjectionLayer`


HTMLAudioElement - Web APIs

HTMLAudioElement
================

The **`HTMLAudioElement`** interface provides access to the properties of `<audio>` elements, as well as methods to manipulate them.

This element is based on, and inherits properties and methods from, the `HTMLMediaElement` interface.

EventTarget

Node

Element

HTMLElement

HTMLMediaElement

HTMLAudioElementConstructor
-----------

`Audio()`

Creates and returns a new `HTMLAudioElement` object, optionally starting the process of loading an audio file into it if the file URL is given.

Instance properties
-------------------

*No specific properties; inherits properties from its parent, `HTMLMediaElement`, and from `HTMLElement`.*

Instance methods
----------------

*Inherits methods from its parent, `HTMLMediaElement`, and from `HTMLElement`. It offers no methods of its own.*

Examples
--------

### Basic usage

You can create a `HTMLAudioElement` entirely with JavaScript using the `Audio()` constructor:

```js
const audioElement = new Audio("car\_horn.wav");
```

then you can invoke the `play()` method on the element

```js
audioElement.play();
```

**Note:** A common gotcha is trying to play an audio element immediately on page load. Modern browser's default autoplay policy will block that from happening. Refer to Firefox and chrome for best practices and work arounds.

Some of the more commonly used properties of the audio element include `src`, `currentTime`, `duration`, `paused`, `muted`, and `volume`. This snippet copies the audio file's duration to a variable:

```js
const audioElement = new Audio("car\_horn.wav");
audioElement.addEventListener("loadeddata", () => {
  let duration = audioElement.duration;
  // The duration variable now holds the duration (in seconds) of the audio clip
});
```

Events
------

*Inherits methods from its parent, `HTMLMediaElement`, and from its ancestor `HTMLElement`.* Listen to events using `addEventListener()` or by assigning an event listener to the `oneventname` property of this interface.

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

| Specification |
| --- |
| HTML Standard # htmlaudioelement |

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

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

See also
--------

* Web media technologies
* Using audio and video in HTML
* HTML element implementing this interface: `<audio>`.


CSSPropertyRule - Web APIs

CSSPropertyRule
===============

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
The **`CSSPropertyRule`** interface of the CSS Properties and Values API represents a single CSS `@property` rule.

CSSRule

CSSPropertyRuleInstance properties
-------------------

*Inherits properties from its ancestor `CSSRule`.*

`CSSPropertyRule.inherits` Read only

Returns the inherit flag of the custom property.

`CSSPropertyRule.initialvalue` Read only

Returns the initial value of the custom property.

`CSSPropertyRule.name` Read only

Returns the name of the custom property.

`CSSPropertyRule.syntax` Read only

Returns the literal syntax of the custom property.

Instance methods
----------------

*No specific methods; inherits methods from its ancestor `CSSRule`.*

Examples
--------

This stylesheet contains a single `@property` rule. The first `CSSRule` returned will be a `CSSPropertyRule` with the properties and values as defined by the rule in CSS.

```css
@property --property-name {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0ffee;
}
```

```js
let myRules = document.styleSheets[0].cssRules;
console.log(myRules[0]); //a CSSPropertyRule
```

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

| Specification |
| --- |
| CSS Properties and Values API Level 1 # the-css-property-rule-interface |

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

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


VRLayerInit - Web APIs

VRLayerInit
===========

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

The **`VRLayerInit`** dictionary of the WebVR API represents a content layer (an `HTMLCanvasElement` or `OffscreenCanvas`) that you want to present in a VR display.

**Note:** This dictionary was part of the old WebVR API. It has been superseded by the WebXR Device API.

You can retrieve `VRLayerInit` objects using `VRDisplay.getLayers()`, and present them using the `VRDisplay.requestPresent()` method.

Instance properties
-------------------

`VRLayerInit.leftBounds`
Deprecated

Defines the left texture bounds of the canvas whose contents will be presented by the `VRDisplay`.

`VRLayerInit.rightBounds`
Deprecated

Defines the right texture bounds of the canvas whose contents will be presented by the `VRDisplay`.

`VRLayerInit.source`
Deprecated

Defines the canvas whose contents will be presented by the `VRDisplay` when `VRDisplay.submitFrame()` is called.

Examples
--------

```js
// currently returns an empty array
let layers = vrDisplay.getLayers();

if (navigator.getVRDisplays) {
  console.log("WebVR 1.1 supported");
  // Then get the displays attached to the computer
  navigator.getVRDisplays().then((displays) => {
    // If a display is available, use it to present the scene
    if (displays.length > 0) {
      vrDisplay = displays[0];
      console.log("Display found");
      // Starting the presentation when the button is clicked: It can only be called in response to a user gesture
      btn.addEventListener("click", () => {
        vrDisplay.requestPresent([{ source: canvas }]).then(() => {
          console.log("Presenting to WebVR display");

          // Here it returns an array of VRLayerInit objects
          layers = vrDisplay.getLayers();

          // …
        });
      });
    }
  });
}
```

`VRLayerInit` objects look something like this:

```js
{
  leftBounds : [/\* … \*/],
  rightBounds: [/\* … \*/],
  source: canvasReference
}
```

**Note:** The `canvasReference` refers to the `<canvas>` element itself, not the WebGL context associated with the canvas. The other two members are arrays

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

This dictionary was part of the old WebVR API that has been superseded by the WebXR Device API. It is no longer on track to becoming a standard.

Until all browsers have implemented the new WebXR APIs, it is recommended to rely on frameworks, like A-Frame, Babylon.js, or Three.js, or a polyfill, to develop WebXR applications that will work across all browsers [1].

See also
--------

* WebVR API


SpeechSynthesisUtterance - Web APIs

SpeechSynthesisUtterance
========================

 The **`SpeechSynthesisUtterance`** interface of the Web Speech API represents a speech request.
 It contains the content the speech service should read and information about how to read it (e.g. language, pitch and volume.)

EventTarget

SpeechSynthesisUtteranceConstructor
-----------

`SpeechSynthesisUtterance()`

Returns a new `SpeechSynthesisUtterance` object instance.

Instance properties
-------------------

*`SpeechSynthesisUtterance` also inherits properties from its parent interface, `EventTarget`.*

`SpeechSynthesisUtterance.lang`

Gets and sets the language of the utterance.

`SpeechSynthesisUtterance.pitch`

Gets and sets the pitch at which the utterance will be spoken at.

`SpeechSynthesisUtterance.rate`

Gets and sets the speed at which the utterance will be spoken at.

`SpeechSynthesisUtterance.text`

Gets and sets the text that will be synthesized when the utterance is spoken.

`SpeechSynthesisUtterance.voice`

Gets and sets the voice that will be used to speak the utterance.

`SpeechSynthesisUtterance.volume`

Gets and sets the volume that the utterance will be spoken at.

Events
------

Listen to these events using `addEventListener()` or by assigning an event listener to the `oneventname` property of this interface.

`boundary`

 Fired when the spoken utterance reaches a word or sentence boundary.
 Also available via the `onboundary` property.

`end`

 Fired when the utterance has finished being spoken.
 Also available via the `onend` property.

`error`

 Fired when an error occurs that prevents the utterance from being successfully spoken.
 Also available via the `onerror` property

`mark`

 Fired when the spoken utterance reaches a named SSML "mark" tag.
 Also available via the `onmark` property.

`pause`

 Fired when the utterance is paused part way through.
 Also available via the `onpause` property.

`resume`

 Fired when a paused utterance is resumed.
 Also available via the `onresume` property.

`start`

 Fired when the utterance has begun to be spoken.
 Also available via the `onstart` property.

Examples
--------

 In our basic Speech synthesizer demo, we first grab a reference to the SpeechSynthesis controller using `window.speechSynthesis`.
 After defining some necessary variables, we retrieve a list of the voices available using `SpeechSynthesis.getVoices()` and populate a select menu with them so the user can choose what voice they want.

Inside the `inputForm.onsubmit` handler, we stop the form submitting with `preventDefault()`, use the `constructor` to create a new utterance instance containing the text from the text `<input>`, set the utterance's `voice` to the voice selected in the `<select>` element, and start the utterance speaking via the `SpeechSynthesis.speak()` method.

```js
const synth = window.speechSynthesis;

const inputForm = document.querySelector("form");
const inputTxt = document.querySelector("input");
const voiceSelect = document.querySelector("select");

let voices;

function loadVoices() {
  voices = synth.getVoices();
  for (let i = 0; i < voices.length; i++) {
    const option = document.createElement("option");
    option.textContent = `${voices[i].name} (${voices[i].lang})`;
    option.value = i;
    voiceSelect.appendChild(option);
  }
}

// in Google Chrome the voices are not ready on page load
if ("onvoiceschanged" in synth) {
  synth.onvoiceschanged = loadVoices;
} else {
  loadVoices();
}

inputForm.onsubmit = (event) => {
  event.preventDefault();

  const utterThis = new SpeechSynthesisUtterance(inputTxt.value);
  utterThis.voice = voices[voiceSelect.value];
  synth.speak(utterThis);
  inputTxt.blur();
};
```

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

| Specification |
| --- |
| Web Speech API # speechsynthesisutterance |

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

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

See also
--------

* Web Speech API


WritableStream - Web APIs

WritableStream
==============

 The **`WritableStream`** interface of the Streams API provides a standard abstraction for writing streaming data to a destination, known as a sink.
 This object comes with built-in backpressure and queuing.

`WritableStream` is a transferable object.

Constructor
-----------

`WritableStream()`

Creates a new `WritableStream` object.

Instance properties
-------------------

`WritableStream.locked` Read only

A boolean indicating whether the `WritableStream` is locked to a writer.

Instance methods
----------------

`WritableStream.abort()`

Aborts the stream, signaling that the producer can no longer successfully write to the stream and it is to be immediately moved to an error state, with any queued writes discarded.

`WritableStream.close()`

Closes the stream.

`WritableStream.getWriter()`

Returns a new instance of `WritableStreamDefaultWriter` and locks the stream to that instance. While the stream is locked, no other writer can be acquired until this one is released.

Examples
--------

The following example illustrates several features of this interface. It shows the creation of the `WritableStream` with a custom sink and an API-supplied queueing strategy. It then calls a function called `sendMessage()`, passing the newly created stream and a string. Inside this function it calls the stream's `getWriter()` method, which returns an instance of `WritableStreamDefaultWriter`. A `forEach()` call is used to write each chunk of the string to the stream. Finally, `write()` and `close()` return promises that are processed to deal with success or failure of chunks and streams.

```js
const list = document.querySelector("ul");

function sendMessage(message, writableStream) {
  // defaultWriter is of type WritableStreamDefaultWriter
  const defaultWriter = writableStream.getWriter();
  const encoder = new TextEncoder();
  const encoded = encoder.encode(message);
  encoded.forEach((chunk) => {
    defaultWriter.ready
      .then(() => defaultWriter.write(chunk))
      .then(() => {
        console.log("Chunk written to sink.");
      })
      .catch((err) => {
        console.log("Chunk error:", err);
      });
  });
  // Call ready again to ensure that all chunks are written
  // before closing the writer.
  defaultWriter.ready
    .then(() => {
      defaultWriter.close();
    })
    .then(() => {
      console.log("All chunks written");
    })
    .catch((err) => {
      console.log("Stream error:", err);
    });
}

const decoder = new TextDecoder("utf-8");
const queuingStrategy = new CountQueuingStrategy({ highWaterMark: 1 });
let result = "";
const writableStream = new WritableStream(
  {
    // Implement the sink
    write(chunk) {
      return new Promise((resolve, reject) => {
        const buffer = new ArrayBuffer(1);
        const view = new Uint8Array(buffer);
        view[0] = chunk;
        const decoded = decoder.decode(view, { stream: true });
        const listItem = document.createElement("li");
        listItem.textContent = `Chunk decoded: ${decoded}`;
        list.appendChild(listItem);
        result += decoded;
        resolve();
      });
    },
    close() {
      const listItem = document.createElement("li");
      listItem.textContent = `[MESSAGE RECEIVED] ${result}`;
      list.appendChild(listItem);
    },
    abort(err) {
      console.log("Sink error:", err);
    },
  },
  queuingStrategy,
);

sendMessage("Hello, world.", writableStream);
```

You can find the full code in our Simple writer example.

### Backpressure

 Because of how backpressure is supported in the API, its implementation in code may be less than obvious.
 To see how backpressure is implemented look for three things:

* The `highWaterMark` property, which is set when creating the counting strategy (line 35), sets the maximum amount of data that the `WritableStream` instance will handle in a single `write()` operation. In this example, it's the maximum amount of data that can be sent to `defaultWriter.write()` (line 11).
* The `defaultWriter.ready` property returns a promise that resolves when the sink (the first property of the `WritableStream` constructor) is done writing data. The data source can either write more data (line 9) or call `close()` (line 24). Calling close() too early can prevent data from being written. This is why the example calls `defaultWriter.ready` twice (lines 9 and 22).
* The `Promise` returned by the sink's `write()` method (line 40) tells the `WritableStream` and its writer when to resolve `defaultWriter.ready`.
Specifications
--------------

| Specification |
| --- |
| Streams Standard # ws-class |

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

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

See also
--------

* WHATWG Stream Visualizer, for a basic visualization of readable, writable, and transform streams.


WebGLContextEvent - Web APIs

WebGLContextEvent
=================

The **WebContextEvent** interface is part of the WebGL API and is an interface for an event that is generated in response to a status change to the WebGL rendering context.

Event

WebGLContextEventConstructor
-----------

`WebGLContextEvent()`

Creates a new `WebGLContextEvent` object.

Instance properties
-------------------

*This interface inherits properties from its parent interface, `Event`.*

`WebGLContextEvent.statusMessage`

A read-only property containing additional information about the event.

Instance methods
----------------

*This interface doesn't define any own methods, but inherits methods from its parent interface, `Event`.*

Examples
--------

With the help of the `WEBGL_lose_context` extension, you can simulate the `webglcontextlost` and `webglcontextrestored` events:

```js
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl");

canvas.addEventListener(
  "webglcontextlost",
  (e) => {
    console.log(e);
  },
  false,
);

gl.getExtension("WEBGL\_lose\_context").loseContext();

// WebGLContextEvent event with type "webglcontextlost" is logged.
```

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

| Specification |
| --- |
| WebGL Specification # 5.15 |

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

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

See also
--------

* `WebGLRenderingContext.isContextLost()`
* `WEBGL_lose_context`, `WEBGL_lose_context.loseContext()`, `WEBGL_lose_context.restoreContext()`
* Events: webglcontextlost, webglcontextrestored, webglcontextcreationerror


Background Tasks API - Web APIs

Background Tasks API
====================

The **Cooperative Scheduling of Background Tasks API** (also referred to as the Background Tasks API or the `requestIdleCallback()` API) provides the ability to queue tasks to be executed automatically by the user agent when it determines that there is free time to do so.

**Note:** This API is *not available* in Web Workers.

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

The main thread of a Web browser is centered around its event loop. This code draws any pending updates to the `Document` currently being displayed, runs any JavaScript code the page needs to run, accepts events from input devices, and dispatches those events to the elements that should receive them. In addition, the event loop handles interactions with the operating system, updates to the browser's own user interface, and so forth. It's an extremely busy chunk of code, and your main JavaScript code may run right inside this thread along with all of this. Certainly most if not all code that is capable of making changes to the DOM is running in the main thread, since it's common for user interface changes to only be available to the main thread.

Because event handling and screen updates are two of the most obvious ways users notice performance issues, it's important for your code to be a good citizen of the Web and help to prevent stalls in the execution of the event loop. In the past, there's been no way to do this reliably other than by writing code that's as efficient as possible and by offloading as much work as possible to workers. `Window.requestIdleCallback()` makes it possible to become actively engaged in helping to ensure that the browser's event loop runs smoothly, by allowing the browser to tell your code how much time it can safely use without causing the system to lag. If you stay within the limit given, you can make the user's experience much better.

### Getting the most out of idle callbacks

Because idle callbacks are intended to give your code a way to cooperate with the event loop to ensure that the system is utilized to its full potential without over-tasking it, resulting in lag or other performance problems, you should be thoughtful about how you go about using them.

* **Use idle callbacks for tasks which don't have high priority.** Because you don't know how many callbacks have been established, and you don't know how busy the user's system is, you don't know how often your callback will be run (unless you specify a `timeout`). There's no guarantee that every pass through the event loop (or even every screen update cycle) will include any idle callbacks being executed; if the event loop uses all available time, you're out of luck (again, unless you've used a `timeout`).
* **Idle callbacks should do their best not to overrun the time allotted.** While the browser, your code, and the Web in general will continue to run normally if you go over the specified time limit (even if you go *way* over it), the time restriction is intended to ensure that you leave the system enough time to finish the current pass through the event loop and get on to the next one without causing other code to stutter or animation effects to lag. Currently, `timeRemaining()` has an upper limit of 50 milliseconds, but in reality you will often have less time than that, since the event loop may already be eating into that time on complex sites, with browser extensions needing processor time, and so forth.
* **Avoid making changes to the DOM within your idle callback.** By the time your callback is run, the current frame has already finished drawing, and all layout updates and computations have been completed. If you make changes that affect layout, you may force a situation in which the browser has to stop and do recalculations that would otherwise be unnecessary. If your callback needs to change the DOM, it should use `Window.requestAnimationFrame()` to schedule that.
* **Avoid tasks whose run time can't be predicted.** Your idle callback should avoid doing anything that could take an unpredictable amount of time. For example, anything which might affect layout should be avoided. You should also avoid resolving or rejecting `Promise`s, since that would invoke the handler for that promise's resolution or rejection as soon as your callback returns.
* **Use timeouts when you need to, but only when you need to.** Using timeouts can ensure that your code runs in a timely manner, but it can also allow you to cause lag or animation stutters by mandating that the browser call you when there's not enough time left for you to run without disrupting performance.
Interfaces
----------

The Background Tasks API adds only one new interface:

`IdleDeadline`

An object of this type is passed to the idle callback to provide an estimate of how long the idle period is expected to last, as well as whether or not the callback is running because its timeout period has expired.

The `Window` interface is also augmented by this API to offer the new `requestIdleCallback()` and `cancelIdleCallback()` methods.

Example
-------

In this example, we'll take a look at how you can use `requestIdleCallback()` to run time-consuming, low-priority tasks during time the browser would otherwise be idle. In addition, this example demonstrates how to schedule updates to the document content using `requestAnimationFrame()`.

Below you'll find only the HTML and JavaScript for this example. The CSS is not shown, since it's not particularly crucial to understanding this functionality.

### HTML

In order to be oriented about what we're trying to accomplish, let's have a look at the HTML. This establishes a box (`id="container"`) that's used to present the progress of an operation (because you never know how long decoding "quantum filament tachyon emissions" will take, after all) as well as a second main box (`id="logBox"`), which is used to display textual output.

```html
<p>
  Demonstration of using cooperatively scheduled background tasks using the
  <code>requestIdleCallback()</code> method.
</p>

<div id="container">
  <div class="label">Decoding quantum filament tachyon emissions…</div>

  <progress id="progress" value="0"></progress>

  <button class="button" id="startButton">Start</button>

  <div class="label counter">
    Task <span id="currentTaskNumber">0</span> of
    <span id="totalTaskCount">0</span>
  </div>
</div>

<div id="logBox">
  <div class="logHeader">Log</div>
  <div id="log"></div>
</div>
```

The progress box uses a `<progress>` element to show the progress, along with a label with sections that are changed to present numeric information about the progress. In addition, there's a "Start" button (creatively given the ID "startButton"), which the user will use to start the data processing.
```

body {
  font-family: "Open Sans", "Lucida Grande", "Arial", sans-serif;
  font-size: 16px;
}

#logBox {
  margin-top: 16px;
  width: 400px;
  height: 500px;
  border-radius: 6px;
  border: 1px solid black;
  box-shadow: 4px 4px 2px black;
}

.logHeader {
  margin: 0;
  padding: 0 6px 4px;
  height: 22px;
  background-color: lightblue;
  border-bottom: 1px solid black;
  border-radius: 6px 6px 0 0;
}

#log {
  font:
    12px "Courier",
    monospace;
  padding: 6px;
  overflow: auto;
  overflow-y: scroll;
  width: 388px;
  height: 460px;
}

#container {
  width: 400px;
  padding: 6px;
  border-radius: 6px;
  border: 1px solid black;
  box-shadow: 4px 4px 2px black;
  display: block;
  overflow: auto;
}

.label {
  display: inline-block;
}

.counter {
  text-align: right;
  padding-top: 4px;
  float: right;
}

.button {
  padding-top: 2px;
  padding-bottom: 4px;
  width: 100px;
  display: inline-block;
  float: left;
  border: 1px solid black;
  cursor: pointer;
  text-align: center;
  margin-top: 0;
  color: white;
  background-color: darkgreen;
}

#progress {
  width: 100%;
  padding-top: 6px;
}
```

### JavaScript

Now that the document structure is defined, construct the JavaScript code that will do the work. The goal: to be able to add requests to call functions to a queue, with an idle callback that runs those functions whenever the system is idle for long enough a time to make progress.

#### Variable declarations

```js
const taskList = [];
let totalTaskCount = 0;
let currentTaskNumber = 0;
let taskHandle = null;
```

These variables are used to manage the list of tasks that are waiting to be performed, as well as status information about the task queue and its execution:

* `taskList` is an `Array` of objects, each representing one task waiting to be run.
* `totalTaskCount` is a counter of the number of tasks that have been added to the queue; it will only go up, never down. We use this to do the math to present progress as a percentage of total work to do.
* `currentTaskNumber` is used to track how many tasks have been processed so far.
* `taskHandle` is a reference to the task currently being processed.

```js
const totalTaskCountElem = document.getElementById("totalTaskCount");
const currentTaskNumberElem = document.getElementById("currentTaskNumber");
const progressBarElem = document.getElementById("progress");
const startButtonElem = document.getElementById("startButton");
const logElem = document.getElementById("log");
```

Next we have variables which reference the DOM elements we need to interact with. These elements are:

* `totalTaskCountElem` is the `<span>` we use to insert the total number of tasks created into the status display in the progress box.
* `currentTaskNumberElem` is the element used to display the number of tasks processed so far.
* `progressBarElem` is the `<progress>` element showing the percentage of the tasks processed so far.
* `startButtonElem` is the start button.
* `logElem` is the `<div>` we'll insert logged text messages into.

```js
let logFragment = null;
let statusRefreshScheduled = false;
```

Finally, we set up a couple of variables for other items:

* `logFragment` will be used to store a `DocumentFragment` that's generated by our logging functions to create content to append to the log when the next animation frame is rendered.
* `statusRefreshScheduled` is used to track whether or not we've already scheduled an update of the status display box for the upcoming frame, so that we only do it once per frame
```

requestIdleCallback =
  requestIdleCallback ||
  ((handler) => {
    const startTime = Date.now();

    return setTimeout(() => {
      handler({
        didTimeout: false,
        timeRemaining() {
          return Math.max(0, 50.0 - (Date.now() - startTime));
        },
      });
    }, 1);
  });

cancelIdleCallback =
  cancelIdleCallback ||
  ((id) => {
    clearTimeout(id);
  });
```

#### Managing the task queue

Next, let's look at the way we manage the tasks that need to be performed. We're going to do this by creating a FIFO queue of tasks, which we'll run as time allows during the idle callback period.

##### Enqueueing tasks

First, we need a function that enqueues tasks for future execution. That function, `enqueueTask()`, looks like this:

```js
function enqueueTask(taskHandler, taskData) {
  taskList.push({
    handler: taskHandler,
    data: taskData,
  });

  totalTaskCount++;

  if (!taskHandle) {
    taskHandle = requestIdleCallback(runTaskQueue, { timeout: 1000 });
  }

  scheduleStatusRefresh();
}
```

`enqueueTask()` accepts as input two parameters:

* `taskHandler` is a function which will be called to handle the task.
* `taskData` is an object which is passed into the task handler as an input parameter, to allow the task to receive custom data.

To enqueue the task, we push an object onto the `taskList` array; the object contains the `taskHandler` and `taskData` values under the names `handler` and `data`, respectively, then increment `totalTaskCount`, which reflects the total number of tasks which have ever been enqueued (we don't decrement it when tasks are removed from the queue).

Next, we check to see if we already have an idle callback created; if `taskHandle` is 0, we know there isn't an idle callback yet, so we call `requestIdleCallback()` to create one. It's configured to call a function called `runTaskQueue()`, which we'll look at shortly, and with a `timeout` of 1 second, so that it will be run at least once per second even if there isn't any actual idle time available.

##### Running tasks

Our idle callback handler, `runTaskQueue()`, gets called when the browser determines there's enough idle time available to let us do some work or our timeout of one second expires. This function's job is to run our enqueued tasks.

```js
function runTaskQueue(deadline) {
  while (
    (deadline.timeRemaining() > 0 || deadline.didTimeout) &&
    taskList.length
  ) {
    const task = taskList.shift();
    currentTaskNumber++;

    task.handler(task.data);
    scheduleStatusRefresh();
  }

  if (taskList.length) {
    taskHandle = requestIdleCallback(runTaskQueue, { timeout: 1000 });
  } else {
    taskHandle = 0;
  }
}
```

`runTaskQueue()`'s core is a loop which continues as long as there's time left (as determined by checking `deadline.timeRemaining`) to be sure it's more than 0 or if the timeout limit was reached (`deadline.didTimeout` is true), and as long as there are tasks in the task list.

For each task in the queue that we have time to execute, we do the following:

1. We remove the task object from the queue.
2. We increment `currentTaskNumber` to track how many tasks we've executed.
3. We call the task's handler, `task.handler`, passing into it the task's data object (`task.data`).
4. We call a function, `scheduleStatusRefresh()`, to handle scheduling a screen update to reflect changes to our progress.

When time runs out, if there are still tasks left in the list, we call `requestIdleCallback()` again so that we can continue to process the tasks the next time there's idle time available. If the queue is empty, we set taskHandle to 0 to indicate that we don't have a callback scheduled. That way, we'll know to request a callback next time `enqueueTask()` is called.

#### Updating the status display

One thing we want to be able to do is update our document with log output and progress information. However, you can't safely change the DOM from within an idle callback. Instead, we'll use `requestAnimationFrame()` to ask the browser to call us when it's safe to update the display.

##### Scheduling display updates

DOM changes are scheduled by calling the `scheduleStatusRefresh()` function.

```js
function scheduleStatusRefresh() {
  if (!statusRefreshScheduled) {
    requestAnimationFrame(updateDisplay);
    statusRefreshScheduled = true;
  }
}
```

This is a simple function. It checks to see if we've already scheduled a display refresh by checking the value of `statusRefreshScheduled`. If it's `false`, we call `requestAnimationFrame()` to schedule a refresh, providing the `updateDisplay()` function to be called to handle that work.

##### Updating the display

The `updateDisplay()` function is responsible for drawing the contents of the progress box and the log. It's called by the browser when the DOM is in a safe condition for us to apply changes during the process of rendering the next frame.

```js
function updateDisplay() {
  const scrolledToEnd =
    logElem.scrollHeight - logElem.clientHeight <= logElem.scrollTop + 1;

  if (totalTaskCount) {
    if (progressBarElem.max !== totalTaskCount) {
      totalTaskCountElem.textContent = totalTaskCount;
      progressBarElem.max = totalTaskCount;
    }

    if (progressBarElem.value !== currentTaskNumber) {
      currentTaskNumberElem.textContent = currentTaskNumber;
      progressBarElem.value = currentTaskNumber;
    }
  }

  if (logFragment) {
    logElem.appendChild(logFragment);
    logFragment = null;
  }

  if (scrolledToEnd) {
    logElem.scrollTop = logElem.scrollHeight - logElem.clientHeight;
  }

  statusRefreshScheduled = false;
}
```

First, `scrolledToEnd` is set to `true` if the text in the log is scrolled to the bottom; otherwise it's set to `false`. We'll use that to determine if we should update the scroll position to ensure that the log stays at the end when we're done adding content to it.

Next, we update the progress and status information if any tasks have been enqueued.

1. If the current maximum value of the progress bar is different from the current total number of enqueued tasks (`totalTaskCount`), then we update the contents of the displayed total number of tasks (`totalTaskCountElem`) and the maximum value of the progress bar, so that it scales properly.
2. We do the same thing with the number of tasks processed so far; if `progressBarElem.value` is different from the task number currently being processed (`currentTaskNumber`), then we update the displayed value of the currently-being-processed task and the current value of the progress bar.

Then, if there's text waiting to be added to the log (that is, if `logFragment` isn't `null`), we append it to the log element using `Element.appendChild()` and set `logFragment` to `null` so we don't add it again.

If the log was scrolled to the end when we started, we make sure it still is. Then we set `statusRefreshScheduled` to `false` to indicate that we've handled the refresh and that it's safe to request a new one.

#### Adding text to the log

The `log()` function adds the specified text to the log. Since we don't know at the time `log()` is called whether or not it's safe to immediately touch the DOM, we will cache the log text until it's safe to update. Above, in the code for `updateDisplay()`, you can find the code that actually adds the logged text to the log element when the animation frame is being updated.

```js
function log(text) {
  if (!logFragment) {
    logFragment = document.createDocumentFragment();
  }

  const el = document.createElement("div");
  el.textContent = text;
  logFragment.appendChild(el);
}
```

First, we create a `DocumentFragment` object named `logFragment` if one doesn't currently exist. This element is a pseudo-DOM into which we can insert elements without immediately changing the main DOM itself.

We then create a new `<div>` element and set its contents to match the input `text`. Then we append the new element to the end of the pseudo-DOM in `logFragment`. `logFragment` will accumulate log entries until the next time `updateDisplay()` is called because the DOM for the changes.

### Running tasks

Now that we've got the task management and display maintenance code done, we can actually start setting up code to run tasks that get work done.

#### The task handler

The function we'll be using as our task handler—that is, the function that will be used as the value of the task object's `handler` property—is `logTaskHandler()`. It's a simple function that outputs a bunch of stuff to the log for each task. In your own application, you'd replace this code with whatever task it is you wish to perform during idle time. Just remember that anything you want to do that changes the DOM needs to be handled through `requestAnimationFrame()`.

```js
function logTaskHandler(data) {
  log(`Running task #${currentTaskNumber}`);

  for (let i = 0; i < data.count; i += 1) {
    log(`${(i + 1).toString()}. ${data.text}`);
  }
}
```

#### The main program

Everything is triggered when the user clicks the Start button, which causes the `decodeTechnoStuff()` function to be called.
```

function getRandomIntInclusive(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() \* (max - min + 1)) + min;
}
```

```js
function decodeTechnoStuff() {
  totalTaskCount = 0;
  currentTaskNumber = 0;
  updateDisplay();

  const n = getRandomIntInclusive(100, 200);

  for (let i = 0; i < n; i++) {
    const taskData = {
      count: getRandomIntInclusive(75, 150),
      text: `This text is from task number ${i + 1} of ${n}`,
    };

    enqueueTask(logTaskHandler, taskData);
  }
}

document
  .getElementById("startButton")
  .addEventListener("click", decodeTechnoStuff, false);
```

`decodeTechnoStuff()` starts by zeroing the values of totalTaskCount (the number of tasks added to the queue so far) and currentTaskNumber (the task currently being run), and then calls `updateDisplay()` to reset the display to its "nothing's happened yet" state.

This example will create a random number of tasks (between 100 and 200 of them). To do so, we use the `getRandomIntInclusive()` function that's provided as an example in the documentation for `Math.random()` to get the number of tasks to create.

Then we start a loop to create the actual tasks. For each task, we create an object, `taskData`, which includes two properties:

* `count` is the number of strings to output into the log from the task.
* `text` is the text to output to the log the number of times specified by `count`.

Each task is then enqueued by calling `enqueueTask()`, passing in `logTaskHandler()` as the handler function and the `taskData` object as the object to pass into the function when it's called.

### Result

Below is the actual functioning result of the code above. Try it out, play with it in your browser's developer tools, and experiment with using it in your own code.

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

| Specification |
| --- |
| requestIdleCallback() Cooperative Scheduling of Background Tasks # the-requestidlecallback-method |

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

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

See also
--------

* `Window.requestIdleCallback()`
* `Window.cancelIdleCallback()`
* `IdleDeadline`


PositionSensorVRDevice - Web APIs

PositionSensorVRDevice
======================

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

**Non-standard:** This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

The **`PositionSensorVRDevice`** interface of the WebVR API represents VR hardware's position sensor. You can access information such as the current position and orientation of the sensor in relation to the head mounted display through the `PositionSensorVRDevice.getState()` method.

Instance methods
----------------

`PositionSensorVRDevice.getState()`
Deprecated

Non-standard

Returns the current state of the position sensor for the current frame (e.g. within the current `window.requestAnimationFrame` callback) or for the previous frame, contained with a `VRPose` object. This is the method you'd normally want to use, versus `getImmediateState()`.

`PositionSensorVRDevice.getImmediateState()`
Deprecated

Non-standard

Returns the current instantaneous position sensor state. This is intended to only be used rarely, for certain special uses, for example sampling the immediate position of a hand orientation sensor — or at least it will be, in the future.

`PositionSensorVRDevice.resetSensor()`
Deprecated

Non-standard

*Can be used to reset the sensor if desired, returning the* position and orientation values to zero.

Instance properties
-------------------

*This interface doesn't define any properties of its own, but it does inherit the properties of its parent interface, `VRDisplay`.*

`VRDisplay.displayId` Read only

Returns the ID for this specific `VRDevice`. The ID shouldn't change across browser restarts, allowing configuration data to be saved based on it.

`VRDisplay.displayName` Read only

A human-readable name to identify the `VRDevice`.

Examples
--------

The following example uses the WebVR API to update the view of a simple `2D canvas` scene on each frame of a `requestAnimationFrame` loop.

```js
function setView() {
  const posState = gPositionSensor.getState();
  if (posState.hasPosition) {
    posPara.textContent = `Position: x${roundToTwo(
 posState.position.x,
 )} y${roundToTwo(posState.position.y)} z${roundToTwo(posState.position.z)}`;
    xPos = -posState.position.x \* WIDTH \* 2;
    yPos = posState.position.y \* HEIGHT \* 2;
    zPos = -posState.position.z > 0.01 ? -posState.position.z : 0.01;
  }

  if (posState.hasOrientation) {
    orientPara.textContent = `Orientation: x${roundToTwo(
 posState.orientation.x,
 )} y${roundToTwo(posState.orientation.y)} z${roundToTwo(
 posState.orientation.z,
 )}`;
    xOrient = posState.orientation.x \* WIDTH;
    yOrient = -posState.orientation.y \* HEIGHT \* 2;
    zOrient = posState.orientation.z \* 180;
  }
}
```

Here we are grabbing a `VRPose` object using `PositionSensorVRDevice.getState()` and storing it in `posState`. We then check to make sure that position and orientation info is present in the current frame using `VRPose.position` and `VRPose.orientation` (these return `null` if, for example the head mounted display is turned off or not pointing at the position sensor, which would cause an error.)

We then output the x, y and z position and orientation values for informational purposes, and use those values to update the `xPos`, `yPos`, `zPos`, `xOrient`, `yOrient`, and `zOrient` variables, which are used to update the scene rendering on each frame.

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

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

See also
--------

* WebVR API


CSSMathNegate - Web APIs

CSSMathNegate
=============

The **`CSSMathNegate`** interface of the CSS\_Object\_Model#css\_typed\_object\_model negates the value passed into it. It inherits properties and methods from its parent `CSSNumericValue`.

CSSStyleValue

CSSNumericValue

CSSMathValue

CSSMathNegateConstructor
-----------

`CSSMathNegate()`

Creates a new `CSSMathNegate` object.

Instance properties
-------------------

`CSSMathNegate.value` Read only

Returns a `CSSNumericValue` object.

Static methods
--------------

*The interface may also inherit methods from its parent interface, `CSSMathValue`.*

Instance methods
----------------

*The interface may also inherit methods from its parent interface, `CSSMathValue`.*

Examples
--------

To do

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

| Specification |
| --- |
| CSS Typed OM Level 1 # cssmathnegate |

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

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


GPUAdapter - Web APIs

GPUAdapter
==========

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`GPUAdapter`** interface of the WebGPU API represents a GPU adapter. From this you can request a `GPUDevice`, adapter info, features, and limits.

A `GPUAdapter` object is requested using the `GPU.requestAdapter()` method.

Instance properties
-------------------

`features`
Experimental
 Read only

A `GPUSupportedFeatures` object that describes additional functionality supported by the adapter.

`isFallbackAdapter`
Experimental
 Read only

A boolean value. Returns `true` if the adapter is a fallback adapter, and `false` if not.

`limits`
Experimental
 Read only

A `GPUSupportedLimits` object that describes the limits supported by the adapter.

Instance methods
----------------

`requestAdapterInfo()`
Experimental

Returns a `Promise` that fulfills with a `GPUAdapterInfo` object containing identifying information about an adapter.

`requestDevice()`
Experimental

Returns a `Promise` that fulfills with a `GPUDevice` object, which is the primary interface for communicating with the GPU.

Examples
--------

```js
async function init() {
  if (!navigator.gpu) {
    throw Error("WebGPU not supported.");
  }

  const adapter = await navigator.gpu.requestAdapter();
  if (!adapter) {
    throw Error("Couldn't request WebGPU adapter.");
  }

  const device = await adapter.requestDevice();

  //...
}
```

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

| Specification |
| --- |
| WebGPU # gpu-adapter |

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

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

See also
--------

* The WebGPU API


OverconstrainedError - Web APIs

OverconstrainedError
====================

The **`OverconstrainedError`** interface of the Media Capture and Streams API indicates that the set of desired capabilities for the current `MediaStreamTrack` cannot currently be met. When this event is thrown on a MediaStreamTrack, it is muted until either the current constraints can be established or until satisfiable constraints are applied.

DOMException

OverconstrainedErrorConstructor
-----------

`OverconstrainedError()`

Creates a new `OverconstrainedError` object.

Instance properties
-------------------

*Also inherits properties from its parent interface, `DOMException`.*

`OverconstrainedError.constraint` Read only

Returns the constraint that was supplied in the constructor, meaning the constraint that was not satisfied.

Instance methods
----------------

*Also inherits methods from its parent interface, `DOMException`.*

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

| Specification |
| --- |
| Media Capture and Streams # overconstrainederror-interface |

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

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


PasswordCredential - Web APIs

PasswordCredential
==================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

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

The interface of the Credential Management API provides information about a username/password pair. In supporting browsers an instance of this class may be passed in the `credential` member of the `init` object for global `fetch()`.

**Note:** This interface is restricted to top-level contexts and cannot be used from an `<iframe>`.

Credential

PasswordCredentialConstructor
-----------

`PasswordCredential()`
Experimental

Creates a new `PasswordCredential` object.

Instance properties
-------------------

*Inherits properties from its ancestor, `Credential`.*

`PasswordCredential.iconURL` Read only
Experimental

A string containing a URL pointing to an image for an icon. This image is intended for display in a credential chooser. The URL must be accessible without authentication.

`PasswordCredential.name` Read only
Experimental

A human-readable string that provides public name for display in a credential chooser.

`PasswordCredential.password` Read only
Experimental

A string containing the password of the credential.

### Event handlers

None.

Instance methods
----------------

None.

Examples
--------

```js
const cred = new PasswordCredential({
  id,
  password,
  name,
  iconURL,
});

navigator.credentials.store(cred).then(() => {
  // Do something else.
});
```

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

| Specification |
| --- |
| Credential Management Level 1 # passwordcredential-interface |

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

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


MediaKeys - Web APIs

MediaKeys
=========

The **`MediaKeys`** interface of Encrypted Media Extensions API represents a set of keys that an associated `HTMLMediaElement` can use for decryption of media data during playback.

Instance properties
-------------------

None.

Instance methods
----------------

`MediaKeys.createSession()`

Returns a new `MediaKeySession` object, which represents a context for message exchange with a content decryption module (CDM).

`MediaKeys.setServerCertificate()`

Returns a `Promise` to a server certificate to be used to encrypt messages to the license server.

Examples
--------

```js
//TBD
```

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

| Specification |
| --- |
| Encrypted Media Extensions # mediakeys-interface |

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

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


XRRay - Web APIs

XRRay
=====

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

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`XRRay`** interface of the WebXR Device API is a geometric ray described by an origin point and a direction vector.

`XRRay` objects can be passed to `XRSession.requestHitTestSource()` or `XRSession.requestHitTestSourceForTransientInput()` to perform hit testing.

Constructor
-----------

`XRRay()`
Experimental

Creates a new `XRRay` object.

Instance properties
-------------------

`XRRay.direction` Read only
Experimental

A `DOMPointReadOnly` representing the ray's 3-dimensional directional vector.

`XRRay.matrix` Read only
Experimental

A transform that can be used to position objects along the `XRRay`. This is a 4 by 4 matrix given as a 16 element `Float32Array` in column major order.

`XRRay.origin` Read only
Experimental

A `DOMPointReadOnly` representing the 3-dimensional point in space that the ray originates from, in meters.

Instance methods
----------------

None.

Examples
--------

### Using `XRRay` to request a hit test source

The `XRSession.requestHitTestSource()` method takes an `XRRay` object for its `offsetRay` option. In this example, the hit test source is positioned slightly above the viewer as the application has some UI elements at the bottom while wanting to maintain the perception of a centered cursor.

```js
const xrSession = navigator.xr.requestSession("immersive-ar", {
  requiredFeatures: ["local", "hit-test"],
});

let hitTestSource = null;

xrSession
  .requestHitTestSource({
    space: viewerSpace, // obtained from xrSession.requestReferenceSpace("viewer");
    offsetRay: new XRRay({ y: 0.5 }),
  })
  .then((viewerHitTestSource) => {
    hitTestSource = viewerHitTestSource;
  });
```

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

| Specification |
| --- |
| WebXR Hit Test Module # xrray-interface |

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

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

See also
--------

* `XRSession.requestHitTestSource()`
* `XRHitTestResult`


OrientationSensor - Web APIs

OrientationSensor
=================

The **`OrientationSensor`** interface of the Sensor APIs is the base class for orientation sensors. This interface cannot be used directly. Instead it provides properties and methods accessed by interfaces that inherit from it.

This feature may be blocked by a Permissions Policy set on your server.

EventTarget

Sensor

OrientationSensorInterfaces based on OrientationSensor
-------------------------------------

Below is a list of interfaces based on the OrientationSensor interface.

* `AbsoluteOrientationSensor`
* `RelativeOrientationSensor`
Instance properties
-------------------

`OrientationSensor.quaternion`

Returns a four element `Array` whose elements contain the components of the unit quaternion representing the device's orientation.

Instance methods
----------------

`OrientationSensor.populateMatrix()`

Populates the given object with the rotation matrix based on the latest sensor reading.

Examples
--------

### Basic Example

The following example, which is loosely based on Intel's Orientation Phone demo, instantiates an `AbsoluteOrientationSensor` with a frequency of 60 times a second. On each reading it uses `OrientationSensor.quaternion` to rotate a visual model of a phone.

```js
const options = { frequency: 60, referenceFrame: "device" };
const sensor = new AbsoluteOrientationSensor(options);

sensor.addEventListener("reading", () => {
  // model is a Three.js object instantiated elsewhere.
  model.quaternion.fromArray(sensor.quaternion).inverse();
});
sensor.addEventListener("error", (error) => {
  if (event.error.name === "NotReadableError") {
    console.log("Sensor is not available.");
  }
});
sensor.start();
```

### Permissions Example

Using orientation sensors requires requesting permissions for multiple device sensors. Because the `Permissions` interface uses promises, a good way to request permissions is to use `Promise.all`.

```js
const sensor = new AbsoluteOrientationSensor();
Promise.all([
  navigator.permissions.query({ name: "accelerometer" }),
  navigator.permissions.query({ name: "magnetometer" }),
  navigator.permissions.query({ name: "gyroscope" }),
]).then((results) => {
  if (results.every((result) => result.state === "granted")) {
    sensor.start();
    // …
  } else {
    console.log("No permissions to use AbsoluteOrientationSensor.");
  }
});
```

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

| Specification |
| --- |
| Orientation Sensor # orientationsensor-interface |

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

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