WebGLRenderingContext: getFramebufferAttachmentParameter() method - Web APIs

WebGLRenderingContext: getFramebufferAttachmentParameter() method
=================================================================

 The
 **`WebGLRenderingContext.getFramebufferAttachmentParameter()`**
 method of the WebGL API returns information
 about a framebuffer's attachment.

Syntax
------

```js
getFramebufferAttachmentParameter(target, attachment, pname)
```

### Parameters

`target`

A `GLenum` specifying the binding point (target). Possible values:

`gl.FRAMEBUFFER`

 Collection buffer data storage of color, alpha,
 depth and stencil buffers used to render an image.

 When using a WebGL 2 context,
 the following values are available additionally:

`gl.DRAW_FRAMEBUFFER`

 Equivalent to `gl.FRAMEBUFFER`.
 Used as a destination for drawing, rendering, clearing, and writing operations.

`gl.READ_FRAMEBUFFER`

Used as a source for reading operations.

`attachment`

 A `GLenum` specifying the attachment point for the
 `texture`. Possible values:

* `gl.COLOR_ATTACHMENT0`: Texture attachment for the framebuffer's
 color buffer.
* `gl.DEPTH_ATTACHMENT`: Texture attachment for the framebuffer's depth
 buffer.
* `gl.STENCIL_ATTACHMENT`: Texture attachment for the framebuffer's
 stencil buffer.
* `gl.DEPTH_STENCIL_ATTACHMENT`: Texture attachment for both, the depth
 and stencil buffer.

 When using a WebGL 2 context,
 the following values are available additionally:

* `gl.COLOR_ATTACHMENT1 gl.COLOR_ATTACHMENT2 gl.COLOR_ATTACHMENT3 gl.COLOR_ATTACHMENT4 gl.COLOR_ATTACHMENT5 gl.COLOR_ATTACHMENT6 gl.COLOR_ATTACHMENT7 gl.COLOR_ATTACHMENT8 gl.COLOR_ATTACHMENT9 gl.COLOR_ATTACHMENT10 gl.COLOR_ATTACHMENT11 gl.COLOR_ATTACHMENT12 gl.COLOR_ATTACHMENT13 gl.COLOR_ATTACHMENT14 gl.COLOR_ATTACHMENT15`

When using the `WEBGL_draw_buffers` extension:

* `ext.COLOR_ATTACHMENT0_WEBGL` (same as
 `gl.COLOR_ATTACHMENT0`)
 `ext.COLOR_ATTACHMENT1_WEBGL ext.COLOR_ATTACHMENT2_WEBGL ext.COLOR_ATTACHMENT3_WEBGL ext.COLOR_ATTACHMENT4_WEBGL ext.COLOR_ATTACHMENT5_WEBGL ext.COLOR_ATTACHMENT6_WEBGL ext.COLOR_ATTACHMENT7_WEBGL ext.COLOR_ATTACHMENT8_WEBGL ext.COLOR_ATTACHMENT9_WEBGL ext.COLOR_ATTACHMENT10_WEBGL ext.COLOR_ATTACHMENT11_WEBGL ext.COLOR_ATTACHMENT12_WEBGL ext.COLOR_ATTACHMENT13_WEBGL ext.COLOR_ATTACHMENT14_WEBGL ext.COLOR_ATTACHMENT15_WEBGL`

`pname`

A `GLenum` specifying information to query. Possible values:

* `gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE`: The type which contains the
 attached image.
* `gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME`: The texture or renderbuffer
 of the attached image (`WebGLRenderbuffer` or
 `WebGLTexture`).
* `gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL`: Mipmap level. Default
 value: 0.
* `gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE`: The name of
 cube-map face of the texture.

When using the `EXT_sRGB` extension:

* `ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT`: The framebuffer
 color encoding.

 When using a WebGL 2 context,
 the following values are available additionally:

* `gl.FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE`
* `gl.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE`
* `gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING`
* `gl.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE`
* `gl.FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE`
* `gl.FRAMEBUFFER_ATTACHMENT_GREEN_SIZE`
* `gl.FRAMEBUFFER_ATTACHMENT_RED_SIZE`
* `gl.FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE`
* `gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER`

When using the `OVR_multiview2` extension:

* `ext.FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR`: the number of views of the framebuffer object attachment.
* `ext.FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR`: the base view index of the framebuffer object attachment.

### Return value

 Depends on the requested information (as specified with `pname`). Either a
 `GLint`, a `GLenum`, a `WebGLRenderbuffer`, or a
 `WebGLTexture`.

| `pname` parameter | Return value |
| --- | --- |
| `gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE` |
 A `GLenum` indicating the
 type of the texture. Either `gl.RENDERBUFFER`,
 `gl.TEXTURE`, or if no image is attached,
 `gl.NONE`.
  |
| `gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME` |
 The texture (`WebGLTexture`) or renderbuffer
 (`WebGLRenderbuffer`) of the attached image.
  |
| `gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL` |
 A `GLint` indicating the
 mipmap level. Default value: 0.
  |
| `gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE` |
 A `GLenum` indicating the
 name of cube-map face of the texture. Possible values:
 * `gl.TEXTURE_CUBE_MAP_POSITIVE_X`: Image for the positive
 X face of the cube.
* `gl.TEXTURE_CUBE_MAP_NEGATIVE_X`: Image for the negative
 X face of the cube.
* `gl.TEXTURE_CUBE_MAP_POSITIVE_Y`: Image for the positive
 Y face of the cube.
* `gl.TEXTURE_CUBE_MAP_NEGATIVE_Y`: Image for the negative
 Y face of the cube.
* `gl.TEXTURE_CUBE_MAP_POSITIVE_Z`: Image for the positive
 Z face of the cube.
* `gl.TEXTURE_CUBE_MAP_NEGATIVE_Z`: Image for the negative
 Z face of the cube.
 |
| `gl.FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE` |
 A `GLint` indicating the
 number of bits in the alpha component of the attachment.
  |
| `gl.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE` |
 A `GLint` indicating the
 number of bits in the blue component of the attachment.
  |
| `gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING` |
 A `GLenum` indicating the
 encoding of components of the specified attachment. Either
 `gl.LINEAR` or `gl.SRGB`.
  |
| `gl.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE` |
 A `GLenum` indicating the
 format of the components of the specified attachment. Either
 `gl.FLOAT`, `gl.INT`,
 `gl.UNSIGNED_INT`, `gl.SIGNED_NORMALIZED`, or
 `gl.UNSIGNED_NORMALIZED`.
  |
| `gl.FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE` |
 A `GLint` indicating the
 number of bits in the depth component of the attachment.
  |
| `gl.FRAMEBUFFER_ATTACHMENT_GREEN_SIZE` |
 A `GLint` indicating the
 number of bits in the green component of the attachment.
  |
| `gl.FRAMEBUFFER_ATTACHMENT_RED_SIZE` |
 A `GLint` indicating the
 number of bits in the red component of the attachment.
  |
| `gl.FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE` |
 A `GLint` indicating the
 number of bits in the stencil component of the attachment.
  |
| `gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER` |
 A `GLint` indicating the
 number of the texture layer which contains the attached image.
  |
| `ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT` |
 A `GLenum` indicating the
 framebuffer color encoding. Either `gl.LINEAR` or
 `ext.SRGB_EXT`.
  |
| `ext.FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR` |
 A `GLsizei` indicating
 the number of views of the framebuffer object attachment.
  |
| `ext.FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR` |
 A `GLint` indicating the
 base view index of the framebuffer object attachment.
  |

### Exceptions

* A `gl.INVALID_ENUM` error is thrown if `target` is not
 `gl.FRAMEBUFFER`, `gl.DRAW_FRAMEBUFFER`,
 `gl.READ_FRAMEBUFFER` or if `attachment` is not one of the
 accepted attachment points.
Examples
--------

```js
gl.getFramebufferAttachmentParameter(
  gl.FRAMEBUFFER,
  gl.COLOR\_ATTACHMENT0,
  gl.FRAMEBUFFER\_ATTACHMENT\_OBJECT\_TYPE,
);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.6 |
| WebGL 2.0 Specification # 3.7.4 |

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

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

See also
--------

* `WebGLRenderingContext.createFramebuffer()`
* `WebGLRenderingContext.deleteFramebuffer()`
* `WebGLRenderingContext.isFramebuffer()`
* Other buffers: `WebGLBuffer`, `WebGLRenderbuffer`
* `EXT_sRGB`
* `WEBGL_draw_buffers`


WebGLRenderingContext: polygonOffset() method - Web APIs

WebGLRenderingContext: polygonOffset() method
=============================================

 The **`WebGLRenderingContext.polygonOffset()`** method of the
 WebGL API specifies the scale factors and
 units to calculate depth values.

 The offset is added before the depth test is performed and before the value is written
 into the depth buffer.

Syntax
------

```js
polygonOffset(factor, units)
```

### Parameters

`factor`

 A `GLfloat` which sets the scale factor for the variable depth offset
 for each polygon. The default value is 0.

`units`

 A `GLfloat` which sets the multiplier by which an
 implementation-specific value is multiplied with to create a constant depth offset.
 The default value is 0.

### Return value

None (`undefined`).

Examples
--------

 The polygon offset fill is disabled by default. To enable or disable polygon offset
 fill, use the `enable()` and
 `disable()` methods with the argument
 `gl.POLYGON_OFFSET_FILL`.

```js
gl.enable(gl.POLYGON\_OFFSET\_FILL);
gl.polygonOffset(2, 3);
```

 To check the current polygon offset factor or units, query the
 `POLYGON_OFFSET_FACTOR` and `POLYGON_OFFSET_UNITS` constants.

```js
gl.getParameter(gl.POLYGON\_OFFSET\_FACTOR); // 2
gl.getParameter(gl.POLYGON\_OFFSET\_UNITS); // 3
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.3 |

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

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

See also
--------

* `WebGLRenderingContext.depthFunc()`


WebGLRenderingContext: isContextLost() method - Web APIs

WebGLRenderingContext: isContextLost() method
=============================================

 The
 **`WebGLRenderingContext.isContextLost()`** method returns a
 boolean value indicating whether or not the WebGL context has been lost and
 must be re-established before rendering can resume.

Syntax
------

```js
isContextLost()
```

### Parameters

None.

### Return value

 A boolean value which is `true` if the context is lost, or
 `false` if not.

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

 There are several reasons why a WebGL context may be lost, making it necessary to
 re-establish the context before resuming rendering. Examples include:

* Two or more pages are using the GPU, but together place too high a demand on the
 GPU, so the browser tells the two contexts that they've lost the connection, then
 selects one of the two to restore access for.
* The user's computer has multiple graphics processors (such as a laptop with both
 mobile and desktop class GPUs, the former used primarily when on battery power), and
 the user or system decides to switch GPUs. In this case, all contexts are lost, then
 restored after switching GPUs.
* Another page running in the user's browser performs an operation using the GPU that
 takes too long, causing the browser to decide to reset the GPU in order to break the
 stall. This would cause every WebGL context to be lost throughout the entire browser.
