1. 8.9 Images
    2. 8.10 Animation frames

8.9 Images

An ImageBitmap object represents a bitmap image that can be painted to a canvas without undue latency.

The exact judgement of what is undue latency of this is left up to the implementer, but in general if making use of the bitmap requires network I/O, or even local disk I/O, then the latency is probably undue; whereas if it only requires a blocking read from a GPU or system RAM, the latency is probably acceptable.

promise = self . createImageBitmap(image [, options ])
promise = self . createImageBitmap(image, sx, sy, sw, sh [, options ])

Takes image, which can be an img element, an SVG image element, a video element, a canvas element, a Blob object, an ImageData object, or another ImageBitmap object, and returns a promise that is resolved when a new ImageBitmap is created.

If no ImageBitmap object can be constructed, for example because the provided image data is not actually an image, then the promise is rejected instead.

If sx, sy, sw, and sh arguments are provided, the source image is cropped to the given pixels, with any pixels missing in the original replaced by transparent black. These coordinates are in the source image's pixel coordinate space, not in CSS pixels.

If options is provided, the ImageBitmap object's bitmap data is modified according to options. For example, if the premultiplyAlpha option is set to "premultiply", the bitmap data's color channels are premultiplied by its alpha channel.

Rejects the promise with an "InvalidStateError" DOMException if the source image is not in a valid state (e.g., an img element that hasn't loaded successfully, an ImageBitmap object whose [[Detached]] internal slot value is true, an ImageData object whose data attribute value's [[ViewedArrayBuffer]] internal slot is detached, or a Blob whose data cannot be interpreted as a bitmap image).

Rejects the promise with a "SecurityError" DOMException if the script is not allowed to access the image data of the source image (e.g. a video that is CORS-cross-origin, or a canvas being drawn on by a script in a worker from another origin).

imageBitmap . close()

Releases imageBitmap's underlying bitmap data.

imageBitmap . width

Returns the intrinsic width of the image, in CSS pixels.

imageBitmap . height

Returns the intrinsic height of the image, in CSS pixels.

Support: createimagebitmapChrome for Android 70+Chrome 59+iOS Safari NoneUC Browser for Android 11.8+Firefox 42+IE NoneOpera Mini NoneSafari NoneEdge NoneOpera 46+Samsung Internet 6.2+Android Browser 67+

Source: caniuse.com

Using this API, a sprite sheet can be precut and prepared:

var sprites = {};
function loadMySprites() {
  var image = new Image();
  image.src = 'mysprites.png';
  var resolver;
  var promise = new Promise(function (arg) { resolver = arg });
  image.onload = function () {
    resolver(Promise.all([
      createImageBitmap(image,  0,  0, 40, 40).then(function (image) { sprites.person = image }),
      createImageBitmap(image, 40,  0, 40, 40).then(function (image) { sprites.grass  = image }),
      createImageBitmap(image, 80,  0, 40, 40).then(function (image) { sprites.tree   = image }),
      createImageBitmap(image,  0, 40, 40, 40).then(function (image) { sprites.hut    = image }),
      createImageBitmap(image, 40, 40, 40, 40).then(function (image) { sprites.apple  = image }),
      createImageBitmap(image, 80, 40, 40, 40).then(function (image) { sprites.snake  = image })
    ]));
  };
  return promise;
}

function runDemo() {
  var canvas = document.querySelector('canvas#demo');
  var context = canvas.getContext('2d');
  context.drawImage(sprites.tree, 30, 10);
  context.drawImage(sprites.snake, 70, 10);
}

loadMySprites().then(runDemo);

8.10 Animation frames

Support: requestanimationframeChrome for Android 70+Chrome 24+iOS Safari 7.0+UC Browser for Android 11.8+Firefox 23+IE 10+Opera Mini NoneSafari 6.1+Edge 12+Opera 15+Samsung Internet 4+Android Browser 4.4+

Source: caniuse.com

Some objects include the AnimationFrameProvider interface mixin.

Each AnimationFrameProvider object also has a target object that stores the provider's internal state. It is defined as follows:

If the AnimationFrameProvider is a Window
The Window's associated Document
If the AnimationFrameProvider is a DedicatedWorkerGlobalScope
The DedicatedWorkerGlobalScope

Each target object has a map of animation frame callbacks, which is an ordered map that must be initially empty, and an animation frame callback identifier, which is a number that must initially be zero.

An AnimationFrameProvider provider is considered supported if any of the following hold:


The requestAnimationFrame(callback) method must run the following steps:

  1. If this AnimationFrameProvider is not supported, then throw a "NotSupportedError" DOMException.

  2. Let target be this AnimationFrameProvider's target object.

  3. Increment target's animation frame callback identifier by one, and let handle be the result.

  4. Let callbacks be target's map of animation frame callbacks.

  5. Set callbacks[handle] to callback.

  6. Return handle.

The cancelAnimationFrame(handle) method must run the following steps:

  1. If this AnimationFrameProvider is not supported, then throw a "NotSupportedError" DOMException.

  2. Let callbacks be this AnimationFrameProvider's target object's map of animation frame callbacks.

  3. Remove callbacks[handle].

To run the animation frame callbacks for a target object target with a timestamp now:

  1. Let callbacks be a clone of target's map of animation frame callbacks.

  2. Set target's map of animation frame callbacks to a new empty ordered map.

  3. For each handlecallback of callbacks, invoke callback, passing now as the only argument, and if an exception is thrown, report the exception.

Inside workers, requestAnimationFrame() can be used together with an OffscreenCanvas transferred from a canvas element. First, in the document, transfer control to the worker:

const offscreenCanvas = document.getElementById("c").transferControlToOffscreen();
worker.postMessage(offscreenCanvas, [offscreenCanvas]);

Then, in the worker, the following code will draw a rectangle moving from left to right:

let ctx, pos = 0;
function draw(dt) {
  ctx.clearRect(0, 0, 100, 100);
  ctx.fillRect(pos, 0, 10, 10);
  pos += 10 * dt;
  requestAnimationFrame(draw);
}

self.onmessage = function(ev) {
  const transferredCanvas = ev.data;
  ctx = transferredCanvas.getContext("2d");
  draw();
};