* The user updates their graphics driver on an operating system that allows graphics
 drivers to be updated without restarting the system.
Examples
--------

 For example, when checking for program linking success, you could also check if the
 context is not lost:

```js
gl.linkProgram(program);

if (!gl.getProgramParameter(program, gl.LINK\_STATUS) && !gl.isContextLost()) {
  const info = gl.getProgramInfoLog(program);
  console.log(`Error linking program:\n${info}`);
}
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.13 |

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

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

See also
--------

* The `WebGLContextEvent` signals changes in the context state.
* Handling lost context in WebGL: Khronos WebGL wiki


WebGLRenderingContext: getUniform() method - Web APIs

WebGLRenderingContext: getUniform() method
==========================================

 The **`WebGLRenderingContext.getUniform()`** method of the WebGL API returns the value of a uniform
 variable at a given location.

Syntax
------

```js
getUniform(program, location)
```

### Parameters

`program`

A `WebGLProgram` containing the uniform attribute.

`location`

 A `WebGLUniformLocation` object containing the location of the uniform
 attribute to get.

### Return value

The returned type depends on the uniform type:

| Uniform type | Returned type |
| --- | --- |
| WebGL 1 only |
| --- |
| `boolean` | `GLBoolean` |
| `int` | `GLint` |
| `float` | `GLfloat` |
| `vec2` | `Float32Array` (with 2 elements) |
| `ivec2` | `Int32Array` (with 2 elements) |
| `bvec2` | `Array` of
 `GLBoolean` (with 2
 elements)
  |
| `vec3` | `Float32Array` (with 3 elements) |
| `ivec3` | `Int32Array` (with 3 elements) |
| `bvec3` | `Array` of
 `GLBoolean` (with 3
 elements)
  |
| `vec4` | `Float32Array` (with 4 elements) |
| `ivec4` | `Int32Array` (with 4 elements) |
| `bvec4` | `Array` of
 `GLBoolean` (with 4
 elements)
  |
| `mat2` | `Float32Array` (with 4 elements) |
| `mat3` | `Float32Array` (with 9 elements) |
| `mat4` | `Float32Array` (with 16 elements) |
| `sampler2D` | `GLint` |
| `samplerCube` | `GLint` |
| Additionally available in WebGL 2 |
| `uint` | `GLuint` |
| `uvec2` | `Uint32Array` (with 2 elements) |
| `uvec3` | `Uint32Array` (with 3 elements) |
| `uvec4` | `Uint32Array` (with 4 elements) |
| `mat2x3` | `Float32Array` (with 6 elements) |
| `mat2x4` | `Float32Array` (with 8 elements) |
| `mat3x2` | `Float32Array` (with 6 elements) |
| `mat3x4` | `Float32Array` (with 12 elements) |
| `mat4x2` | `Float32Array` (with 8 elements) |
| `mat4x3` | `Float32Array` (with 12 elements) |
| any sampler type | `GLint` |

Examples
--------

```js
const loc = gl.getUniformLocation(program, "u\_foobar");
gl.getUniform(program, loc);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.10 |
| WebGL 2.0 Specification # 3.7.8 |

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

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

See also
--------

* `WebGLUniformLocation`
* `WebGLRenderingContext.getActiveUniform()`


WebGLRenderingContext: depthRange() method - Web APIs

WebGLRenderingContext: depthRange() method
==========================================

 The **`WebGLRenderingContext.depthRange()`** method of the WebGL API specifies the depth range mapping
 from normalized device coordinates to window or viewport coordinates.

Syntax
------

```js
depthRange(zNear, zFar)
```

### Parameters

`zNear`

 A `GLclampf` specifying the mapping of the near clipping plane to
 window or viewport coordinates. Clamped to the range 0 to 1 and must be less than or
 equal to `zFar`. The default value i`s 0.`

`zFar`

 A `GLclampf` specifying the mapping of the far clipping plane to window
 or viewport coordinates. Clamped to the range 0 to 1. The default value
 i`s 1.`

### Return value

None (`undefined`).

Examples
--------

```js
gl.depthRange(0.2, 0.6);
```

 To check the current depth range, query the `DEPTH_RANGE` constant which
 returns a `Float32Array`

```js
gl.getParameter(gl.DEPTH\_RANGE);
// Float32Array[0.2, 0.6]
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.3 |

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

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

See also
--------

* `WebGLRenderingContext.viewport()`
* `WebGLRenderingContext.depthFunc()`


WebGLRenderingContext: deleteFramebuffer() method - Web APIs

WebGLRenderingContext: deleteFramebuffer() method
=================================================

 The **`WebGLRenderingContext.deleteFramebuffer()`** method of
 the WebGL API deletes a given
 `WebGLFramebuffer` object. This method has no effect if the frame buffer
 has already been deleted.

Syntax
------

```js
deleteFramebuffer(framebuffer)
```

### Parameters

`framebuffer`

A `WebGLFramebuffer` object to delete.

### Return value

None (`undefined`).

Examples
--------

### Deleting a frame buffer

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

// …

gl.deleteFramebuffer(framebuffer);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.6 |

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

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

See also
--------

* `WebGLRenderingContext.bindFramebuffer()`
* `WebGLRenderingContext.createFramebuffer()`
* `WebGLRenderingContext.isFramebuffer()`
* Other buffers: `WebGLBuffer`, `WebGLRenderbuffer`


WebGLRenderingContext: stencilFunc() method - Web APIs

WebGLRenderingContext: stencilFunc() method
===========================================

 The **`WebGLRenderingContext.stencilFunc()`** method of the WebGL API sets the front and back function
 and reference value for stencil testing.

 Stenciling enables and disables drawing on a per-pixel basis. It is typically used in
 multipass rendering to achieve special effects.

Syntax
------

```js
stencilFunc(func, ref, mask)
```

### Parameters

`func`

 A `GLenum` specifying the test function. The default function is
 `gl.ALWAYS`. The possible values are:

* `gl.NEVER`: Never pass.
* `gl.LESS`: Pass if
 `(ref & mask) < (stencil & mask)`.
* `gl.EQUAL`: Pass if
 `(ref & mask) = (stencil & mask)`.
* `gl.LEQUAL`: Pass if
 `(ref & mask) <= (stencil & mask)`.
* `gl.GREATER`: Pass if
 `(ref & mask) > (stencil & mask)`.
* `gl.NOTEQUAL`: Pass if
 `(ref & mask) !== (stencil & mask)`.
* `gl.GEQUAL`: Pass if
 `(ref & mask) >= (stencil & mask)`.
* `gl.ALWAYS`: Always pass.

`ref`

 A `GLint` specifying the reference value for the stencil test. This
 value is clamped to the range 0 to 2^n - 1 where n is the number of bitplanes
 in the stencil buffer. The default value is 0.

`mask`

 A `GLuint` specifying a bit-wise mask that is used to AND the reference
 value and the stored stencil value when the test is done. The default value is all 1.

### Return value

None (`undefined`).

Examples
--------

 The stencil testing is disabled by default. To enable or disable stencil testing, use
 the `enable()` and
 `disable()` methods with the argument
 `gl.STENCIL_TEST`.

```js
gl.enable(gl.STENCIL\_TEST);
gl.stencilFunc(gl.LESS, 0, 0b1110011);
```

 To get the current stencil function, reference value, or other stencil information,
 query the following constants with `getParameter()`.

```js
gl.getParameter(gl.STENCIL\_FUNC);
gl.getParameter(gl.STENCIL\_VALUE\_MASK);
gl.getParameter(gl.STENCIL\_REF);
gl.getParameter(gl.STENCIL\_BACK\_FUNC);
gl.getParameter(gl.STENCIL\_BACK\_VALUE\_MASK);
gl.getParameter(gl.STENCIL\_BACK\_REF);
gl.getParameter(gl.STENCIL\_BITS);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.3 |

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

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

See also
--------

* `WebGLRenderingContext.stencilFuncSeparate()`
* `WebGLRenderingContext.stencilMask()`
* `WebGLRenderingContext.stencilMaskSeparate()`
* `WebGLRenderingContext.stencilOp()`
* `WebGLRenderingContext.stencilOpSeparate()`


WebGLRenderingContext: drawingBufferHeight property - Web APIs

WebGLRenderingContext: drawingBufferHeight property
===================================================

 The read-only **`WebGLRenderingContext.drawingBufferHeight`**
 property represents the actual height of the current drawing buffer. It should match the
 `height` attribute of the `<canvas>` element associated with
 this context, but might differ if the implementation is not able to provide the
 requested height.

Value
-----

A number.

Examples
--------

Given this `<canvas>` element:

```html
<canvas id="canvas"></canvas>
```

You can get the height of the drawing buffer with the following lines:

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

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

| Specification |
| --- |
| WebGL Specification # DOM-WebGLRenderingContext-drawingBufferHeight |

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

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

See also
--------

* `WebGLRenderingContext.drawingBufferWidth`
* `WebGLRenderingContext.viewport()`


WebGLRenderingContext: finish() method - Web APIs

WebGLRenderingContext: finish() method
======================================

 The **`WebGLRenderingContext.finish()`** method of the WebGL API blocks execution until all
 previously called commands are finished.

Syntax
------

```js
finish()
```

### Parameters

None.

### Return value

None (`undefined`).

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

| Specification |
| --- |
| WebGL Specification # 5.14.11 |

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

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

See also
--------

* `WebGLRenderingContext.flush()`
* WebGL best practices (which recommends avoiding `finish()` as it may slow down
 your main rendering loop)


WebGLRenderingContext: viewport() method - Web APIs

WebGLRenderingContext: viewport() method
========================================

 The **`WebGLRenderingContext.viewport()`** method of the WebGL API sets the viewport, which specifies
 the affine transformation of x and y from normalized device coordinates to window
 coordinates.

Syntax
------

```js
viewport(x, y, width, height)
```

### Parameters

`x`

 A `GLint` specifying the horizontal coordinate for the lower left
 corner of the viewport origin. Default value: 0.

`y`

 A `GLint` specifying the vertical coordinate for the lower left corner
 of the viewport origin. Default value: 0.

`width`

 A non-negative `GLsizei` specifying the width of the viewport. Default
 value: width of the canvas.

`height`

 A non-negative `GLsizei` specifying the height of the viewport. Default
 value: height of the canvas.

### Return value

None (`undefined`).

### Errors thrown

 If either *width* or *height* is a negative value, a
 `gl.INVALID_VALUE` error is thrown.

Examples
--------

 When you first create a WebGL context, the size of the viewport will match the size of
 the canvas. However, if you resize the canvas, you will need to tell the WebGL context a
 new viewport setting. In this situation, you can use `gl.viewport`.

```js
gl.viewport(0, 0, canvas.width, canvas.height);
```

 The viewport width and height are clamped to a range that is implementation dependent.
 To get this range, you can use the `MAX_VIEWPORT_DIMS` constant, which
 returns an `Int32Array`.

```js
gl.getParameter(gl.MAX\_VIEWPORT\_DIMS);
// e.g. Int32Array[16384, 16384]
```

To get the current viewport, query the `VIEWPORT` constant.

```js
gl.getParameter(gl.VIEWPORT);
// e.g. Int32Array[0, 0, 640, 480]
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.4 |

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

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

See also
--------

* `WebGLRenderingContext.scissor()`
* `WebGLRenderingContext.getParameter()`


WebGLRenderingContext: isEnabled() method - Web APIs

WebGLRenderingContext: isEnabled() method
=========================================

 The **`WebGLRenderingContext.isEnabled()`** method of the WebGL API tests whether a specific WebGL
 capability is enabled or not for this context.

 By default, all capabilities except `gl.DITHER` are
 **disabled**.

Syntax
------

```js
isEnabled(cap)
```

### Parameters

`cap`

A `GLenum` specifying which WebGL capability to test. Possible values:

| Constant | Description |
| --- | --- |
| `gl.BLEND` | Blending of the computed fragment color values. See `WebGLRenderingContext.blendFunc()`. |
| `gl.CULL_FACE` | Culling of polygons. See `WebGLRenderingContext.cullFace()`. |
| `gl.DEPTH_TEST` | Depth comparisons and updates to the depth buffer. See `WebGLRenderingContext.depthFunc()`. |
| `gl.DITHER` | Dithering of color components before they get written to the color buffer. |
| `gl.POLYGON_OFFSET_FILL` | Adding an offset to depth values of polygon's fragments. See `WebGLRenderingContext.polygonOffset()`. |
| `gl.SAMPLE_ALPHA_TO_COVERAGE` | Computation of a temporary coverage value determined by the alpha value. |
| `gl.SAMPLE_COVERAGE` | ANDing the fragment's coverage with the temporary coverage value. See `WebGLRenderingContext.sampleCoverage()`. |
| `gl.SCISSOR_TEST` | Scissor test that discards fragments that are outside of the scissor rectangle. See `WebGLRenderingContext.scissor()`. |
| `gl.STENCIL_TEST` | Stencil testing and updates to the stencil buffer. See `WebGLRenderingContext.stencilFunc()`. |

 When using a WebGL 2 context, the
 following values are available additionally:

| Constant | Description |
| --- | --- |
| `gl.RASTERIZER_DISCARD` | Primitives are discarded immediately before the rasterization stage, but after the optional transform feedback stage. `gl.clear()` commands are ignored. |

### Return value

 A `GLboolean` indicating if the capability *cap* is enabled
 (`true`), or not (`false`).

Examples
--------

```js
gl.isEnabled(gl.STENCIL\_TEST);
// false
```

 To activate or deactivate a specific capability, use the
 `WebGLRenderingContext.enable()` and
 `WebGLRenderingContext.disable()` methods:

```js
gl.enable(gl.STENCIL\_TEST);
gl.disable(gl.STENCIL\_TEST);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.3 |
| WebGL 2.0 Specification # 3.7.2 |

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

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

See also
--------

* `WebGLRenderingContext.enable()`
* `WebGLRenderingContext.disable()`


WebGLRenderingContext: blendFuncSeparate() method - Web APIs

WebGLRenderingContext: blendFuncSeparate() method
=================================================

 The **`WebGLRenderingContext.blendFuncSeparate()`** method of
 the WebGL API defines which function is used
 for blending pixel arithmetic for RGB and alpha components separately.

Syntax
------

```js
blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha)
```

### Parameters

`srcRGB`

 A `WebGL_API.Types` specifying a multiplier for the red, green and blue (RGB)
 source blending factors. The default value is `gl.ONE`. For possible
 values, see below.

`dstRGB`

 A `WebGL_API.Types` specifying a multiplier for the red, green and blue (RGB)
 destination blending factors. The default value is `gl.ZERO`. For possible
 values, see below.

`srcAlpha`

 A `WebGL_API.Types` specifying a multiplier for the alpha source blending
 factor. The default value is `gl.ONE`. For possible values, see below.

`dstAlpha`

 A `WebGL_API.Types` specifying a multiplier for the alpha destination blending
 factor. The default value is `gl.ZERO`. For possible values, see below.

### Return value

None (`undefined`).

### Exceptions

* If *srcRGB*, *dstRGB*, *srcAlpha*, or *dstAlpha* is not
 one of the listed possible values, a `gl.INVALID_ENUM` error is thrown.
* If a constant color and a constant alpha value are used together as source
 (`srcRGB`) and destination (`dstRGB`) factors, a
 `gl.INVALID_ENUM` error is thrown.
Constants
---------

 The following constants can be used for *srcRGB*, *dstRGB*,
 *srcAlpha*, and *dstAlpha*

 The formulas for the blending factors can be described like this (all RGBA values are
 between 0 and 1):

* color(RGB) = (sourceColor \* *srcRGB*) + (destinationColor \* *dstRGB*)
* color(A) = (sourceAlpha \* *srcAlpha*) + (destinationAlpha \*
 *dstAlpha*)

 In the following table, RS, GS, BS, AS represent respectively
 the *red*, *green*, *blue* and *alpha* component of the source, while
 RD, GD, BD, AD represent respectively
 the *red*, *green*, *blue* and *alpha* component of the destination.
 Similarly, RC, GC, BC, AC represent respectively
 the *red*, *green*, *blue* and *alpha* component of a constant color.
 They are all values between 0 and 1, included.

| Constant | RGB factor | Alpha factor | Description |
| --- | --- | --- | --- |
| `gl.ZERO` | 0,0,0 | 0 | Multiplies all colors by 0. |
| `gl.ONE` | 1,1,1,1 | 1 | Multiplies all colors by 1. |
| `gl.SRC_COLOR` | RS, GS, BS | AS | Multiplies all colors by the source colors. |
| `gl.ONE_MINUS_SRC_COLOR` | 1-RS, 1-GS, 1-BS | 1-AS | Multiplies all colors by 1 minus each source color. |
| `gl.DST_COLOR` | RD, GD, BD | AD | Multiplies all colors by the destination color. |
| `gl.ONE_MINUS_DST_COLOR` | 1-RD, 1-GD, 1-BD | 1-AD | Multiplies all colors by 1 minus each destination color. |
| `gl.SRC_ALPHA` | AS, AS, AS | AS | Multiplies all colors by the source alpha color. |
| `gl.ONE_MINUS_SRC_ALPHA` | 1-AS, 1-AS, 1-AS | 1-AS | Multiplies all colors by 1 minus the source alpha color. |
| `gl.DST_ALPHA` | AD, AD, AD | AD | Multiplies all colors by the destination alpha color. |
| `gl.ONE_MINUS_DST_ALPHA` | 1-AD, 1-AD, 1-AD | 1-AD | Multiplies all colors by 1 minus the destination alpha color. |
| `gl.CONSTANT_COLOR` | RC, GC, BC | AC | Multiplies all colors by a constant color. |
| `gl.ONE_MINUS_CONSTANT_COLOR` | 1-RC, 1-GC, 1-BC | 1-AC | Multiplies all colors by 1 minus a constant color. |
| `gl.CONSTANT_ALPHA` | AC, AC, AC | AC | Multiplies all colors by a constant alpha value. |
| `gl.ONE_MINUS_CONSTANT_ALPHA` | 1-AC, 1-AC, 1-AC | 1-AC | Multiplies all colors by 1 minus a constant alpha value. |
| `gl.SRC_ALPHA_SATURATE` |
 min(AS, 1 - AD), min(AS, 1 -
 AD), min(AS, 1 - AD)
  | 1 |
 Multiplies the RGB colors by the smaller of either the source alpha
 color or the value of 1 minus the destination alpha color. The alpha
 value is multiplied by 1.
  |

Examples
--------

 To use the blend function, you first have to activate blending with
 `WebGLRenderingContext.enable()` with the argument `gl.BLEND`.

```js
gl.enable(gl.BLEND);
gl.blendFuncSeparate(gl.SRC\_COLOR, gl.DST\_COLOR, gl.ONE, gl.ZERO);
```

 To get the current blend function, query the `BLEND_SRC_RGB`,
 `BLEND_SRC_ALPHA`, `BLEND_DST_RGB`, and
 `BLEND_DST_ALPHA` constants which return one of the blend function constants.

```js
gl.enable(gl.BLEND);
gl.blendFuncSeparate(gl.SRC\_COLOR, gl.DST\_COLOR, gl.ONE, gl.ZERO);
gl.getParameter(gl.BLEND\_SRC\_RGB) === gl.SRC\_COLOR;
// true
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.3 |

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

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

See also
--------

* `WebGLRenderingContext.blendColor()`
* `WebGLRenderingContext.blendEquation()`


WebGLRenderingContext: getUniformLocation() method - Web APIs

WebGLRenderingContext: getUniformLocation() method
==================================================

 Part of the WebGL API, the `WebGLRenderingContext` method
 **`getUniformLocation()`** returns the location of a
 specific **uniform** variable which is part of a given
 `WebGLProgram`.

 The uniform variable is returned as a
 `WebGLUniformLocation` object, which is an opaque identifier used to
 specify where in the GPU's memory that uniform variable is located.

 Once you have the uniform's location, you can access the uniform itself using one of
 the other uniform access methods, passing in the uniform location as one of the
 inputs:

* `getUniform()`
    + : Returns the value of the uniform at the given location.
* `WebGLRenderingContext.uniform[1234][fi][v]()`
    + : Sets the uniform's value to the specified value, which may be a single floating
     point or integer number, or a 2-4 component vector specified either as a list of
     values or as a `Float32Array` or `Int32Array`.
* `WebGLRenderingContext.uniformMatrix[234][fv]()`
    + : Sets the uniform's value to the specified matrix, possibly with transposition. The
     value is represented as a sequence of `GLfloat` values or as a
     `Float32Array`.

The uniform itself is declared in the shader program using GLSL.

Syntax
------

```js
getUniformLocation(program, name)
```

### Parameters

`program`

The `WebGLProgram` in which to locate the specified uniform variable.

`name`

 A string specifying the name of the uniform variable whose
 location is to be returned. The name can't have any whitespace in it, and you
 can't use this function to get the location of any uniforms starting with the
 reserved string `"gl_"`, since those are internal to the WebGL
 layer.

 The possible values correspond to the uniform names returned by
 `getActiveUniform`; see
 that function for specifics on how declared uniforms map to uniform location
 names.

 Additionally, for uniforms declared as arrays, the following names are also
 valid:

* The uniform name without the `[0]` suffix. E.g. the location
 returned for `arrayUniform` is equivalent to the one for
 `arrayUniform[0]`.
* The uniform name indexed with an integer. E.g. the location returned for
 `arrayUniform[2]` would point directly to the third entry of
 the `arrayUniform` uniform.

### Return value

 A `WebGLUniformLocation` value indicating the location of the named
 variable, if it exists. If the specified variable doesn't exist, `null` is
 returned instead.

 The `WebGLUniformLocation` is an opaque value used to uniquely identify the
 location in the GPU's memory at which the uniform variable is located. With this value
 in hand, you can call other WebGL methods to access the value of the uniform variable.

**Note:** The `WebGLUniformLocation` type is compatible with the
 `GLint` type when specifying the index or location of a uniform
 attribute.

### Errors

 The following errors may occur; to check for errors after
 `getUniformLocation()` returns, call
 `getError()`.

`GL_INVALID_VALUE`

The `program` parameter is not a value or object generated by WebGL.

`GL_INVALID_OPERATION`

 The `program` parameter doesn't correspond to a GLSL program generated
 by WebGL, or the specified program hasn't been linked successfully.

Examples
--------

 In this example, taken from the `animateScene()` method in the article A basic 2D WebGL animation example, obtains the locations of three uniforms from
 the shading program, then sets the value of each of the three uniforms.

```js
gl.useProgram(shaderProgram);

uScalingFactor = gl.getUniformLocation(shaderProgram, "uScalingFactor");
uGlobalColor = gl.getUniformLocation(shaderProgram, "uGlobalColor");
uRotationVector = gl.getUniformLocation(shaderProgram, "uRotationVector");

gl.uniform2fv(uScalingFactor, currentScale);
gl.uniform2fv(uRotationVector, currentRotation);
gl.uniform4fv(uGlobalColor, [0.1, 0.7, 0.2, 1.0]);
```

**Note:** This code snippet is taken from the function `animateScene()` in "A basic 2D WebGL animation example."
 See that article for the full sample and to see the resulting animation in action.

 After setting the current shading program to `shaderProgram`, this code
 fetches the three uniforms `"uScalingFactor"`, `"uGlobalColor"`,
 and `"uRotationVector"`, calling `getUniformLocation()` once for
 each uniform.

Then the three uniforms' values are set:

* The `uScalingFactor` uniform — a 2-component vertex — receives the
 horizontal and vertical scaling factors from the variable
 `currentScale`.
* The uniform `uRotationVector` is set to the contents of the variable
 `currentRotation`. This, too, is a 2-component vertex.
* Finally, the uniform `uGlobalColor` is set to the color
 `[0.1, 0.7, 0.2, 1.0]`, the components in this 4-component vector
 represent the values of red, green, blue, and alpha, respectively.

 Having done this, the next time the shading functions are called, their own variables
 named `uScalingFactor`, `uGlobalColor`, and
 `uRotationVector` will all have the values provided by the JavaScript code.

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

| Specification |
| --- |
| WebGL Specification # 5.14.10 |

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

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

See also
--------

* `WebGLRenderingContext.getAttribLocation()`
* `WebGLRenderingContext.getActiveUniform()`
* `WebGLUniformLocation`


WebGLRenderingContext: bindTexture() method - Web APIs

WebGLRenderingContext: bindTexture() method
===========================================

 The **`WebGLRenderingContext.bindTexture()`** method of the WebGL API binds a given
 `WebGLTexture` to a target (binding point).

Syntax
------

```js
bindTexture(target, texture)
```

### Parameters

`target`

A `GLenum` specifying the binding point (target). Possible values:

* `gl.TEXTURE_2D`: A two-dimensional texture.
* `gl.TEXTURE_CUBE_MAP`: A cube-mapped texture.
 When using a WebGL 2 context,
 the following values are available additionally:
    + `gl.TEXTURE_3D`: A three-dimensional texture.
    + `gl.TEXTURE_2D_ARRAY`: A two-dimensional array texture.

`texture`

A `WebGLTexture` object to bind.

### Return value

None (`undefined`).

### Exceptions

 A `gl.INVALID_ENUM` error is thrown if `target` is not
 `gl.TEXTURE_2D`, `gl.TEXTURE_CUBE_MAP`,
 `gl.TEXTURE_3D`, or `gl.TEXTURE_2D_ARRAY`.

Examples
--------

### Binding a texture

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

gl.bindTexture(gl.TEXTURE\_2D, texture);
```

### Getting current bindings

 To check the current texture binding, query the `gl.TEXTURE_BINDING_2D` or
 `gl.TEXTURE_BINDING_CUBE_MAP` constants.

```js
gl.getParameter(gl.TEXTURE\_BINDING\_2D);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.8 |
| WebGL 2.0 Specification # 3.7.1 |

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

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

See also
--------

* `WebGLRenderingContext.createTexture()`
* `WebGLRenderingContext.deleteTexture()`
* `WebGLRenderingContext.isTexture()`
* `WebGLRenderingContext.texImage2D()`


WebGLRenderingContext: isShader() method - Web APIs

WebGLRenderingContext: isShader() method
========================================

 The **`WebGLRenderingContext.isShader()`** method of the WebGL API returns `true` if the
 passed `WebGLShader` is valid, `false` otherwise.

Syntax
------

```js
isShader(shader)
```

### Parameters

`shader`

A `WebGLShader` to check.

### Return value

A `GLboolean` indicating whether or not the shader is valid.

Examples
--------

### Checking a shader

```js
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl");
const shader = gl.createShader(gl.VERTEX\_SHADER);

// …

gl.isShader(shader);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.9 |

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

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

See also
--------

* `WebGLRenderingContext.createShader()`
* `WebGLRenderingContext.deleteShader()`


WebGLRenderingContext: bindFramebuffer() method - Web APIs

WebGLRenderingContext: bindFramebuffer() method
===============================================

 The **`WebGLRenderingContext.bindFramebuffer()`** method of the
 WebGL API binds to the specified target the provided `WebGLFramebuffer`, or, if the `framebuffer` argument is null, the default `WebGLFramebuffer`, which is associated with the canvas rendering context.

Syntax
------

```js
bindFramebuffer(target, framebuffer)
```

### Parameters

`target`

A `GLenum` specifying the binding point (target). Possible values:

`gl.FRAMEBUFFER`

 Collection buffer data storage of color, alpha,
 depth and stencil buffers used as both a destination for drawing and as a source for reading (see below).

 When using a WebGL 2 context,
 the following values are available additionally:

`gl.DRAW_FRAMEBUFFER`

Used as a destination for drawing operations such as `gl.draw*`, `gl.clear*` and `gl.blitFramebuffer`.

`gl.READ_FRAMEBUFFER`

Used as a source for reading operations such as `gl.readPixels` and `gl.blitFramebuffer`.

`framebuffer`

A `WebGLFramebuffer` object to bind, or `null` for binding the `HTMLCanvasElement` or `OffscreenCanvas` object associated with the rendering context.

### Return value

None (`undefined`).

### Exceptions

 A `gl.INVALID_ENUM` error is thrown if `target` is not
 `gl.FRAMEBUFFER`, `gl.DRAW_FRAMEBUFFER`, or
 `gl.READ_FRAMEBUFFER`.

Examples
--------

### Binding a frame buffer

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

gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
```

### Getting current bindings

 To check the current frame buffer binding, query the `FRAMEBUFFER_BINDING`
 constant.

```js
gl.getParameter(gl.FRAMEBUFFER\_BINDING);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.6 |
| WebGL 2.0 Specification # 3.7.1 |

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

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

See also
--------

* `WebGLRenderingContext.createFramebuffer()`
* `WebGLRenderingContext.deleteFramebuffer()`
* `WebGLRenderingContext.isFramebuffer()`
* Other buffers: `WebGLBuffer`, `WebGLRenderbuffer`


WebGLRenderingContext: deleteTexture() method - Web APIs

WebGLRenderingContext: deleteTexture() method
=============================================

 The **`WebGLRenderingContext.deleteTexture()`** method of the
 WebGL API deletes a given
 `WebGLTexture` object. This method has no effect if the texture has already
 been deleted.

Syntax
------

```js
deleteTexture(texture)
```

### Parameters

`texture`

A `WebGLTexture` object to delete.

### Return value

None (`undefined`).

Examples
--------

### Deleting a texture

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

// …

gl.deleteTexture(texture);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.8 |

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

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

See also
--------

* `WebGLRenderingContext.bindTexture()`
* `WebGLRenderingContext.createTexture()`
* `WebGLRenderingContext.isTexture()`
* `WebGLRenderingContext.texImage2D()`


WebGLRenderingContext: getAttachedShaders() method - Web APIs

WebGLRenderingContext: getAttachedShaders() method
==================================================

 The **`WebGLRenderingContext.getAttachedShaders()`** method of
 the WebGL API returns a list of
 `WebGLShader` objects attached to a `WebGLProgram`.

Syntax
------

```js
getAttachedShaders(program)
```

### Parameters

`program`

A `WebGLProgram` object to get attached shaders for.

### Return value

 An `Array` of `WebGLShader` objects that are attached to the
 given `WebGLProgram`.

Examples
--------

```js
const program = gl.createProgram();

// Attach pre-existing shaders
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);

gl.getAttachedShaders(program);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.9 |

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

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

See also
--------

* `WebGLRenderingContext.createShader()`
* `WebGLRenderingContext.isShader()`
* `WebGLRenderingContext.deleteShader()`


WebGLRenderingContext: copyTexImage2D() method - Web APIs

WebGLRenderingContext: copyTexImage2D() method
==============================================

 The **`WebGLRenderingContext.copyTexImage2D()`** method of the
 WebGL API copies pixels from the current
 `WebGLFramebuffer` into a 2D texture image.

Syntax
------

```js
copyTexImage2D(target, level, internalformat, x, y, width, height, border)
```

### Parameters

`target`

 A `GLenum` specifying the binding point (target) of the active texture.
 Possible values:

* `gl.TEXTURE_2D`: A two-dimensional texture.
* `gl.TEXTURE_CUBE_MAP_POSITIVE_X`: Positive X face for a cube-mapped
 texture.
* `gl.TEXTURE_CUBE_MAP_NEGATIVE_X`: Negative X face for a cube-mapped
 texture.
* `gl.TEXTURE_CUBE_MAP_POSITIVE_Y`: Positive Y face for a cube-mapped
 texture.
* `gl.TEXTURE_CUBE_MAP_NEGATIVE_Y`: Negative Y face for a cube-mapped
 texture.
* `gl.TEXTURE_CUBE_MAP_POSITIVE_Z`: Positive Z face for a cube-mapped
 texture.
* `gl.TEXTURE_CUBE_MAP_NEGATIVE_Z`: Negative Z face for a cube-mapped
 texture.

`level`

 A `GLint` specifying the level of detail. Level 0 is the base image
 level and level *n* is the n-th mipmap reduction level.

`internalformat`

 A `GLenum` specifying the color components in the texture. Possible
 values:

* `gl.ALPHA`: Discards the red, green and blue components and reads the
 alpha component.
* `gl.RGB`: Discards the alpha components and reads the red, green and
 blue components.
* `gl.RGBA`: Red, green, blue and alpha components are read from the
 color buffer.
* `gl.LUMINANCE`: Each color component is a luminance component, alpha
 is 1.0.
* `gl.LUMINANCE_ALPHA`: Each component is a luminance/alpha component.

`x`

 A `GLint` specifying the x coordinate of the lower left corner where to
 start copying.

`y`

 A `GLint` specifying the y coordinate of the lower left corner where to
 start copying.

`width`

A `GLsizei` specifying the width of the texture.

`height`

A `GLsizei` specifying the height of the texture.

`border`

A `GLint` specifying the width of the border. Must be 0.

### Return value

None (`undefined`).

Examples
--------

```js
gl.copyTexImage2D(gl.TEXTURE\_2D, 0, gl.RGBA, 0, 0, 512, 512, 0);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.8 |

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

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

See also
--------

* `WebGLRenderingContext.createTexture()`
* `WebGLRenderingContext.bindTexture()`
* `WebGLRenderingContext.texImage2D()`
* `WebGLRenderingContext.texSubImage2D()`
* `WebGLRenderingContext.compressedTexImage2D()`


WebGLRenderingContext: bufferData() method - Web APIs

WebGLRenderingContext: bufferData() method
==========================================

 The **`WebGLRenderingContext.bufferData()`** method of the WebGL API initializes and creates the
 buffer object's data store.

Syntax
------

```js
// WebGL1
bufferData(target, usage)
bufferData(target, size, usage)
bufferData(target, srcData, usage)

// WebGL2
bufferData(target, usage, srcOffset)
bufferData(target, srcData, usage, srcOffset)
bufferData(target, srcData, usage, srcOffset, length)
```

### Parameters

`target`

A `GLenum` specifying the binding point (target). Possible values:

`gl.ARRAY_BUFFER`

 Buffer containing vertex attributes, such as
 vertex coordinates, texture coordinate data, or vertex color data.

`gl.ELEMENT_ARRAY_BUFFER`

Buffer used for element indices.

When using a WebGL 2 context, the following values are available additionally:

`gl.COPY_READ_BUFFER`

Buffer for copying from one buffer object to another.

`gl.COPY_WRITE_BUFFER`

Buffer for copying from one buffer object to another.

`gl.TRANSFORM_FEEDBACK_BUFFER`

Buffer for transform feedback operations.

`gl.UNIFORM_BUFFER`

Buffer used for storing uniform blocks.

`gl.PIXEL_PACK_BUFFER`

Buffer used for pixel transfer operations.

`gl.PIXEL_UNPACK_BUFFER`

Buffer used for pixel transfer operations.

`size`

 A `GLsizeiptr` setting the size in bytes of the buffer object's data
 store.

`srcData` Optional

 An `ArrayBuffer`, `SharedArrayBuffer`, a `TypedArray` or a `DataView`
 that will be copied into the data store.
 If `null`, a data store is still created, but the content is uninitialized and undefined.

`usage`

 A `GLenum` specifying the intended usage pattern of the data store
 for optimization purposes. Possible values:

`gl.STATIC_DRAW`

 The contents are intended to be specified
 once by the application, and used many times as the source for WebGL
 drawing and image specification commands.

`gl.DYNAMIC_DRAW`

 The contents are intended to be respecified
 repeatedly by the application, and used many times as the source for WebGL
 drawing and image specification commands.

`gl.STREAM_DRAW`

 The contents are intended to be specified
 once by the application, and used at most a few times as the source for
 WebGL drawing and image specification commands.

When using a WebGL 2 context, the following values are available additionally:

`gl.STATIC_READ`

 The contents are intended to be
 specified once by reading data from WebGL, and queried many times
 by the application.

`gl.DYNAMIC_READ`

 The contents are intended to be
 respecified repeatedly by reading data from WebGL, and queried
 many times by the application.

`gl.STREAM_READ`

 The contents are intended to be
 specified once by reading data from WebGL, and queried at most a
 few times by the application

`gl.STATIC_COPY`

 The contents are intended to be
 specified once by reading data from WebGL, and used many times as
 the source for WebGL drawing and image specification commands.

`gl.DYNAMIC_COPY`

 The contents are intended to be
 respecified repeatedly by reading data from WebGL, and used many
 times as the source for WebGL drawing and image specification
 commands.

`gl.STREAM_COPY`

 The contents are intended to be
 specified once by reading data from WebGL, and used at most a few
 times as the source for WebGL drawing and image specification
 commands.

`srcOffset`

 A `GLuint` specifying the element index offset where to start reading
 the buffer.

`length` Optional

A `GLuint` defaulting to 0.

### Return value

None (`undefined`).

### Exceptions

* A `gl.OUT_OF_MEMORY` error is thrown if the context is unable to create
 a data store with the given `size`.
* A `gl.INVALID_VALUE` error is thrown if `size` is negative.
* A `gl.INVALID_ENUM` error is thrown if `target` or
 `usage` are not one of the allowed enums.
Examples
--------

### Using bufferData

```js
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl");
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY\_BUFFER, buffer);
gl.bufferData(gl.ARRAY\_BUFFER, 1024, gl.STATIC\_DRAW);
```

### Getting buffer information

 To check the current buffer usage and buffer size, use the
 `WebGLRenderingContext.getBufferParameter()` method.

```js
gl.getBufferParameter(gl.ARRAY\_BUFFER, gl.BUFFER\_SIZE);
gl.getBufferParameter(gl.ARRAY\_BUFFER, gl.BUFFER\_USAGE);
```

### Getting size of a typed array

To calculate size parameter for a typed array.

```js
const dataArray = new Float32Array([1, 2, 3, 4]);
const sizeInBytes = dataArray.length \* dataArray.BYTES\_PER\_ELEMENT;
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.5 |

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

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

See also
--------

* `WebGLRenderingContext.createBuffer()`
* `WebGLRenderingContext.bufferSubData()`
* Other buffers: `WebGLFramebuffer`, `WebGLRenderbuffer`


WebGLRenderingContext: getSupportedExtensions() method - Web APIs

WebGLRenderingContext: getSupportedExtensions() method
======================================================

 The **`WebGLRenderingContext.getSupportedExtensions()`** method
 returns a list of all the supported WebGL
 extensions.

Syntax
------

```js
getSupportedExtensions()
```

### Parameters

None.

### Return value

An `Array` of strings with all the supported WebGL extensions.

Examples
--------

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

const extensions = gl.getSupportedExtensions();
// Array [ 'ANGLE\_instanced\_arrays', 'EXT\_blend\_minmax', … ]
```

 See also the `WebGLRenderingContext.getExtension()` method to get a
 specific extension object.

WebGL extensions
----------------

Extensions for the WebGL API are registered in the WebGL Extension Registry. They are also listed here.

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

| Specification |
| --- |
| WebGL Specification # 5.14.14 |

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

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

See also
--------

* `WebGLRenderingContext.getExtension()`
* webglreport.com


WebGLRenderingContext: enableVertexAttribArray() method - Web APIs

WebGLRenderingContext: enableVertexAttribArray() method
=======================================================

 The `WebGLRenderingContext` method
 **`enableVertexAttribArray()`**, part of the WebGL API, turns on the generic vertex
 attribute array at the specified index into the list of attribute arrays.

**Note:** You can disable the attribute array by calling
 `disableVertexAttribArray()`.

 In WebGL, values that apply to a specific vertex are stored in attributes. These are only
 available to the JavaScript code and the vertex shader. Attributes are referenced by an
 index number into the list of attributes maintained by the GPU. Some vertex attribute
 indices may have predefined purposes, depending on the platform and/or the GPU. Others
 are assigned by the WebGL layer when you create the attributes.

 Either way, since attributes cannot be used unless enabled, and are disabled by
 default, you need to call `enableVertexAttribArray()` to enable individual
 attributes so that they can be used. Once that's been done, other methods can be used to
 access the attribute, including `vertexAttribPointer()`, `vertexAttrib*()`, and `getVertexAttrib()`.

Syntax
------

```js
enableVertexAttribArray(index)
```

### Parameters

`index`

 A `GLuint` specifying the index number that uniquely identifies the
 vertex attribute to enable. If you know the name of the attribute but not its index,
 you can get the index by calling `getAttribLocation()`.

### Return value

None (`undefined`).

### Errors

 To check for errors after calling `enableVertexAttribArray()`, call
 `getError()`.

`WebGLRenderingContext.INVALID_VALUE`

 The specified `index` is invalid; that is, it's greater than or equal to
 the maximum number of entries permitted in the context's vertex attribute list, as
 indicated by the value of `WebGLRenderingContext.MAX_VERTEX_ATTRIBS`.

Examples
--------

 This code — a snippet taken from the full example A basic 2D WebGL animation example — shows the use of `enableVertexArray()` to activate
 the attribute that will be used by the WebGL layer to pass individual vertexes from the
 vertex buffer into the vertex shader function.

```js
gl.bindBuffer(gl.ARRAY\_BUFFER, vertexBuffer);

aVertexPosition = gl.getAttribLocation(shaderProgram, "aVertexPosition");

gl.enableVertexAttribArray(aVertexPosition);
gl.vertexAttribPointer(
  aVertexPosition,
  vertexNumComponents,
  gl.FLOAT,
  false,
  0,
  0,
);

gl.drawArrays(gl.TRIANGLES, 0, vertexCount);
```

**Note:** This code snippet is taken from the function `animateScene()` in "A basic 2D WebGL animation example." See
 that article for the full sample and to see the resulting animation in action.

 This code sets the buffer of vertexes that will be used to draw the triangles of the
 shape by calling `bindBuffer()`. Then
 the vertex position attribute's index is obtained from the shader program by calling
 `getAttribLocation()`.

 With the index of the vertex position attribute now available in
 `aVertexPosition`, we call `enableVertexAttribArray()` to enable
 the position attribute so it can be used by the shader program (in particular, by the
 vertex shader).

 Then the vertex buffer is bound to the `aVertexPosition` attribute by
 calling `vertexAttribPointer()`. This step is not obvious, since this binding is almost a
 side effect. But as a result, accessing `aVertexPosition` now obtains data
 from the vertex buffer.

 With the association in place between the vertex buffer for our shape and the
 `aVertexPosition` attribute used to deliver vertexes one by one into the
 vertex shader, we're ready to draw the shape by calling
 `drawArrays()`.

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

| Specification |
| --- |
| WebGL Specification # 5.14.10 |

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

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

See also
--------

* Data in WebGL
* Adding 2D content to a WebGL context
* A basic 2D WebGL animation sample
* `disableVertexAttribArray()`


WebGLRenderingContext: createBuffer() method - Web APIs

WebGLRenderingContext: createBuffer() method
============================================

 The **`WebGLRenderingContext.createBuffer()`** method of the WebGL API creates and initializes a
 `WebGLBuffer` storing data such as vertices or colors.

Syntax
------

```js
createBuffer()
```

### Parameters

None.

### Return value

A `WebGLBuffer` storing data such as vertices or colors.

Examples
--------

### Creating a buffer

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

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

| Specification |
| --- |
| WebGL Specification # 5.14.5 |

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

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

See also
--------

* `WebGLRenderingContext.bindBuffer()`
* `WebGLRenderingContext.deleteBuffer()`
* `WebGLRenderingContext.isBuffer()`
* Other buffers: `WebGLFramebuffer`, `WebGLRenderbuffer`


WebGLRenderingContext: getAttribLocation() method - Web APIs

WebGLRenderingContext: getAttribLocation() method
=================================================

 The **`WebGLRenderingContext.getAttribLocation()`** method of
 the WebGL API returns the location of an
 attribute variable in a given `WebGLProgram`.

Syntax
------

```js
getAttribLocation(program, name)
```

### Parameters

`program`

A `WebGLProgram` containing the attribute variable.

`name`

 A string specifying the name of the attribute variable whose
 location to get.

### Return value

 A `GLint` number indicating the location of the variable name if found.
 Returns -1 otherwise.

Examples
--------

```js
gl.getAttribLocation(program, "vColor");
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.10 |

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

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

See also
--------

* `WebGLRenderingContext.getUniformLocation()`


WebGLRenderingContext: deleteRenderbuffer() method - Web APIs

WebGLRenderingContext: deleteRenderbuffer() method
==================================================

 The **`WebGLRenderingContext.deleteRenderbuffer()`** method of
 the WebGL API deletes a given
 `WebGLRenderbuffer` object. This method has no effect if the render buffer
 has already been deleted.

Syntax
------

```js
deleteRenderbuffer(renderbuffer)
```

### Parameters

`renderbuffer`

A `WebGLRenderbuffer` object to delete.

### Return value

None (`undefined`).

Examples
--------

### Deleting a renderbuffer

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

// …

gl.deleteRenderbuffer(renderbuffer);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.7 |

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

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

See also
--------

* `WebGLRenderingContext.bindRenderbuffer()`
* `WebGLRenderingContext.createRenderbuffer()`
* `WebGLRenderingContext.isRenderbuffer()`
* Other buffers: `WebGLBuffer`, `WebGLFramebuffer`


WebGLRenderingContext: disable() method - Web APIs

WebGLRenderingContext: disable() method
=======================================

 The **`WebGLRenderingContext.disable()`** method of the WebGL API disables specific WebGL
 capabilities for this context.

Syntax
------

```js
disable(capability)
```

### Parameters

`capability`

 A `GLenum` specifying which WebGL capability to disable. Possible
 values:

| Constant | Description |
| --- | --- |
| `gl.BLEND` | Deactivates blending of the computed fragment color values. See `WebGLRenderingContext.blendFunc()`. |
| `gl.CULL_FACE` | Deactivates culling of polygons. See `WebGLRenderingContext.cullFace()`. |
| `gl.DEPTH_TEST` | Deactivates depth comparisons and updates to the depth buffer. See `WebGLRenderingContext.depthFunc()`. |
| `gl.DITHER` | Deactivates dithering of color components before they get written to the color buffer. |
| `gl.POLYGON_OFFSET_FILL` | Deactivates adding an offset to depth values of polygon's fragments. See `WebGLRenderingContext.polygonOffset()`. |
| `gl.SAMPLE_ALPHA_TO_COVERAGE` | Deactivates the computation of a temporary coverage value determined by the alpha value. |
| `gl.SAMPLE_COVERAGE` | Deactivates ANDing the fragment's coverage with the temporary coverage value. See `WebGLRenderingContext.sampleCoverage()`. |
| `gl.SCISSOR_TEST` | Deactivates the scissor test that discards fragments that are outside of the scissor rectangle. See `WebGLRenderingContext.scissor()`. |
| `gl.STENCIL_TEST` | Deactivates stencil testing and updates to the stencil buffer. See `WebGLRenderingContext.stencilFunc()`. |

 When using a WebGL 2 context, the
 following values are available additionally:

| Constant | Description |
| --- | --- |
| `gl.RASTERIZER_DISCARD` | Deactivates that primitives are discarded immediately before the rasterization stage, but after the optional transform feedback stage. `gl.clear()` commands are ignored. |

### Return value

None (`undefined`).

Examples
--------

```js
gl.disable(gl.DITHER);
```

 To check if a capability is disabled, use the
 `WebGLRenderingContext.isEnabled()` method:

```js
gl.isEnabled(gl.DITHER);
// false
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.3 |

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

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

See also
--------

* `WebGLRenderingContext.enable()`
* `WebGLRenderingContext.isEnabled()`


WebGLRenderingContext: depthFunc() method - Web APIs

WebGLRenderingContext: depthFunc() method
=========================================

 The **`WebGLRenderingContext.depthFunc()`** method of the WebGL API specifies a function that compares
 incoming pixel depth to the current depth buffer value.

Syntax
------

```js
depthFunc(func)
```

### Parameters

`func`

 A `GLenum` specifying the depth comparison function, which sets the
 conditions under which the pixel will be drawn. The default value is
 `gl.LESS`. Possible values are:

* `gl.NEVER` (never pass)
* `gl.LESS` (pass if the incoming value is less than the depth buffer
 value)
* `gl.EQUAL` (pass if the incoming value equals the depth buffer value)
* `gl.LEQUAL` (pass if the incoming value is less than or equal to the
 depth buffer value)
* `gl.GREATER` (pass if the incoming value is greater than the depth
 buffer value)
* `gl.NOTEQUAL` (pass if the incoming value is not equal to the depth
 buffer value)
* `gl.GEQUAL` (pass if the incoming value is greater than or equal to
 the depth buffer value)
* `gl.ALWAYS` (always pass)

### Return value

None (`undefined`).

Examples
--------

 The depth testing is disabled by default. To enable or disable depth testing, use the
 `enable()` and
 `disable()` methods with the argument
 `gl.DEPTH_TEST`.

```js
gl.enable(gl.DEPTH\_TEST);
gl.depthFunc(gl.NEVER);
```

To check the current depth function, query the `DEPTH_FUNC` constant.

```js
gl.getParameter(gl.DEPTH\_FUNC) === gl.NEVER;
// true
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.3 |

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

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

See also
--------

* `WebGLRenderingContext.enable()`


WebGLRenderingContext: createTexture() method - Web APIs

WebGLRenderingContext: createTexture() method
=============================================

 The **`WebGLRenderingContext.createTexture()`** method of the
 WebGL API creates and initializes a
 `WebGLTexture` object.

Syntax
------

```js
createTexture()
```

### Parameters

None.

### Return value

A `WebGLTexture` object to which images can be bound to.

Examples
--------

See also the WebGL tutorial on Using textures in WebGL.

### Creating a texture

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

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

| Specification |
| --- |
| WebGL Specification # 5.14.8 |

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

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

See also
--------

* `WebGLRenderingContext.bindTexture()`
* `WebGLRenderingContext.deleteTexture()`
* `WebGLRenderingContext.isTexture()`
* `WebGLRenderingContext.texImage2D()`


WebGLRenderingContext: getShaderPrecisionFormat() method - Web APIs

WebGLRenderingContext: getShaderPrecisionFormat() method
========================================================

 The
 **`WebGLRenderingContext.getShaderPrecisionFormat()`** method of
 the WebGL API returns a new
 `WebGLShaderPrecisionFormat` object describing the range and precision for
 the specified shader numeric format.

Syntax
------

```js
getShaderPrecisionFormat(shaderType, precisionType)
```

### Parameters

`shaderType`

Either a `gl.FRAGMENT_SHADER` or a `gl.VERTEX_SHADER`.

`precisionType`

 A precision type value. Either `gl.LOW_FLOAT`,
 `gl.MEDIUM_FLOAT`, `gl.HIGH_FLOAT`, `gl.LOW_INT`,
 `gl.MEDIUM_INT`, or `gl.HIGH_INT`.

### Return value

 A `WebGLShaderPrecisionFormat` object or `null`, if an error
 occurs.

### Exceptions

* `gl.INVALID_ENUM` if the shader or precision types aren't recognized.
* `gl.INVALID_OPERATION` if the shader compiler isn't supported.
Examples
--------

 The following code gets the precision format of a `gl.VERTEX_SHADER` with a
 `gl.MEDIUM_FLOAT` precision type.

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

gl.getShaderPrecisionFormat(gl.VERTEX\_SHADER, gl.MEDIUM\_FLOAT);
// WebGLShaderPrecisionFormat { rangeMin: 127, rangeMax: 127, precision: 23 }
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.9 |

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

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

See also
--------

* `WebGLShaderPrecisionFormat`


WebGLRenderingContext: stencilFuncSeparate() method - Web APIs

WebGLRenderingContext: stencilFuncSeparate() method
===================================================

 The **`WebGLRenderingContext.stencilFuncSeparate()`** method of
 the WebGL API sets the front and/or back
 function and reference value for stencil testing.

 Stencilling enables and disables drawing on a per-pixel basis. It is typically used in
 multipass rendering to achieve special effects.

Syntax
------

```js
stencilFuncSeparate(face, func, ref, mask)
```

### Parameters

`face`

 A `GLenum` specifying whether the front and/or back stencil state is
 updated. The possible values are:

* `gl.FRONT`
* `gl.BACK`
* `gl.FRONT_AND_BACK`

`func`

 A `GLenum` specifying the test function. The default function is
 `gl.ALWAYS`. The possible values are:

* `gl.NEVER`: Never pass.
* `gl.LESS`: Pass if `(ref & mask) < (stencil & mask)`.
* `gl.EQUAL`: Pass if `(ref & mask) = (stencil & mask)`.
* `gl.LEQUAL`: Pass if `(ref & mask) <= (stencil & mask)`.
* `gl.GREATER`: Pass if `(ref & mask) > (stencil & mask)`.
* `gl.NOTEQUAL`: Pass if `(ref & mask) !== (stencil & mask)`.
* `gl.GEQUAL`: Pass if `(ref & mask) >= (stencil & mask)`.
* `gl.ALWAYS`: Always pass.

`ref`

 A `GLint` specifying the reference value for the stencil test. This
 value is clamped to the range 0 to 2^n - 1 where n is the number of bitplanes
 in the stencil buffer. The default value is 0.

`mask`

 A `GLuint` specifying a bit-wise mask that is used to AND the reference
 value and the stored stencil value when the test is done. The default value is all 1.

### Return value

None (`undefined`).

Examples
--------

 The stencil testing is disabled by default. To enable or disable stencil testing, use
 the `enable()` and
 `disable()` methods with the argument
 `gl.STENCIL_TEST`.

```js
gl.enable(gl.STENCIL\_TEST);
gl.stencilFuncSeparate(gl.FRONT, gl.LESS, 0.2, 1110011);
```

 To get the current stencil function, reference value, or other stencil information,
 query the following constants with `getParameter()`.

```js
gl.getParameter(gl.STENCIL\_FUNC);
gl.getParameter(gl.STENCIL\_VALUE\_MASK);
gl.getParameter(gl.STENCIL\_REF);
gl.getParameter(gl.STENCIL\_BACK\_FUNC);
gl.getParameter(gl.STENCIL\_BACK\_VALUE\_MASK);
gl.getParameter(gl.STENCIL\_BACK\_REF);
gl.getParameter(gl.STENCIL\_BITS);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.3 |

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

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

See also
--------

* `WebGLRenderingContext.stencilFunc()`
* `WebGLRenderingContext.stencilMask()`
* `WebGLRenderingContext.stencilMaskSeparate()`
* `WebGLRenderingContext.stencilOp()`
* `WebGLRenderingContext.stencilOpSeparate()`


WebGLRenderingContext: clear() method - Web APIs

WebGLRenderingContext: clear() method
=====================================

The **`WebGLRenderingContext.clear()`** method of the WebGL API clears buffers to preset values.

 The preset values can be set by `clearColor()`, `clearDepth()` or
 `clearStencil()`.

 The scissor box, dithering, and buffer writemasks can affect the `clear()`
 method.

Syntax
------

```js
clear(mask)
```

### Parameters

`mask`

 A `GLbitfield` bitwise OR mask that indicates the buffers to be
 cleared. Possible values are:

* `gl.COLOR_BUFFER_BIT`
* `gl.DEPTH_BUFFER_BIT`
* `gl.STENCIL_BUFFER_BIT`

### Return value

None (`undefined`).

### Exceptions

 If *mask* is not one of the listed possible values, a
 `gl.INVALID_ENUM` error is thrown.

Examples
--------

The `clear()` method accepts multiple values.

```js
gl.clear(gl.DEPTH\_BUFFER\_BIT);
gl.clear(gl.DEPTH\_BUFFER\_BIT | gl.COLOR\_BUFFER\_BIT);
```

 To get the current clear values, query the `COLOR_CLEAR_VALUE`,
 `DEPTH_CLEAR_VALUE`, and `STENCIL_CLEAR_VALUE` constants.

```js
gl.getParameter(gl.COLOR\_CLEAR\_VALUE);
gl.getParameter(gl.DEPTH\_CLEAR\_VALUE);
gl.getParameter(gl.STENCIL\_CLEAR\_VALUE);
```

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

| Specification |
| --- |
| WebGL Specification # 5.14.11 |

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

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

See also
--------

* `WebGLRenderingContext.clearColor()`
* `WebGLRenderingContext.clearDepth()`
* `WebGLRenderingContext.clearStencil()`


Canvas tutorial - Web APIs

Canvas tutorial
===============

This tutorial describes how to use the **`<canvas>`** element to draw 2D graphics, starting with the basics. The examples provided should give you some clear ideas about what you can do with canvas, and will provide code snippets that may get you started in building your own content.

`<canvas>` is an HTML element which can be used to draw graphics via scripting (usually JavaScript). This can, for instance, be used to draw graphs, combine photos, or create simple animations.

First introduced in WebKit by Apple for the macOS Dashboard, `<canvas>` has since been implemented in browsers. Today, all major browsers support it.

Before you start
----------------

Using the `<canvas>` element is not very difficult, but you do need a basic understanding of HTML and JavaScript. The `<canvas>` element is not supported in some older browsers, but is supported in recent versions of all major browsers. The default size of the canvas is 300 pixels × 150 pixels (width × height). But custom sizes can be defined using the HTML `height` and `width` property. In order to draw graphics on the canvas we use a JavaScript context object, which creates graphics on the fly.

In this tutorial
----------------

1. Basic usage
2. Drawing shapes
3. Applying styles and colors
4. Drawing text
5. Using images
6. Transformations
7. Compositing and clipping
8. Basic animations
9. Advanced animations
10. Pixel manipulation
11. Optimizing the canvas
12. Finale
See also
--------

* Canvas topic page
* HTML5CanvasTutorials
A note to contributors
----------------------

Due to an unfortunate technical error that occurred the week of June 17, 2013, we lost the history of this tutorial, including attributions to all past contributors to its content. We apologize for this, and hope you'll forgive this unfortunate mishap.

* Next »


Manipulating video using canvas - Web APIs

Manipulating video using canvas
===============================

By combining the capabilities of the `video` element with a `canvas`, you can manipulate video data in real time to incorporate a variety of visual effects to the video being displayed. This tutorial demonstrates how to perform chroma-keying (also known as the "green screen effect") using JavaScript code.

The document content
--------------------

The HTML document used to render this content is shown below.

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <title>Video test page</title>
    <style>
 body {
 background: black;
 color: #cccccc;
 }
 #c2 {
 background-image: url(media/foo.png);
 background-repeat: no-repeat;
 }
 div {
 float: left;
 border: 1px solid #444444;
 padding: 10px;
 margin: 10px;
 background: #3b3b3b;
 }
 </style>
  </head>

  <body>
    <div>
      <video
 id="video"
 src="media/video.mp4"
 controls
 crossorigin="anonymous" />
    </div>
    <div>
      <canvas id="c1" width="160" height="96"></canvas>
      <canvas id="c2" width="160" height="96"></canvas>
    </div>
    <script src="processor.js"></script>
  </body>
</html>
```

The key bits to take away from this are:

1. This document establishes two `canvas` elements, with the IDs `c1` and `c2`. Canvas `c1` is used to display the current frame of the original video, while `c2` is used to display the video after performing the chroma-keying effect; `c2` is preloaded with the still image that will be used to replace the green background in the video.
2. The JavaScript code is imported from a script named `processor.js`.
The JavaScript code
-------------------

The JavaScript code in `processor.js` consists of three methods.

### Initializing the chroma-key player

The `doLoad()` method is called when the HTML document initially loads. This method's job is to prepare the variables needed by the chroma-key processing code, and to set up an event listener so we can detect when the user starts playing the video.

```js
const processor = {};

processor.doLoad = function doLoad() {
  const video = document.getElementById("video");
  this.video = video;

  this.c1 = document.getElementById("c1");
  this.ctx1 = this.c1.getContext("2d");

  this.c2 = document.getElementById("c2");
  this.ctx2 = this.c2.getContext("2d");

  video.addEventListener(
    "play",
    () => {
      this.width = video.videoWidth / 2;
      this.height = video.videoHeight / 2;
      this.timerCallback();
    },
    false,
  );
};
```

This code grabs references to the elements in the HTML document that are of particular interest, namely the `video` element and the two `canvas` elements. It also fetches references to the graphics contexts for each of the two canvases. These will be used when we're actually doing the chroma-keying effect.

Then `addEventListener()` is called to begin watching the `video` element so that we obtain notification when the user presses the play button on the video. In response to the user beginning playback, this code fetches the width and height of the video, halving each (we will be halving the size of the video when we perform the chroma-keying effect), then calls the `timerCallback()` method to start watching the video and computing the visual effect.

### The timer callback

The timer callback is called initially when the video starts playing (when the "play" event occurs), then takes responsibility for establishing itself to be called periodically in order to launch the keying effect for each frame.

```js
processor.timerCallback = function timerCallback() {
  if (this.video.paused || this.video.ended) {
    return;
  }
  this.computeFrame();
  setTimeout(() => {
    this.timerCallback();
  }, 0);
};
```

The first thing the callback does is check to see if the video is even playing; if it's not, the callback returns immediately without doing anything.

Then it calls the `computeFrame()` method, which performs the chroma-keying effect on the current video frame.

The last thing the callback does is call `setTimeout()` to schedule itself to be called again as soon as possible. In the real world, you would probably schedule this to be done based on knowledge of the video's frame rate.

### Manipulating the video frame data

The `computeFrame()` method, shown below, is responsible for actually fetching a frame of data and performing the chroma-keying effect.

```js
processor.computeFrame = function () {
  this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
  const frame = this.ctx1.getImageData(0, 0, this.width, this.height);
  const data = frame.data;

  for (let i = 0; i < data.length; i += 4) {
    const red = data[i + 0];
    const green = data[i + 1];
    const blue = data[i + 2];
    if (green > 100 && red > 100 && blue < 43) {
      data[i + 3] = 0;
    }
  }
  this.ctx2.putImageData(frame, 0, 0);
};
```

When this routine is called, the video element is displaying the most recent frame of video data, which looks like this:

![A single frame of the video element. There is a person wearing a black t-shirt. The background-color is yellow.](/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas/video.png)

In line 2, that frame of video is copied into the graphics context `ctx1` of the first canvas, specifying as the height and width the values we previously saved to draw the frame at half size. Note that you can pass the video element into the context's `drawImage()` method to draw the current video frame into the context. The result is:

![A single frame of the video element. There is a person wearing a black t-shirt. The background-color is yellow. This is a smaller version of the picture above.](/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas/sourcectx.png)

Line 3 fetches a copy of the raw graphics data for the current frame of video by calling the `getImageData()` method on the first context. This provides raw 32-bit pixel image data we can then manipulate. Line 4 computes the number of pixels in the image by dividing the total size of the frame's image data by four.

The `for` loop that begins on line 6 scans through the frame's pixels, pulling out the red, green, and blue values for each pixel, and compares the values against predetermined numbers that are used to detect the green screen that will be replaced with the still background image imported from `foo.png`.

Every pixel in the frame's image data that is found that is within the parameters that are considered to be part of the green screen has its alpha value replaced with a zero, indicating that the pixel is entirely transparent. As a result, the final image has the entire green screen area 100% transparent, so that when it's drawn into the destination context in line 13, the result is an overlay onto the static backdrop.

The resulting image looks like this:

![A single frame of the video element shows the same person wearing a black t-shirt as in the photos above. The background is different: it is the Firefox logo.](/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas/output.png)

This is done repeatedly as the video plays, so that frame after frame is processed and displayed with the chroma-key effect.

View the full source for this example.

See also
--------

* Web media technologies
* Guide to media types and formats on the web
* Learning area: Video and audio content


Advanced animations - Web APIs

Advanced animations
===================

* « Previous
* Next »

In the last chapter we made some basic animations and got to know ways to get things moving. In this part we will have a closer look at the motion itself and are going to add some physics to make our animations more advanced.

Drawing a ball
--------------

We are going to use a ball for our animation studies, so let's first draw that ball onto the canvas. The following code will set us up.

```html
<canvas id="canvas" width="600" height="300"></canvas>
```

As usual, we need a drawing context first. To draw the ball, we will create a `ball` object which contains properties and a `draw()` method to paint it on the canvas.

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

const ball = {
  x: 100,
  y: 100,
  radius: 25,
  color: "blue",
  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI \* 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  },
};

ball.draw();
```

Nothing special here, the ball is actually a simple circle and gets drawn with the help of the `arc()` method.

Adding velocity
---------------

Now that we have a ball, we are ready to add a basic animation like we have learned in the last chapter of this tutorial. Again, `window.requestAnimationFrame()` helps us to control the animation. The ball gets moving by adding a velocity vector to the position. For each frame, we also clear the canvas to remove old circles from prior frames.

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let raf;

const ball = {
  x: 100,
  y: 100,
  vx: 5,
  vy: 2,
  radius: 25,
  color: "blue",
  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI \* 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  },
};

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ball.draw();
  ball.x += ball.vx;
  ball.y += ball.vy;
  raf = window.requestAnimationFrame(draw);
}

canvas.addEventListener("mouseover", (e) => {
  raf = window.requestAnimationFrame(draw);
});

canvas.addEventListener("mouseout", (e) => {
  window.cancelAnimationFrame(raf);
});

ball.draw();
```

Boundaries
----------

Without any boundary collision testing our ball runs out of the canvas quickly. We need to check if the `x` and `y` position of the ball is out of the canvas dimensions and invert the direction of the velocity vectors. To do so, we add the following checks to the `draw` method:

```js
if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
  ball.vy = -ball.vy;
}
if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
  ball.vx = -ball.vx;
}
```

### First demo

Let's see how it looks in action so far.

#### HTML

```html
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let raf;

const ball = {
  x: 100,
  y: 100,
  vx: 5,
  vy: 2,
  radius: 25,
  color: "blue",
  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI \* 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  },
};

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ball.draw();
  ball.x += ball.vx;
  ball.y += ball.vy;

  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
    ball.vy = -ball.vy;
  }
  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
    ball.vx = -ball.vx;
  }

  raf = window.requestAnimationFrame(draw);
}

canvas.addEventListener("mouseover", (e) => {
  raf = window.requestAnimationFrame(draw);
});

canvas.addEventListener("mouseout", (e) => {
  window.cancelAnimationFrame(raf);
});

ball.draw();
```

#### Result

Move your mouse into the canvas to start the animation.

Acceleration
------------

To make the motion more real, you can play with the velocity like this, for example:

```js
ball.vy \*= 0.99;
ball.vy += 0.25;
```

This slows down the vertical velocity each frame, so that the ball will just bounce on the floor in the end.

### Second demo

#### HTML

```html
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let raf;

const ball = {
  x: 100,
  y: 100,
  vx: 5,
  vy: 2,
  radius: 25,
  color: "blue",
  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI \* 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  },
};

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ball.draw();
  ball.x += ball.vx;
  ball.y += ball.vy;
  ball.vy \*= 0.99;
  ball.vy += 0.25;

  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
    ball.vy = -ball.vy;
  }
  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
    ball.vx = -ball.vx;
  }

  raf = window.requestAnimationFrame(draw);
}

canvas.addEventListener("mouseover", (e) => {
  raf = window.requestAnimationFrame(draw);
});

canvas.addEventListener("mouseout", (e) => {
  window.cancelAnimationFrame(raf);
});

ball.draw();
```

#### Result

Trailing effect
---------------

Until now we have made use of the `clearRect` method when clearing prior frames. If you replace this method with a semi-transparent `fillRect`, you can easily create a trailing effect.

```js
ctx.fillStyle = "rgb(255 255 255 / 30%)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
```

### Third demo

#### HTML

```html
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let raf;

const ball = {
  x: 100,
  y: 100,
  vx: 5,
  vy: 2,
  radius: 25,
  color: "blue",
  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI \* 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  },
};

function draw() {
  ctx.fillStyle = "rgb(255 255 255 / 30%)";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ball.draw();
  ball.x += ball.vx;
  ball.y += ball.vy;
  ball.vy \*= 0.99;
  ball.vy += 0.25;

  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
    ball.vy = -ball.vy;
  }
  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
    ball.vx = -ball.vx;
  }

  raf = window.requestAnimationFrame(draw);
}

canvas.addEventListener("mouseover", (e) => {
  raf = window.requestAnimationFrame(draw);
});

canvas.addEventListener("mouseout", (e) => {
  window.cancelAnimationFrame(raf);
});

ball.draw();
```

#### Result

Adding mouse control
--------------------

To get some control over the ball, we can make it follow our mouse using the `mousemove` event, for example. The `click` event releases the ball and lets it bounce again.

### Fourth demo

#### HTML

```html
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let raf;
let running = false;

const ball = {
  x: 100,
  y: 100,
  vx: 5,
  vy: 1,
  radius: 25,
  color: "blue",
  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI \* 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  },
};

function clear() {
  ctx.fillStyle = "rgb(255 255 255 / 30%)";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
}

function draw() {
  clear();
  ball.draw();
  ball.x += ball.vx;
  ball.y += ball.vy;

  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
    ball.vy = -ball.vy;
  }
  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
    ball.vx = -ball.vx;
  }

  raf = window.requestAnimationFrame(draw);
}

canvas.addEventListener("mousemove", (e) => {
  if (!running) {
    clear();
    ball.x = e.clientX;
    ball.y = e.clientY;
    ball.draw();
  }
});

canvas.addEventListener("click", (e) => {
  if (!running) {
    raf = window.requestAnimationFrame(draw);
    running = true;
  }
});

canvas.addEventListener("mouseout", (e) => {
  window.cancelAnimationFrame(raf);
  running = false;
});

ball.draw();
```

#### Result

Move the ball using your mouse and release it with a click.

Breakout
--------

This short chapter only explains some techniques to create more advanced animations. There are many more! How about adding a paddle, some bricks, and turn this demo into a Breakout game? Check out our Game development area for more gaming related articles.

See also
--------

* `window.requestAnimationFrame()`
* « Previous
* Next »


Basic usage of canvas - Web APIs

Basic usage of canvas
=====================

* « Previous
* Next »

Let's start this tutorial by looking at the `<canvas>` HTML element itself. At the end of this page, you will know how to set up a canvas 2D context and have drawn a first example in your browser.

The `<canvas>` element
----------------------

```html
<canvas id="tutorial" width="150" height="150"></canvas>
```

At first sight a `<canvas>` looks like the `<img>` element, with the only clear difference being that it doesn't have the `src` and `alt` attributes. Indeed, the `<canvas>` element has only two attributes, `width` and `height`. These are both optional and can also be set using DOM properties. When no `width` and `height` attributes are specified, the canvas will initially be **300 pixels** wide and **150 pixels** high. The element can be sized arbitrarily by CSS, but during rendering the image is scaled to fit its layout size: if the CSS sizing doesn't respect the ratio of the initial canvas, it will appear distorted.

**Note:** If your renderings seem distorted, try specifying your `width` and `height` attributes explicitly in the `<canvas>` attributes, and not using CSS.

The `id` attribute isn't specific to the `<canvas>` element but is one of the global HTML attributes which can be applied to any HTML element (like `class` for instance). It is always a good idea to supply an `id` because this makes it much easier to identify it in a script.

The `<canvas>` element can be styled just like any normal image (`margin`, `border`, `background`…). These rules, however, don't affect the actual drawing on the canvas. We'll see how this is done in a dedicated chapter of this tutorial. When no styling rules are applied to the canvas it will initially be fully transparent.

### Accessible content

The `<canvas>` element, like the `<img>`, `<video>`, `<audio>`, and `<picture>` elements, must be made accessible by providing fallback text to be displayed when the media doesn't load or the user is unable to experience it as intended. You should always provide fallback content, captions, and alternative text, as appropriate for the media type.

Providing fallback content is very straightforward: just insert the alternate content inside the `<canvas>` element to be accessed by screen readers, spiders, and other automated bots. Browsers, by default, will ignore the content inside the container, rendering the canvas normally unless `<canvas>` isn't supported.

For example, we could provide a text description of the canvas content or provide a static image of the dynamically rendered content. This can look something like this:

```html
<canvas id="stockGraph" width="150" height="150">
  current stock price: $3.15 + 0.15
</canvas>

<canvas id="clock" width="150" height="150">
  <img src="images/clock.png" width="150" height="150" alt="A clock" />
</canvas>
```

Telling the user to use a different browser that supports canvas does not help users who can't read the canvas at all. Providing useful fallback text or sub DOM adds accessibility to an otherwise non-accessible element.

### Required `</canvas>` tag

As a consequence of the way fallback is provided, unlike the `<img>` element, the `<canvas>` element **requires** the closing tag (`</canvas>`). If this tag is not present, the rest of the document would be considered the fallback content and wouldn't be displayed.

If fallback content is not needed, a simple `<canvas id="foo" role="presentation" …></canvas>` is fully compatible with all browsers that support canvas at all. This should only be used if the canvas is purely presentational.

The rendering context
---------------------

The `<canvas>` element creates a fixed-size drawing surface that exposes one or more **rendering contexts**, which are used to create and manipulate the content shown. In this tutorial, we focus on the 2D rendering context. Other contexts may provide different types of rendering; for example, WebGL uses a 3D context based on OpenGL ES.

The canvas is initially blank. To display something, a script first needs to access the rendering context and draw on it. The `<canvas>` element has a method called `getContext()`, used to obtain the rendering context and its drawing functions. `getContext()` takes one parameter, the type of context. For 2D graphics, such as those covered by this tutorial, you specify `"2d"` to get a `CanvasRenderingContext2D`.

```js
const canvas = document.getElementById("tutorial");
const ctx = canvas.getContext("2d");
```

The first line in the script retrieves the node in the DOM representing the `<canvas>` element by calling the `document.getElementById()` method. Once you have the element node, you can access the drawing context using its `getContext()` method.

Checking for support
--------------------

The fallback content is displayed in browsers which do not support `<canvas>`. Scripts can also check for support programmatically by testing for the presence of the `getContext()` method. Our code snippet from above becomes something like this:

```js
const canvas = document.getElementById("tutorial");

if (canvas.getContext) {
  const ctx = canvas.getContext("2d");
  // drawing code here
} else {
  // canvas-unsupported code here
}
```

A skeleton template
-------------------

Here is a minimalistic template, which we'll be using as a starting point for later examples.

**Note:** it is not good practice to embed a script inside HTML. We do it here to keep the example concise.

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>Canvas tutorial</title>
    <style>
 canvas {
 border: 1px solid black;
 }
 </style>
  </head>
  <body>
    <canvas id="tutorial" width="150" height="150"></canvas>
    <script>
 function draw() {
 const canvas = document.getElementById("tutorial");
 if (canvas.getContext) {
 const ctx = canvas.getContext("2d");
 }
 }
 window.addEventListener("load", draw);
 </script>
  </body>
</html>
```

The script includes a function called `draw()`, which is executed once the page finishes loading; this is done by listening for the `load` event on the document. This function, or one like it, could also be called using `setTimeout()`, `setInterval()`, or any other event handler, as long as the page has been loaded first.

Here is how a template would look in action. As shown here, it is initially blank.

A simple example
----------------

To begin, let's take a look at a simple example that draws two intersecting rectangles, one of which has alpha transparency. We'll explore how this works in more detail in later examples.

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <title>Canvas experiment</title>
  </head>
  <body>
    <canvas id="canvas" width="150" height="150"></canvas>
    <script type="application/javascript">
 function draw() {
 const canvas = document.getElementById("canvas");
 if (canvas.getContext) {
 const ctx = canvas.getContext("2d");

 ctx.fillStyle = "rgb(200 0 0)";
 ctx.fillRect(10, 10, 50, 50);

 ctx.fillStyle = "rgb(0 0 200 / 50%)";
 ctx.fillRect(30, 30, 50, 50);
 }
 }
 draw();
 </script>
  </body>
</html>
```

This example looks like this:

| Screenshot | Live sample |
| --- | --- |
|  |  |

* « Previous
* Next »