<!-- To the extent possible under law, the editors have waived all copyright and related or neighboring rights to this work. -->
<pre class=metadata>
Title: Geometry Interfaces Module Level 1
Shortname: geometry
Level: 1
Status: ED
Work Status: Refining
ED: https://drafts.fxtf.org/geometry/
TR: https://www.w3.org/TR/geometry-1/
Previous Version: https://www.w3.org/TR/2014/CR-geometry-1-20141125/
Previous Version: https://www.w3.org/TR/2014/WD-geometry-1-20140918/
Previous Version: https://www.w3.org/TR/2014/WD-geometry-1-20140626/
Previous Version: https://www.w3.org/TR/2014/WD-geometry-1-20140522/
Previous Version: https://www.w3.org/TR/2013/WD-matrix-20130919/
Group: fxtf
Editor: Dirk Schulze, Adobe Inc., dschulze@adobe.com, w3cid 51803
Editor: Chris Harrelson, Google Inc., chrishtr@chromium.org, w3cid 90243
Former Editor: Simon Pieters, Opera Software AS, simonp@opera.com
Former Editor: Rik Cabanier, Magic Leap, rcabanier@magicleap.com, w3cid 106988
Abstract: This specification provides basic geometric interfaces to represent points, rectangles, quadrilaterals and transformation matrices that can be used by other modules or specifications.
Test Suite: http://test.csswg.org/suites/geometry-1_dev/nightly-unstable/
Use <i> Autolinks: no
Include Can I Use Panels: true
Can I Use URL: https://drafts.fxtf.org/geometry/
Can I Use URL: https://www.w3.org/TR/geometry-1/
Ignore Can I Use URL Failure: https://drafts.fxtf.org/geometry/
Ignore Can I Use URL Failure: https://www.w3.org/TR/geometry-1/
Complain About: accidental-2119 true
</pre>

<pre class=anchors>
urlPrefix: https://tc39.github.io/ecma262/; spec: ECMA-262
    type: dfn
        text: SameValueZero; url: sec-samevaluezero
        text: ToString; url: sec-tostring
        text: !; url: sec-algorithm-conventions
</pre>

<script src=https://resources.whatwg.org/file-issue.js async data-file-issue-url="https://github.com/w3c/fxtf-drafts/issues/new?title=[geometry]%20"></script>
<script src="../shared/MathJax/MathJax.js?config=MML_SVGorMML,local/local"></script>

<style>
a.selected-text-file-an-issue {
  position: fixed;
  bottom: 0;
  right: 0;
  background: rgba(255, 255, 255, 0.8);
  font-size: smaller;
  padding: 4px 10px;
  z-index: 4;
}
</style>

Introduction {#intro}
=====================

<em>This section is non-normative.</em>

This specification describes several geometry interfaces for the representation of points,
rectangles, quadrilaterals and transformation matrices with the dimension of 3x2 and 4x4.

The SVG interfaces {{SVGPoint}}, {{SVGRect}} and {{SVGMatrix}} are aliasing the here defined
interfaces in favor for common interfaces used by SVG, Canvas 2D Context and CSS
Transforms. [[SVG11]] [[HTML]] [[CSS3-TRANSFORMS]]


The DOMPoint interfaces {#DOMPoint}
===================================

A 2D or a 3D <dfn>point</dfn> can be represented by the following WebIDL interfaces:

<pre class=idl>
[Exposed=(Window,Worker),
 Serializable]
interface DOMPointReadOnly {
    constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
            optional unrestricted double z = 0, optional unrestricted double w = 1);

    [NewObject] static DOMPointReadOnly fromPoint(optional DOMPointInit other = {});

    readonly attribute unrestricted double x;
    readonly attribute unrestricted double y;
    readonly attribute unrestricted double z;
    readonly attribute unrestricted double w;

    [NewObject] DOMPoint matrixTransform(optional DOMMatrixInit matrix = {});

    [Default] object toJSON();
};

[Exposed=(Window,Worker),
 Serializable,
 LegacyWindowAlias=SVGPoint]
interface DOMPoint : DOMPointReadOnly {
    constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
            optional unrestricted double z = 0, optional unrestricted double w = 1);

    [NewObject] static DOMPoint fromPoint(optional DOMPointInit other = {});

    inherit attribute unrestricted double x;
    inherit attribute unrestricted double y;
    inherit attribute unrestricted double z;
    inherit attribute unrestricted double w;
};

dictionary DOMPointInit {
    unrestricted double x = 0;
    unrestricted double y = 0;
    unrestricted double z = 0;
    unrestricted double w = 1;
};
</pre>

The following algorithms assume that {{DOMPointReadOnly}} objects have the internal member
variables <dfn dfn-for=point id=point-x-coordinate>x coordinate</dfn>, <dfn dfn-for=point
id=point-y-coordinate>y coordinate</dfn>, <dfn dfn-for=point id=point-z-coordinate>z
coordinate</dfn> and <dfn dfn-for=point id=point-w-perspective>w perspective</dfn>.
{{DOMPointReadOnly}} as well as the inheriting interface {{DOMPoint}} must be able to access and set
the value of these variables.

An interface returning an {{DOMPointReadOnly}} object by an attribute or function may be able to
modify internal member variable values. Such an interface must specify this ability explicitly in
prose.

Internal member variables must not be exposed in any way.

The <dfn dfn-type=constructor dfn-for=DOMPointReadOnly><code>DOMPointReadOnly(<var>x</var>,
<var>y</var>, <var>z</var>, <var>w</var>)</code></dfn> and <dfn dfn-type=constructor
dfn-for=DOMPoint><code>DOMPoint(<var>x</var>, <var>y</var>, <var>z</var>, <var>w</var>)</code></dfn>
constructors, when invoked, must run the following steps:

1. Let <var>point</var> be a new {{DOMPointReadOnly}} or {{DOMPoint}} object as appropriate.
2. Set <var>point</var>'s variables <a for=point>x coordinate</a> to <var>x</var>, <a for=point>y coordinate</a> to <var>y</var>, <a for=point>z coordinate</a> to <var>z</var> and <a for=point>w perspective</a> to <var>w</var>.
3. Return <var>point</var>.

The <dfn method dfn-for=DOMPointReadOnly
id=dom-dompointreadonly-frompoint><code>fromPoint(<var>other</var>)</code></dfn> static method on
{{DOMPointReadOnly}} must <a>create a <code>DOMPointReadOnly</code> from the dictionary</a>
<var>other</var>.

The <dfn method dfn-for=DOMPoint
id=dom-dompoint-frompoint><code>fromPoint(<var>other</var>)</code></dfn> static method on
{{DOMPoint}} must <a>create a <code>DOMPoint</code> from the dictionary</a> <var>other</var>.

To <dfn lt="create a DOMPointReadOnly from the dictionary">create a <code>DOMPointReadOnly</code>
from a dictionary</dfn> <var>other</var>, or to <dfn lt="create a DOMPoint from the
dictionary">create a <code>DOMPoint</code> from a dictionary</dfn> <var>other</var>, follow these
steps:

1. Let <var>point</var> be a new {{DOMPointReadOnly}} or {{DOMPoint}} as appropriate.
2. <p>Set <var>point</var>'s variables <a for=point>x coordinate</a> to <var>other</var>'s
    {{DOMPointInit/x}} dictionary member, <a for=point>y coordinate</a> to <var>other</var>'s
    {{DOMPointInit/y}} dictionary member, <a for=point>z coordinate</a> to <var>other</var>'s
    {{DOMPointInit/z}} dictionary member and <a for=point>w perspective</a> to <var>other</var>'s
    {{DOMPointInit/w}} dictionary member.
3. Return <var>point</var>.

<div dfn-type=attribute dfn-for="DOMPointReadOnly, DOMPoint">
    The <dfn><code>x</code></dfn> attribute, on getting, must return the <a for=point>x
    coordinate</a> value. For the {{DOMPoint}} interface, setting the
    {{DOMPoint/x}} attribute must set the <a for=point>x coordinate</a> to the new value.

    The <dfn><code>y</code></dfn> attribute, on getting, must return the <a for=point>y
    coordinate</a> value. For the {{DOMPoint}} interface, setting the
    {{DOMPoint/y}} attribute must set the <a for=point>y coordinate</a> to the new value.

    The <dfn><code>z</code></dfn> attribute, on getting, must return the <a for=point>z
    coordinate</a> value. For the {{DOMPoint}} interface, setting the
    {{DOMPoint/z}} attribute must set the <a for=point>z coordinate</a> to the new value.

    The <dfn><code>w</code></dfn> attribute, on getting, must return the <a for=point>w
    perspective</a> value. For the {{DOMPoint}} interface, setting the
    {{DOMPoint/w}} attribute must set the <a for=point>w perspective</a> to the new value.
</div>

The <dfn dfn-type=method dfn-for=DOMPointReadOnly>matrixTransform(<var>matrix</var>)</dfn>
method, when invoked, must run the following steps:

1. Let <var>matrixObject</var> be the result of invoking <a>create a <code>DOMMatrix</code>
    from the dictionary</a> <var>matrix</var>.
2. Return the result of invoking <a>transform a point with a matrix</a>, given the current
    point and <var>matrixObject</var>. The current point does not get modified.

<div class=example>
In this example the method {{DOMPointReadOnly/matrixTransform()}} on a {{DOMPoint}} instance is
called with a {{DOMMatrix}} instance as argument.

<pre><code highlight=javascript>
var point = new DOMPoint(5, 4);
var matrix = new DOMMatrix([2, 0, 0, 2, 10, 10]);
var transformedPoint = point.matrixTransform(matrix);
</code></pre>

The <var ignore>point</var> variable is set to a new {{DOMPoint}} object with <a for=point>x
coordinate</a> initialized to 5 and <a for=point>y coordinate</a> initialized to 4. This new
{{DOMPoint}} is now scaled and the translated by <var ignore>matrix</var>. This resulting <var
ignore>transformedPoint</var> has the <a for=point>x coordinate</a> 20 and <a for=point>y
coordinate</a> 18.
</div>


Transforming a point with a matrix {#transforming-a-point-with-a-matrix}
------------------------------------------------------------------------

To <dfn export>transform a <a>point</a> with a <a>matrix</a></dfn>, given <var>point</var> and
<var>matrix</var>:

1. Let <var>x</var> be <var>point</var>'s <a for=point>x coordinate</a>.
2. Let <var>y</var> be <var>point</var>'s <a for=point>y coordinate</a>.
3. Let <var>z</var> be <var>point</var>'s <a for=point>z coordinate</a>.
4. Let <var>w</var> be <var>point</var>'s <a for=point>w perspective</a>.
5. Let <var>pointVector</var> be a new column vector with the elements being <var>x</var>,
    <var>y</var>, <var>z</var>, and <var>w</var>, respectively.

    <math display=inline><mrow><mfenced open=[ close=]><mrow><mtable><mtr><mtd><mi>x</mi></mtd></mtr><mtr><mtd><mi>y</mi></mtd></mtr><mtr><mtd><mi>z</mi></mtd></mtr><mtr><mtd><mi>w</mi></mtd></mtr></mtable></mrow></mfenced></mrow></math>
6. Set <var>pointVector</var> to <var>pointVector</var> <a>post-multiplied</a> by
    <var>matrix</var>.
7. Let <var>transformedPoint</var> be a new {{DOMPoint}} object.
8. Set <var>transformedPoint</var>'s <a for=point>x coordinate</a> to <var>pointVector</var>'s
    first element.
9. Set <var>transformedPoint</var>'s <a for=point>y coordinate</a> to <var>pointVector</var>'s
    second element.
10. Set <var>transformedPoint</var>'s <a for=point>z coordinate</a> to <var>pointVector</var>'s
    third element.
11. Set <var>transformedPoint</var>'s <a for=point>w perspective</a> to <var>pointVector</var>'s
    fourth element.
12. Return <var>transformedPoint</var>.

Note: If <var>matrix</var>'s <a for=matrix>is 2D</a> is true, <var>point</var>'s <a
for=point>z coordinate</a> is ''0'' or ''-0'', and <var>point</var>'s <a for=point>w perspective</a>
is ''1'', then this is a 2D transformation. Otherwise this is a 3D transformation.


The DOMRect interfaces {#DOMRect}
=================================

Objects implementing the {{DOMRectReadOnly}} interface represent a <dfn>rectangle</dfn>.

<a>Rectangles</a> have the following properties:

<dl dfn-for=rectangle>
    : <dfn for=rectangle id=rectangle-origin>origin</dfn>
    ::
        When the rectangle has a non-negative <a for=rectangle>width dimension</a>, the rectangle's
        horizontal origin is the left edge; otherwise, it is the right edge. Similarly, when the rectangle
        has a non-negative <a for=rectangle>height dimension</a>, the rectangle's vertical origin is the
        top edge; otherwise, it is the bottom edge.
    : <dfn for=rectangle id=rectangle-x-coordinate>x coordinate</dfn>
    ::
        The horizontal distance between the viewport's left edge and the rectangle's <a
        for=rectangle>origin</a>.
    : <dfn for=rectangle id=rectangle-y-coordinate>y coordinate</dfn>
    ::
        The vertical distance between the viewport's top edge and the rectangle's <a
        for=rectangle>origin</a>.
    : <dfn for=rectangle id=rectangle-width-dimension>width dimension</dfn>
    ::
        The width of the rectangle. Can be negative.
    : <dfn for=rectangle id=rectangle-height-dimension>height dimension</dfn>
    ::
        The height of the rectangle. Can be negative.
</dl>

<pre class=idl>
[Exposed=(Window,Worker),
 Serializable]
interface DOMRectReadOnly {
    constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
            optional unrestricted double width = 0, optional unrestricted double height = 0);

    [NewObject] static DOMRectReadOnly fromRect(optional DOMRectInit other = {});

    readonly attribute unrestricted double x;
    readonly attribute unrestricted double y;
    readonly attribute unrestricted double width;
    readonly attribute unrestricted double height;
    readonly attribute unrestricted double top;
    readonly attribute unrestricted double right;
    readonly attribute unrestricted double bottom;
    readonly attribute unrestricted double left;

    [Default] object toJSON();
};

[Exposed=(Window,Worker),
 Serializable,
 LegacyWindowAlias=SVGRect]
interface DOMRect : DOMRectReadOnly {
    constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
            optional unrestricted double width = 0, optional unrestricted double height = 0);

    [NewObject] static DOMRect fromRect(optional DOMRectInit other = {});

    inherit attribute unrestricted double x;
    inherit attribute unrestricted double y;
    inherit attribute unrestricted double width;
    inherit attribute unrestricted double height;
};

dictionary DOMRectInit {
    unrestricted double x = 0;
    unrestricted double y = 0;
    unrestricted double width = 0;
    unrestricted double height = 0;
};
</pre>

The following algorithms assume that {{DOMRectReadOnly}} objects have the internal member
variables <a for=rectangle>x coordinate</a>, <a for=rectangle>y coordinate</a>, <a
for=rectangle>width dimension</a> and <a for=rectangle>height dimension</a>. {{DOMRectReadOnly}} as
well as the inheriting interface {{DOMRect}} must be able to access and set the value of these
variables.

An interface returning an {{DOMRectReadOnly}} object by an attribute or function may be able to
modify internal member variable values. Such an interface must specify this ability explicitly in
prose.

Internal member variables must not be exposed in any way.

The <dfn dfn-type=constructor dfn-for=DOMRectReadOnly><code>DOMRectReadOnly(<var>x</var>,
<var>y</var>, <var>width</var>, <var>height</var>)</code></dfn> and <dfn dfn-type=constructor
dfn-for=DOMRect><code>DOMRect(<var>x</var>, <var>y</var>, <var>width</var>,
<var>height</var>)</code></dfn> constructors, when invoked, must run the following steps:

1. Let <var>rect</var> be a new {{DOMRectReadOnly}} or {{DOMRect}} object as appropriate.
2. Set <var>rect</var>'s variables <a for=rectangle>x coordinate</a> to <var>x</var>, <a
    for=rectangle>y coordinate</a> to <var>y</var>, <a for=rectangle>width dimension</a> to
    <var>width</var> and <a for=rectangle>height dimension</a> to <var>height</var>.
3. Return <var>rect</var>.

The <dfn method lt=fromRect() dfn-for=DOMRectReadOnly
id=dom-domrectreadonly-fromrect><code>fromRect(<var>other</var>)</code></dfn> static method on
{{DOMRectReadOnly}} must <a>create a <code>DOMRectReadOnly</code> from the dictionary</a>
<var>other</var>.

The <dfn method lt=fromRect() dfn-for=DOMRect
id=dom-domrect-fromrect><code>fromRect(<var>other</var>)</code></dfn> static method on {{DOMRect}}
must <a>create a <code>DOMRect</code> from the dictionary</a> <var>other</var>.

To <dfn lt="create a DOMRectReadOnly from the dictionary">create a <code>DOMRectReadOnly</code>
from a dictionary</dfn> <var>other</var>, or to <dfn lt="create a DOMRect from the
dictionary">create a <code>DOMRect</code> from a dictionary</dfn> <var>other</var>, follow these
steps:

1. Let <var>rect</var> be a new {{DOMRectReadOnly}} or {{DOMRect}} as appropriate.
2. Set <var>rect</var>'s variables <a for=rectangle>x coordinate</a> to <var>other</var>'s
    {{DOMRectInit/x}} dictionary member, <a for=rectangle>y coordinate</a> to <var>other</var>'s
    {{DOMRectInit/y}} dictionary member, <a for=rectangle>width dimension</a> to <var>other</var>'s
    {{DOMRectInit/width}} dictionary member and <a for=rectangle>height dimension</a> to
    <var>other</var>'s {{DOMRectInit/height}} dictionary member.
3. Return <var>rect</var>.

<div dfn-type=attribute dfn-for="DOMRectReadOnly DOMRect">
The <dfn><code>x</code></dfn> attribute, on getting, must return the <a for=rectangle>x
coordinate</a> value. For the {{DOMRect}} interface, setting the
{{DOMRect/x}} attribute must set the <a for=rectangle>x coordinate</a> to the new value.

The <dfn><code>y</code></dfn> attribute, on getting, it must return the <a for=rectangle>y
coordinate</a> value. For the {{DOMRect}} interface, setting the
{{DOMRect/y}} attribute must set the <a for=rectangle>y coordinate</a> to the new value.

The <dfn><code>width</code></dfn> attribute, on getting, must return the <a for=rectangle>width
dimension</a> value. For the {{DOMRect}} interface, setting the
{{DOMRect/width}} attribute must set the <a for=rectangle>width dimension</a> to the new value.

The <dfn><code>height</code></dfn> attribute, on getting, must return the <a
for=rectangle>height dimension</a> value. For the {{DOMRect}} interface, setting the
{{DOMRect/height}} attribute must set the <a for=rectangle>height dimension</a> value to the new
value.

The <dfn><code>top</code></dfn> attribute, on getting, must return min(<a for=rectangle>y
coordinate</a>, <a for=rectangle>y coordinate</a> + <a for=rectangle>height dimension</a>).

The <dfn><code>right</code></dfn> attribute, on getting, must return max(<a for=rectangle>x
coordinate</a>, <a for=rectangle>x coordinate</a> + <a for=rectangle>width dimension</a>).

The <dfn><code>bottom</code></dfn> attribute, on getting, must return max(<a for=rectangle>y
coordinate</a>, <a for=rectangle>y coordinate</a> + <a for=rectangle>height dimension</a>).

The <dfn><code>left</code></dfn> attribute, on getting, must return min(<a for=rectangle>x
coordinate</a>, <a for=rectangle>x coordinate</a> + <a for=rectangle>width dimension</a>).
</div>


The DOMRectList interface {#DOMRectList}
========================================

<pre class=idl>
[Exposed=Window]
interface DOMRectList {
    readonly attribute unsigned long length;
    getter DOMRect? item(unsigned long index);
};
</pre>

The <dfn dfn-type=attribute dfn-for=DOMRectList>length</dfn> attribute must return the total
number of {{DOMRect}} objects associated with the object.

The <dfn dfn-type=method dfn-for=DOMRectList>item(<var>index</var>)</dfn> method, when invoked, must
return ''null'' when <var>index</var> is greater than or equal to the number of {{DOMRect}} objects
associated with the {{DOMRectList}}. Otherwise, the {{DOMRect}} object at <var>index</var> must be
returned. Indices are zero-based.

ADVISEMENT: {{DOMRectList}} only exists for compatibility with legacy Web content. When specifying a
new API, {{DOMRectList}} must not be used. Use <code>sequence&lt;DOMRect></code> instead. [[WEBIDL]]


The DOMQuad interface {#DOMQuad}
================================

Objects implementing the {{DOMQuad}} interface represents a <dfn export>quadrilateral</dfn>.

<pre class=idl>
[Exposed=(Window,Worker),
 Serializable]
interface DOMQuad {
    constructor(optional DOMPointInit p1 = {}, optional DOMPointInit p2 = {},
            optional DOMPointInit p3 = {}, optional DOMPointInit p4 = {});

    [NewObject] static DOMQuad fromRect(optional DOMRectInit other = {});
    [NewObject] static DOMQuad fromQuad(optional DOMQuadInit other = {});

    [SameObject] readonly attribute DOMPoint p1;
    [SameObject] readonly attribute DOMPoint p2;
    [SameObject] readonly attribute DOMPoint p3;
    [SameObject] readonly attribute DOMPoint p4;
    [NewObject] DOMRect getBounds();

    [Default] object toJSON();
};

dictionary DOMQuadInit {
  DOMPointInit p1;
  DOMPointInit p2;
  DOMPointInit p3;
  DOMPointInit p4;
};
</pre>

The following algorithms assume that {{DOMQuad}} objects have the internal member variables <dfn
dfn-for=quadrilateral id=quadrilateral-point-1>point 1</dfn>, <dfn dfn-for=quadrilateral
id=quadrilateral-point-2>point 2</dfn>, <dfn dfn-for=quadrilateral id=quadrilateral-point-3>point
3</dfn>, and <dfn dfn-for=quadrilateral id=quadrilateral-point-4>point 4</dfn>, which are
{{DOMPoint}} objects. {{DOMQuad}} must be able to access and set the value of these variables. The
author can modify these {{DOMPoint}} objects, which directly affects the quadrilateral.

An interface returning a {{DOMQuad}} object by an attribute or function may be able to modify
internal member variable values. Such an interface must specify this ability explicitly in prose.

Internal member variables must not be exposed in any way.

The <dfn dfn-type=constructor dfn-for=DOMQuad><code>DOMQuad(<var>p1</var>, <var>p2</var>,
<var>p3</var>, <var>p4</var>)</code></dfn> constructor, when invoked, must run the following steps:

1. Let <var>point1</var> be a new {{DOMPoint}} object with its attributes set to the values of
    the namesake dictionary members in <var>p1</var>.
2. Let <var>point2</var> be a new {{DOMPoint}} object with its attributes set to the values of
    the namesake dictionary members in <var>p2</var>.
3. Let <var>point3</var> be a new {{DOMPoint}} object with its attributes set to the values of
    the namesake dictionary members in <var>p3</var>.
4. Let <var>point4</var> be a new {{DOMPoint}} object with its attributes set to the values of
    the namesake dictionary members in <var>p4</var>.
5. Return a new {{DOMQuad}} with <a for=quadrilateral>point 1</a> set to <var>point1</var>, <a
    for=quadrilateral>point 2</a> set to <var>point2</var>, <a for=quadrilateral>point 3</a> set to
    <var>point3</var> and <a for=quadrilateral>point 4</a> set to <var>point4</var>.

Note: It is possible to pass {{DOMPoint}}/{{DOMPointReadOnly}} arguments as well. The passed
arguments will be transformed to the correct object type internally following the WebIDL rules.
[[!WEBIDL]]

The <dfn method lt=fromRect() dfn-for=DOMQuad><code>fromRect(<var>other</var>)</code></dfn>
static method on {{DOMQuad}} must <a>create a <code>DOMQuad</code> from the <code>DOMRectInit</code>
dictionary</a> <var>other</var>.

To <dfn lt="create a DOMQuad from the DOMRectInit dictionary">create a <code>DOMQuad</code> from
a <code>DOMRectInit</code> dictionary</dfn> <var>other</var>, follow these steps:

1. <p>Let <var>x</var>, <var>y</var>, <var>width</var> and <var>height</var> be the value of
    <var>other</var>'s {{DOMRectInit/x}}, {{DOMRectInit/y}}, {{DOMRectInit/width}} and
    {{DOMRectInit/height}} dictionary members, respectively.
2. Let <var>point1</var> be a new {{DOMPoint}} object with <a for=point>x coordinate</a> set to
    <var>x</var>, <a for=point>y coordinate</a> set to <var>y</var>, <a for=point>z coordinate</a> set
    to ''0'' and <a for=point>w perspective</a> set to ''1''.
3. Let <var>point2</var> be a new {{DOMPoint}} object with <a for=point>x coordinate</a> set to
    <var>x</var> + <var>width</var>, <a for=point>y coordinate</a> set to <var>y</var>, <a for=point>z
    coordinate</a> set to ''0'' and <a for=point>w perspective</a> set to ''1''.
4. Let <var>point3</var> be a new {{DOMPoint}} object with <a for=point>x coordinate</a> set to
    <var>x</var> + <var>width</var>, <a for=point>y coordinate</a> set to <var>y</var> +
    <var>height</var>, <a for=point>z coordinate</a> set to ''0'' and <a for=point>w perspective</a>
    set to ''1''.
5. Let <var>point4</var> be a new {{DOMPoint}} object with <a for=point>x coordinate</a> set to
    <var>x</var>, <a for=point>y coordinate</a> set to <var>y</var> + <var>height</var>, <a for=point>z
    coordinate</a> set to ''0'' and <a for=point>w perspective</a> set to ''1''.
6. Return a new {{DOMQuad}} with <a for=quadrilateral>point 1</a> set to <var>point1</var>, <a
    for=quadrilateral>point 2</a> set to <var>point2</var>, <a for=quadrilateral>point 3</a> set to
    <var>point3</var> and <a for=quadrilateral>point 4</a> set to <var>point4</var>.

The <dfn method lt=fromQuad() dfn-for=DOMQuad><code>fromQuad(<var>other</var>)</code></dfn>
static method on {{DOMQuad}} must <a>create a <code>DOMQuad</code> from the <code>DOMQuadInit</code>
dictionary</a> <var>other</var>.

To <dfn lt="create a DOMQuad from the DOMQuadInit dictionary">create a <code>DOMQuad</code> from
a <code>DOMQuadInit</code> dictionary</dfn> <var>other</var>, follow these steps:

1. Let <var>point1</var> be the result of invoking <a>create a <code>DOMPoint</code> from the
    dictionary</a> {{DOMQuadInit/p1}} dictionary member of <var>other</var>, if it exists.
2. Let <var>point2</var> be the result of invoking <a>create a <code>DOMPoint</code> from the
    dictionary</a> {{DOMQuadInit/p2}} dictionary member of <var>other</var>, if it exists.
3. Let <var>point3</var> be the result of invoking <a>create a <code>DOMPoint</code> from the
    dictionary</a> {{DOMQuadInit/p3}} dictionary member of <var>other</var>, if it exists.
4. Let <var>point4</var> be the result of invoking <a>create a <code>DOMPoint</code> from the
    dictionary</a> {{DOMQuadInit/p4}} dictionary member of <var>other</var>, if it exists.
5. Return a new {{DOMQuad}} with <a for=quadrilateral>point 1</a> set to <var>point1</var>, <a
    for=quadrilateral>point 2</a> set to <var>point2</var>, <a for=quadrilateral>point 3</a> set to
    <var>point3</var> and <a for=quadrilateral>point 4</a> set to <var>point4</var>.

<div dfn-type=attribute dfn-for=DOMQuad>
The <dfn><code>p1</code></dfn> attribute must return <a for=quadrilateral>point 1</a>.

The <dfn><code>p2</code></dfn> attribute must return <a for=quadrilateral>point 2</a>.

The <dfn><code>p3</code></dfn> attribute must return <a for=quadrilateral>point 3</a>.

The <dfn><code>p4</code></dfn> attribute must return <a for=quadrilateral>point 4</a>.
</div>

The <dfn method for=DOMQuad>getBounds()</dfn> method, when invoked, must run the following
algorithm:

1. Let <var>bounds</var> be a {{DOMRect}} object.
2. Let <var>left</var> be the minimum of <a for=quadrilateral>point 1</a>'s <a for=point>x
    coordinate</a>, <a for=quadrilateral>point 2</a>'s <a for=point>x coordinate</a>, <a
    for=quadrilateral>point 3</a>'s <a for=point>x coordinate</a> and <a for=quadrilateral>point
    4</a>'s <a for=point>x coordinate</a>.
3. Let <var>top</var> be the minimum of <a for=quadrilateral>point 1</a>'s <a for=point>y
    coordinate</a>, <a for=quadrilateral>point 2</a>'s <a for=point>y coordinate</a>, <a
    for=quadrilateral>point 3</a>'s <a for=point>y coordinate</a> and <a for=quadrilateral>point
    4</a>'s <a for=point>y coordinate</a>.
4. Let <var>right</var> be the maximum of <a for=quadrilateral>point 1</a>'s <a for=point>x
    coordinate</a>, <a for=quadrilateral>point 2</a>'s <a for=point>x coordinate</a>, <a
    for=quadrilateral>point 3</a>'s <a for=point>x coordinate</a> and <a for=quadrilateral>point
    4</a>'s <a for=point>x coordinate</a>.
5. Let <var>bottom</var> be the maximum of <a for=quadrilateral>point 1</a>'s <a for=point>y
    coordinate</a>, <a for=quadrilateral>point 2</a>'s <a for=point>y coordinate</a>, <a
    for=quadrilateral>point 3</a>'s <a for=point>y coordinate</a> and <a for=quadrilateral>point
    4</a>'s <a for=point>y coordinate</a>.
6. Set <a for=rectangle>x coordinate</a> of <var>bounds</var> to <var>left</var>, <a
    for=rectangle>y coordinate</a> of <var>bounds</var> to <var>top</var>, <a for=rectangle>width
    dimension</a> of <var>bounds</var> to <var>right</var> - <var>left</var> and <a
    for=rectangle>height dimension</a> of <var>bounds</var> to <var>bottom</var> - <var>top</var>.
7. Return <var>bounds</var>.

<div class=example>
In this example the {{DOMQuad}} constructor is called with arguments of type {{DOMPoint}} and
{{DOMPointInit}}. Both arguments are accepted and can be used.

<pre><code highlight=javascript>
var point = new DOMPoint(2, 0);
var quad1 = new DOMQuad(point, {x: 12, y: 0}, {x: 12, y: 10}, {x: 2, y: 10});
</code></pre>

The attribute values of the resulting {{DOMQuad}} <var ignore>quad1</var> above are also
equivalent to the attribute values of the following {{DOMQuad}} <var ignore>quad2</var>:

<pre><code highlight=javascript>
var rect = new DOMRect(2, 0, 10, 10);
var quad2 = DOMQuad.fromRect(rect);
</code></pre>
</div>

<div class=example>
This is an example of an irregular quadrilateral:

<pre><code highlight=javascript>
new DOMQuad({x: 40, y: 25}, {x: 180, y: 8}, {x: 210, y: 150}, {x: 10, y: 180});
</code></pre>

<figure>
    <svg width="230" height="200" role="img" aria-label="An irregular quadrilateral with none of the
    sides being vertical or horizontal. Its four corners are marked with red circles. Around this
    quadrilateral is a dashed rectangle. All sides of this rectangle are vertical or horizontal and
    tangent the quadrilateral.">
        <polygon points="40 25, 180 8, 210 150, 10 180" fill="rgb(51, 153, 204)"/>
        <rect x="10" y="8" width="200" height="172" fill="none" stroke="black" stroke-dasharray="3 2"/>
        <circle cx="40" cy="25" r="3" fill="rgb(204, 51, 51)"/>
        <circle cx="180" cy="8" r="3" fill="rgb(204, 51, 51)"/>
        <circle cx="210" cy="150" r="3" fill="rgb(204, 51, 51)"/>
        <circle cx="10" cy="180" r="3" fill="rgb(204, 51, 51)"/>
    </svg>
    <figcaption>An irregular quadrilateral represented by a {{DOMQuad}}. The four red colored
    circles represent the {{DOMPoint}} attributes {{DOMQuad/p1}} to {{DOMQuad/p4}}. The dashed
    rectangle represents the bounding rectangle returned by the {{DOMQuad/getBounds()}} method of the
    {{DOMQuad}}.</figcaption>
</figure>
</div>


The DOMMatrix interfaces {#DOMMatrix}
=====================================

The {{DOMMatrix}} and {{DOMMatrixReadOnly}} interfaces each represent a mathematical <dfn
caniuse=dommatrix>matrix</dfn> with the purpose of describing transformations in a graphical
context. The following sections describe the details of the interface.

<figure>
    <math display=block><mrow><mfenced open=[ close=] separators=,><mrow><mtable><mtr><mtd><msub><mi>m</mi><mi>11</mi></msub></mtd><mtd><msub><mi>m</mi><mi>21</mi></msub></mtd><mtd><msub><mi>m</mi><mi>31</mi></msub></mtd><mtd><msub><mi>m</mi><mi>41</mi></msub></mtd></mtr><mtr><mtd><msub><mi>m</mi><mi>12</mi></msub></mtd><mtd><msub><mi>m</mi><mi>22</mi></msub></mtd><mtd><msub><mi>m</mi><mi>32</mi></msub></mtd><mtd><msub><mi>m</mi><mi>42</mi></msub></mtd></mtr><mtr><mtd><msub><mi>m</mi><mi>13</mi></msub></mtd><mtd><msub><mi>m</mi><mi>23</mi></msub></mtd><mtd><msub><mi>m</mi><mi>33</mi></msub></mtd><mtd><msub><mi>m</mi><mi>43</mi></msub></mtd></mtr><mtr><mtd><msub><mi>m</mi><mi>14</mi></msub></mtd><mtd><msub><mi>m</mi><mi>24</mi></msub></mtd><mtd><msub><mi>m</mi><mi>34</mi></msub></mtd><mtd><msub><mi>m</mi><mi>44</mi></msub></mtd></mtr></mtable></mrow></mfenced></mrow></math>
    <figcaption>A <dfn>4x4 abstract matrix</dfn> with items <var
    ignore>m<sub>11</sub></var> to <var ignore>m<sub>44</sub></var>.</figcaption>
</figure>

In the following sections, terms have the following meaning:

<dl export>
    : <dfn>post-multiply</dfn>
    ::
        <p>Term <var>A</var> post-multiplied by term <var>B</var> is equal to <var>A</var> &middot;
        <var>B</var>.
    : <dfn>pre-multiply</dfn>
    ::
        Term <var>A</var> pre-multiplied by term <var>B</var> is equal to <var>B</var> &middot;
        <var>A</var>.
    : <dfn>multiply</dfn>
    ::
        Multiply term <var>A</var> by term <var>B</var> is equal to <var>A</var> &middot;
        <var>B</var>.
</dl>

<pre class=idl>
[Exposed=(Window,Worker),
 Serializable]
interface DOMMatrixReadOnly {
    constructor(optional (DOMString or sequence&lt;unrestricted double>) init);

    [NewObject] static DOMMatrixReadOnly fromMatrix(optional DOMMatrixInit other = {});
    [NewObject] static DOMMatrixReadOnly fromFloat32Array(Float32Array array32);
    [NewObject] static DOMMatrixReadOnly fromFloat64Array(Float64Array array64);

    // These attributes are simple aliases for certain elements of the 4x4 matrix
    readonly attribute unrestricted double a;
    readonly attribute unrestricted double b;
    readonly attribute unrestricted double c;
    readonly attribute unrestricted double d;
    readonly attribute unrestricted double e;
    readonly attribute unrestricted double f;

    readonly attribute unrestricted double m11;
    readonly attribute unrestricted double m12;
    readonly attribute unrestricted double m13;
    readonly attribute unrestricted double m14;
    readonly attribute unrestricted double m21;
    readonly attribute unrestricted double m22;
    readonly attribute unrestricted double m23;
    readonly attribute unrestricted double m24;
    readonly attribute unrestricted double m31;
    readonly attribute unrestricted double m32;
    readonly attribute unrestricted double m33;
    readonly attribute unrestricted double m34;
    readonly attribute unrestricted double m41;
    readonly attribute unrestricted double m42;
    readonly attribute unrestricted double m43;
    readonly attribute unrestricted double m44;

    readonly attribute boolean is2D;
    readonly attribute boolean isIdentity;

    // Immutable transform methods
    [NewObject] DOMMatrix translate(optional unrestricted double tx = 0,
                                    optional unrestricted double ty = 0,
                                    optional unrestricted double tz = 0);
    [NewObject] DOMMatrix scale(optional unrestricted double scaleX = 1,
                                optional unrestricted double scaleY,
                                optional unrestricted double scaleZ = 1,
                                optional unrestricted double originX = 0,
                                optional unrestricted double originY = 0,
                                optional unrestricted double originZ = 0);
    [NewObject] DOMMatrix scaleNonUniform(optional unrestricted double scaleX = 1,
                                          optional unrestricted double scaleY = 1);
    [NewObject] DOMMatrix scale3d(optional unrestricted double scale = 1,
                                  optional unrestricted double originX = 0,
                                  optional unrestricted double originY = 0,
                                  optional unrestricted double originZ = 0);
    [NewObject] DOMMatrix rotate(optional unrestricted double rotX = 0,
                                 optional unrestricted double rotY,
                                 optional unrestricted double rotZ);
    [NewObject] DOMMatrix rotateFromVector(optional unrestricted double x = 0,
                                           optional unrestricted double y = 0);
    [NewObject] DOMMatrix rotateAxisAngle(optional unrestricted double x = 0,
                                          optional unrestricted double y = 0,
                                          optional unrestricted double z = 0,
                                          optional unrestricted double angle = 0);
    [NewObject] DOMMatrix skewX(optional unrestricted double sx = 0);
    [NewObject] DOMMatrix skewY(optional unrestricted double sy = 0);
    [NewObject] DOMMatrix multiply(optional DOMMatrixInit other = {});
    [NewObject] DOMMatrix flipX();
    [NewObject] DOMMatrix flipY();
    [NewObject] DOMMatrix inverse();

    [NewObject] DOMPoint transformPoint(optional DOMPointInit point = {});
    [NewObject] Float32Array toFloat32Array();
    [NewObject] Float64Array toFloat64Array();

    [Exposed=Window] stringifier;
    [Default] object toJSON();
};

[Exposed=(Window,Worker),
 Serializable,
 LegacyWindowAlias=(SVGMatrix,WebKitCSSMatrix)]
interface DOMMatrix : DOMMatrixReadOnly {
    constructor(optional (DOMString or sequence&lt;unrestricted double>) init);

    [NewObject] static DOMMatrix fromMatrix(optional DOMMatrixInit other = {});
    [NewObject] static DOMMatrix fromFloat32Array(Float32Array array32);
    [NewObject] static DOMMatrix fromFloat64Array(Float64Array array64);

    // These attributes are simple aliases for certain elements of the 4x4 matrix
    inherit attribute unrestricted double a;
    inherit attribute unrestricted double b;
    inherit attribute unrestricted double c;
    inherit attribute unrestricted double d;
    inherit attribute unrestricted double e;
    inherit attribute unrestricted double f;

    inherit attribute unrestricted double m11;
    inherit attribute unrestricted double m12;
    inherit attribute unrestricted double m13;
    inherit attribute unrestricted double m14;
    inherit attribute unrestricted double m21;
    inherit attribute unrestricted double m22;
    inherit attribute unrestricted double m23;
    inherit attribute unrestricted double m24;
    inherit attribute unrestricted double m31;
    inherit attribute unrestricted double m32;
    inherit attribute unrestricted double m33;
    inherit attribute unrestricted double m34;
    inherit attribute unrestricted double m41;
    inherit attribute unrestricted double m42;
    inherit attribute unrestricted double m43;
    inherit attribute unrestricted double m44;

    // Mutable transform methods
    DOMMatrix multiplySelf(optional DOMMatrixInit other = {});
    DOMMatrix preMultiplySelf(optional DOMMatrixInit other = {});
    DOMMatrix translateSelf(optional unrestricted double tx = 0,
                            optional unrestricted double ty = 0,
                            optional unrestricted double tz = 0);
    DOMMatrix scaleSelf(optional unrestricted double scaleX = 1,
                        optional unrestricted double scaleY,
                        optional unrestricted double scaleZ = 1,
                        optional unrestricted double originX = 0,
                        optional unrestricted double originY = 0,
                        optional unrestricted double originZ = 0);
    DOMMatrix scale3dSelf(optional unrestricted double scale = 1,
                          optional unrestricted double originX = 0,
                          optional unrestricted double originY = 0,
                          optional unrestricted double originZ = 0);
    DOMMatrix rotateSelf(optional unrestricted double rotX = 0,
                         optional unrestricted double rotY,
                         optional unrestricted double rotZ);
    DOMMatrix rotateFromVectorSelf(optional unrestricted double x = 0,
                                   optional unrestricted double y = 0);
    DOMMatrix rotateAxisAngleSelf(optional unrestricted double x = 0,
                                  optional unrestricted double y = 0,
                                  optional unrestricted double z = 0,
                                  optional unrestricted double angle = 0);
    DOMMatrix skewXSelf(optional unrestricted double sx = 0);
    DOMMatrix skewYSelf(optional unrestricted double sy = 0);
    DOMMatrix invertSelf();

    [Exposed=Window] DOMMatrix setMatrixValue(DOMString transformList);
};

dictionary DOMMatrix2DInit {
    unrestricted double a;
    unrestricted double b;
    unrestricted double c;
    unrestricted double d;
    unrestricted double e;
    unrestricted double f;
    unrestricted double m11;
    unrestricted double m12;
    unrestricted double m21;
    unrestricted double m22;
    unrestricted double m41;
    unrestricted double m42;
};

dictionary DOMMatrixInit : DOMMatrix2DInit {
    unrestricted double m13 = 0;
    unrestricted double m14 = 0;
    unrestricted double m23 = 0;
    unrestricted double m24 = 0;
    unrestricted double m31 = 0;
    unrestricted double m32 = 0;
    unrestricted double m33 = 1;
    unrestricted double m34 = 0;
    unrestricted double m43 = 0;
    unrestricted double m44 = 1;
    boolean is2D;
};
</pre>

The following algorithms assume that {{DOMMatrixReadOnly}} objects have the internal member
variables <dfn dfn-for=matrix>m11 element</dfn>, <dfn dfn-for=matrix>m12 element</dfn>, <dfn
dfn-for=matrix>m13 element</dfn>, <dfn dfn-for=matrix>m14 element</dfn>, <dfn dfn-for=matrix>m21
element</dfn>, <dfn dfn-for=matrix>m22 element</dfn>, <dfn dfn-for=matrix>m23 element</dfn>, <dfn
dfn-for=matrix>m24 element</dfn>, <dfn dfn-for=matrix>m31 element</dfn>, <dfn dfn-for=matrix>m32
element</dfn>, <dfn dfn-for=matrix>m33 element</dfn>, <dfn dfn-for=matrix>m34 element</dfn>, <dfn
dfn-for=matrix>m41 element</dfn>, <dfn dfn-for=matrix>m42 element</dfn>, <dfn dfn-for=matrix>m43
element</dfn>, <dfn dfn-for=matrix>m44 element</dfn> and <a for=matrix>is 2D</a>.
{{DOMMatrixReadOnly}} as well as the inheriting interface {{DOMMatrix}} must be able to access and
set the value of these variables.

An interface returning an {{DOMMatrixReadOnly}} object by an attribute or function may be able to
modify internal member variable values. Such an interface must specify this ability explicitly in
prose.

Internal member variables must not be exposed in any way.

The {{DOMMatrix}} and {{DOMMatrixReadOnly}} interfaces replace the <code>SVGMatrix</code>
interface from SVG. [[SVG11]]


DOMMatrix2DInit and DOMMatrixInit dictionaries {#dommatrixinit-dictionary}
--------------------------------------------------------------------------

To <dfn dfn-for=matrix>validate and fixup (2D)</dfn> a {{DOMMatrix2DInit}} or {{DOMMatrixInit}}
dictionary <var>dict</var>, run the following steps:

1. If if at least one of the following conditions are true for <var>dict</var>, then throw a
    {{TypeError}} exception and abort these steps.
    * {{DOMMatrix2DInit/a}} and {{DOMMatrix2DInit/m11}} are both present and
        [=SameValueZero=]({{DOMMatrix2DInit/a}}, {{DOMMatrix2DInit/m11}}) is <code>false</code>.
    * {{DOMMatrix2DInit/b}} and {{DOMMatrix2DInit/m12}} are both present and
        [=SameValueZero=]({{DOMMatrix2DInit/b}}, {{DOMMatrix2DInit/m12}}) is <code>false</code>.
    * {{DOMMatrix2DInit/c}} and {{DOMMatrix2DInit/m21}} are both present and
        [=SameValueZero=]({{DOMMatrix2DInit/c}}, {{DOMMatrix2DInit/m21}}) is <code>false</code>.
    * {{DOMMatrix2DInit/d}} and {{DOMMatrix2DInit/m22}} are both present and
        [=SameValueZero=]({{DOMMatrix2DInit/d}}, {{DOMMatrix2DInit/m22}}) is <code>false</code>.
    * {{DOMMatrix2DInit/e}} and {{DOMMatrix2DInit/m41}} are both present and
        [=SameValueZero=]({{DOMMatrix2DInit/e}}, {{DOMMatrix2DInit/m41}}) is <code>false</code>.
    * {{DOMMatrix2DInit/f}} and {{DOMMatrix2DInit/m42}} are both present and
        [=SameValueZero=]({{DOMMatrix2DInit/f}}, {{DOMMatrix2DInit/m42}}) is <code>false</code>.
2. If {{DOMMatrix2DInit/m11}} is not present then set it to the value of member
    {{DOMMatrix2DInit/a}}, or value ''1'' if {{DOMMatrix2DInit/a}} is also not present.
3. If {{DOMMatrix2DInit/m12}} is not present then set it to the value of member
    {{DOMMatrix2DInit/b}}, or value ''0'' if {{DOMMatrix2DInit/b}} is also not present.
4. If {{DOMMatrix2DInit/m21}} is not present then set it to the value of member
    {{DOMMatrix2DInit/c}}, or value ''0'' if {{DOMMatrix2DInit/c}} is also not present.
5. If {{DOMMatrix2DInit/m22}} is not present then set it to the value of member
    {{DOMMatrix2DInit/d}}, or value ''1'' if {{DOMMatrix2DInit/d}} is also not present.
6. If {{DOMMatrix2DInit/m41}} is not present then set it to the value of member
    {{DOMMatrix2DInit/e}}, or value ''0'' if {{DOMMatrix2DInit/e}} is also not present.
7. If {{DOMMatrix2DInit/m42}} is not present then set it to the value of member
    {{DOMMatrix2DInit/f}}, or value ''0'' if {{DOMMatrix2DInit/f}} is also not present.

Note: The [=SameValueZero=] comparison algorithm returns <code>true</code> for two ''NaN''
values, and also for ''0'' and ''-0''. [[!ECMA-262]]

To <dfn dfn-for=matrix>validate and fixup</dfn> a {{DOMMatrixInit}} dictionary <var>dict</var>,
run the following steps:

1. <a for=matrix>Validate and fixup (2D)</a> <var>dict</var>.</p>
2. If {{DOMMatrixInit/is2D}} is <code>true</code> and: at least one of {{DOMMatrixInit/m13}},
    {{DOMMatrixInit/m14}}, {{DOMMatrixInit/m23}}, {{DOMMatrixInit/m24}}, {{DOMMatrixInit/m31}},
    {{DOMMatrixInit/m32}}, {{DOMMatrixInit/m34}}, {{DOMMatrixInit/m43}} are present with a value other
    than ''0'' or ''-0'', or at least one of {{DOMMatrixInit/m33}}, {{DOMMatrixInit/m44}} are present
    with a value other than ''1'', then throw a {{TypeError}} exception and abort these steps.
3. If {{DOMMatrixInit/is2D}} is not present and at least one of {{DOMMatrixInit/m13}},
    {{DOMMatrixInit/m14}}, {{DOMMatrixInit/m23}}, {{DOMMatrixInit/m24}}, {{DOMMatrixInit/m31}},
    {{DOMMatrixInit/m32}}, {{DOMMatrixInit/m34}}, {{DOMMatrixInit/m43}} are present with a value other
    than ''0'' or ''-0'', or at least one of {{DOMMatrixInit/m33}}, {{DOMMatrixInit/m44}} are present
    with a value other than ''1'', set {{DOMMatrixInit/is2D}} to <code>false</code>.
4. If {{DOMMatrixInit/is2D}} is still not present, set it to <code>true</code>.


<h3 id=dommatrix-parse algorithm>Parsing a string into an abstract matrix</h3>

To <dfn>parse a string into an abstract matrix</dfn>, given a string <var>transformList</var>,
means to run the following steps. It will either return a <a>4x4 abstract matrix</a> and a boolean
<var>2dTransform</var>, or failure.

1. If <var>transformList</var> is the empty string, set it to the string "<code>matrix(1, 0, 0,
    1, 0, 0)</code>".
2. <a for=CSS>Parse</a> <var>transformList</var> into <var>parsedValue</var> given the grammar
    for the CSS 'transform' property. The result will be a <<transform-list>>, the keyword
    ''transform/none'', or failure. If <var>parsedValue</var> is failure, or any <<transform-function>>
    has <<length>> values without <a spec=css-values>absolute length</a> units, or any keyword other
    than ''transform/none'' is used, then return failure. [[!CSS3-SYNTAX]] [[!CSS3-TRANSFORMS]]
3. If <var>parsedValue</var> is ''transform/none'', set <var>parsedValue</var> to a
    <<transform-list>> containing a single identity matrix.
4. Let <var>2dTransform</var> track the 2D/3D dimension status of <var>parsedValue</var>.
    <dl class=switch>
        : If <var>parsedValue</var> consists of any <a
            href="https://drafts.csswg.org/css-transforms-1/#transform-primitives">three-dimensional
            transform functions</a>
        ::
            Set <var>2dTransform</var> to <code>false</code>.
        : Otherwise
        ::
            Set <var>2dTransform</var> to <code>true</code>.
    </dl>
5. Transform all <<transform-function>>s to <a lt="4x4 abstract matrix">4x4 abstract
    matrices</a> by following the “<a
    href=https://drafts.csswg.org/css-transforms-1/#mathematical-description>Mathematical Description
    of Transform Functions</a>”. [[!CSS3-TRANSFORMS]]
6. Let <var>matrix</var> be a <a>4x4 abstract matrix</a> as shown in the initial
    figure of this section. <a>Post-multiply</a> all matrices from left to right and set
    <var>matrix</var> to this product.
7. Return <var>matrix</var> and <var>2dTransform</var>.


Creating DOMMatrixReadOnly and DOMMatrix objects {#dommatrix-create}
--------------------------------------------------------------------

To <dfn>create a 2d matrix</dfn> of type <var>type</var> being either {{DOMMatrixReadOnly}} or
{{DOMMatrix}}, with a sequence <var>init</var> of 6 elements, follow these steps:

1. Let <var>matrix</var> be a new instance of <var>type</var>.
2. Set <a for=matrix>m11 element</a>, <a for=matrix>m12 element</a>, <a for=matrix>m21
    element</a>, <a for=matrix>m22 element</a>, <a for=matrix>m41 element</a> and <a for=matrix>m42
    element</a> to the values of <var>init</var> in order starting with the first value.
3. Set <a for=matrix>m13 element</a>, <a for=matrix>m14 element</a>, <a for=matrix>m23
    element</a>, <a for=matrix>m24 element</a>, <a for=matrix>m31 element</a>, <a for=matrix>m32
    element</a>, <a for=matrix>m34 element</a>, and <a for=matrix>m43 element</a> to ''0''.
4. Set <a for=matrix>m33 element</a> and <a for=matrix>m44 element</a> to ''1''.
5. Set <a for=matrix>is 2D</a> to <code>true</code>.
6. Return <var>matrix</var>

To <dfn>create a 3d matrix</dfn> with <var>type</var> being either {{DOMMatrixReadOnly}} or
{{DOMMatrix}}, with a sequence <var>init</var> of 16 elements, follow these steps:

1. Let <var>matrix</var> be a new instance of <var>type</var>.
2. Set <a for=matrix>m11 element</a> to <a for=matrix>m44 element</a> to the values of
    <var>init</var> in column-major order.
3. Set <a for=matrix>is 2D</a> to <code>false</code>.
4. Return <var>matrix</var>

The <dfn dfn-type=constructor
dfn-for=DOMMatrixReadOnly><code>DOMMatrixReadOnly(<var>init</var>)</code></dfn> and the <dfn
dfn-type=constructor dfn-for=DOMMatrix><code>DOMMatrix(<var>init</var>)</code></dfn> constructors
must follow these steps:

<dl class=switch>
    : If <var>init</var> is omitted
    ::
        Return the result of invoking <a>create a 2d matrix</a> of type {{DOMMatrixReadOnly}} or
        {{DOMMatrix}} as appropriate, with the sequence [''1'', ''0'', ''0'', ''1'', ''0'', ''0''].
    : If <var>init</var> is a {{DOMString}}
    ::
        1. If <a>current global object</a> is not a {{Window}} object, then throw a {{TypeError}}
            exception.
        2. <a lt="parse a string into an abstract matrix">Parse <var>init</var> into an abstract
            matrix</a>, and let <var>matrix</var> and <var>2dTransform</var> be the result. If the result is
            failure, then throw a "{{SyntaxError}}" {{DOMException}}.
        3. <dl class=switch>
            : If <var>2dTransform</var> is <code>true</code>
            ::
                Return the result of invoking <a>create a 2d matrix</a> of type {{DOMMatrixReadOnly}} or
                {{DOMMatrix}} as appropriate, with a sequence of numbers, the values being the elements <var
                ignore>m11</var>, <var ignore>m12</var>, <var ignore>m21</var>, <var ignore>m22</var>, <var
                ignore>m41</var> and <var ignore>m42</var> of <var>matrix</var>.
            : Otherwise
            ::
                Return the result of invoking <a>create a 3d matrix</a> of type {{DOMMatrixReadOnly}} or
                {{DOMMatrix}} as appropriate, with a sequence of numbers, the values being the 16 elements of
                <var>matrix</var>.
    : If <var>init</var> is a sequence with 6 elements
    ::
        Return the result of invoking <a>create a 2d matrix</a> of type {{DOMMatrixReadOnly}} or
        {{DOMMatrix}} as appropriate, with the sequence <var>init</var>.
    : If <var>init</var> is a sequence with 16 elements
    ::
        Return the result of invoking <a>create a 3d matrix</a> of type {{DOMMatrixReadOnly}} or
        {{DOMMatrix}} as appropriate, with the sequence <var>init</var>.
    : Otherwise
    ::
        Throw a {{TypeError}} exception.
</dl>

The <dfn method lt=fromMatrix() dfn-for=DOMMatrixReadOnly
id=dom-dommatrixreadonly-frommatrix><code>fromMatrix(<var>other</var>)</code></dfn> static method on
{{DOMMatrixReadOnly}} must <a>create a <code>DOMMatrixReadOnly</code> from the dictionary</a>
<var>other</var>.

The <dfn method lt=fromMatrix() dfn-for=DOMMatrix
id=dom-dommatrix-frommatrix><code>fromMatrix(<var>other</var>)</code></dfn> static method on
{{DOMMatrix}} must <a>create a <code>DOMMatrix</code> from the dictionary</a> <var>other</var>.

To <dfn export lt="create a DOMMatrixReadOnly from the 2D dictionary">create a
<code>DOMMatrixReadOnly</code> from a 2D dictionary</dfn> <var>other</var> or to <dfn lt="create a
DOMMatrix from the 2D dictionary" export>create a <code>DOMMatrix</code> from a 2D dictionary</dfn>
<var>other</var>, follow these steps:

1. <a for=matrix>Validate and fixup (2D)</a> <var>other</var>.
2. Return the result of invoking <a>create a 2d matrix</a> of type {{DOMMatrixReadOnly}} or
    {{DOMMatrix}} as appropriate, with a sequence of numbers, the values being the 6 elements
    {{DOMMatrix2DInit/m11}}, {{DOMMatrix2DInit/m12}}, {{DOMMatrix2DInit/m21}}, {{DOMMatrix2DInit/m22}},
    {{DOMMatrix2DInit/m41}} and {{DOMMatrix2DInit/m42}} of <var>other</var> in the given order.

To <dfn export lt="create a DOMMatrixReadOnly from the dictionary">create a
<code>DOMMatrixReadOnly</code> from a dictionary</dfn> <var>other</var> or to <dfn lt="create a
DOMMatrix from the dictionary">create a <code>DOMMatrix</code> from a dictionary</dfn>
<var>other</var>, follow these steps:

1. <a for=matrix>Validate and fixup</a> <var>other</var>.
2. <dl class=switch>
        : If the {{DOMMatrixInit/is2D}} dictionary member of <var>other</var> is <code>true</code>
        ::
            Return the result of invoking <a>create a 2d matrix</a> of type {{DOMMatrixReadOnly}} or
            {{DOMMatrix}} as appropriate, with a sequence of numbers, the values being the 6 elements
            {{DOMMatrix2DInit/m11}}, {{DOMMatrix2DInit/m12}}, {{DOMMatrix2DInit/m21}}, {{DOMMatrix2DInit/m22}},
            {{DOMMatrix2DInit/m41}} and {{DOMMatrix2DInit/m42}} of <var>other</var> in the given order.
        : Otherwise
        ::
            Return the result of invoking <a>create a 3d matrix</a> of type {{DOMMatrixReadOnly}} or
            {{DOMMatrix}} as appropriate, with a sequence of numbers, the values being the 16 elements
            {{DOMMatrix2DInit/m11}}, {{DOMMatrix2DInit/m12}}, {{DOMMatrixInit/m13}}, ..., {{DOMMatrixInit/m44}}
            of <var>other</var> in the given order.
    </dl>

The <dfn method dfn-for=DOMMatrixReadOnly
id=dom-dommatrixreadonly-fromfloat32array><code>fromFloat32Array(<var>array32</var>)</code></dfn>
static method on {{DOMMatrixReadOnly}} and the <dfn method dfn-for=DOMMatrix
id=dom-dommatrix-fromfloat32array><code>fromFloat32Array(<var>array32</var>)</code></dfn> static
method on {{DOMMatrix}} must follow these steps:

<dl class=switch>
    : If <var>array32</var> has 6 elements
    ::
        Return the result of invoking <a>create a 2d matrix</a> of type {{DOMMatrixReadOnly}} or
        {{DOMMatrix}} as appropriate, with a sequence of numbers taking the values from <var>array32</var>
        in the provided order.
    : If <var>array32</var> has 16 elements
    ::
        Return the result of invoking <a>create a 3d matrix</a> of type {{DOMMatrixReadOnly}} or
        {{DOMMatrix}} as appropriate, with a sequence of numbers taking the values from <var>array32</var>
        in the provided order.
    : Otherwise
    ::
        Throw a {{TypeError}} exception.
</dl>

The <dfn method dfn-for=DOMMatrixReadOnly
id=dom-dommatrixreadonly-fromfloat64array><code>fromFloat64Array(<var>array64</var>)</code></dfn>
static method on {{DOMMatrixReadOnly}} and the <dfn method dfn-for=DOMMatrix
id=dom-dommatrix-fromfloat64array><code>fromFloat64Array(<var>array64</var>)</code></dfn> static
method on {{DOMMatrix}} must follow these steps:

<dl class=switch>
    : If <var>array64</var> has 6 elements
    ::
        Return the result of invoking <a>create a 2d matrix</a> of type {{DOMMatrixReadOnly}} or
        {{DOMMatrix}} as appropriate, with a sequence of numbers taking the values from <var>array64</var>
        in the provided order.
    : If <var>array32</var> has 16 elements
    ::
        Return the result of invoking <a>create a 3d matrix</a> of type {{DOMMatrixReadOnly}} or
        {{DOMMatrix}} as appropriate, with a sequence of numbers taking the values from <var>array64</var>
        in the provided order.
    : Otherwise
    ::
        Throw a {{TypeError}} exception.
</dl>


DOMMatrix attributes {#dommatrix-attributes}
--------------------------------------------

The following attributes {{DOMMatrixReadOnly/m11}} to {{DOMMatrixReadOnly/m44}} correspond to the
16 items of the matrix interfaces.

<div dfn-type=attribute dfn-for="DOMMatrixReadOnly, DOMMatrix">
The <dfn><code>m11</code></dfn> and <dfn><code>a</code></dfn> attributes, on getting, must
return the <a for=matrix>m11 element</a> value. For the {{DOMMatrix}} interface, setting the
{{DOMMatrix/m11}} or the {{DOMMatrix/a}} attribute must set the <a for=matrix>m11 element</a> to
the new value.

The <dfn><code>m12</code></dfn> and <dfn><code>b</code></dfn> attributes, on getting, must
return the <a for=matrix>m12 element</a> value. For the {{DOMMatrix}} interface, setting the
{{DOMMatrix/m12}} or the {{DOMMatrix/b}} attribute must set the <a for=matrix>m12 element</a> to
the new value.

The <dfn><code>m13</code></dfn> attribute, on getting, must return the <a for=matrix>m13
element</a> value. For the {{DOMMatrix}} interface, setting the {{DOMMatrix/m13}} attribute must
set the <a for=matrix>m13 element</a> to the new value and, if the new value is not ''0'' or
''-0'', set <a for=matrix>is 2D</a> to <code>false</code>.

The <dfn><code>m14</code></dfn> attribute, on getting, must return the <a for=matrix>m14
element</a> value. For the {{DOMMatrix}} interface, setting the {{DOMMatrix/m14}} attribute must
set the <a for=matrix>m14 element</a> to the new value and, if the new value is not ''0'' or
''-0'', set <a for=matrix>is 2D</a> to <code>false</code>.

The <dfn><code>m21</code></dfn> and <dfn><code>c</code></dfn> attributes, on getting, must
return the <a for=matrix>m21 element</a> value. For the {{DOMMatrix}} interface, setting the
{{DOMMatrix/m21}} or the {{DOMMatrix/c}} attribute must set the <a for=matrix>m21 element</a> to
the new value.

The <dfn><code>m22</code></dfn> and <dfn><code>d</code></dfn> attributes, on getting, must
return the <a for=matrix>m22 element</a> value. For the {{DOMMatrix}} interface, setting the
{{DOMMatrix/m22}} or the {{DOMMatrix/d}} attribute must set the <a for=matrix>m22 element</a> to
the new value.

The <dfn><code>m23</code></dfn> attribute, on getting, must return the <a for=matrix>m23
element</a> value. For the {{DOMMatrix}} interface, setting the {{DOMMatrix/m23}} attribute must
set the <a for=matrix>m23 element</a> to the new value and, if the new value is not ''0'' or
''-0'', set <a for=matrix>is 2D</a> to <code>false</code>.

The <dfn><code>m24</code></dfn> attribute, on getting, must return the <a for=matrix>m24
element</a> value. For the {{DOMMatrix}} interface, setting the {{DOMMatrix/m24}} attribute must
set the <a for=matrix>m24 element</a> to the new value and, if the new value is not ''0'' or
''-0'', set <a for=matrix>is 2D</a> to <code>false</code>.

The <dfn><code>m31</code></dfn> attribute, on getting, must return the <a for=matrix>m31
element</a> value. For the {{DOMMatrix}} interface, setting the {{DOMMatrix/m31}} attribute must
set the <a for=matrix>m31 element</a> to the new value and, if the new value is not ''0'' or
''-0'', set <a for=matrix>is 2D</a> to <code>false</code>.

The <dfn><code>m32</code></dfn> attribute, on getting, must return the <a for=matrix>m32
element</a> value. For the {{DOMMatrix}} interface, setting the {{DOMMatrix/m32}} attribute must
set the <a for=matrix>m32 element</a> to the new value and, if the new value is not ''0'' or
''-0'', set <a for=matrix>is 2D</a> to <code>false</code>.

The <dfn><code>m33</code></dfn> attribute, on getting, must return the <a for=matrix>m33
element</a> value. For the {{DOMMatrix}} interface, setting the {{DOMMatrix/m33}} attribute must
set the <a for=matrix>m33 element</a> to the new value and, if the new value is not ''1'', set <a
for=matrix>is 2D</a> to <code>false</code>.

The <dfn><code>m34</code></dfn> attribute, on getting, must return the <a for=matrix>m34
element</a> value. For the {{DOMMatrix}} interface, setting the {{DOMMatrix/m34}} attribute must
set the <a for=matrix>m34 element</a> to the new value and, if the new value is not ''0'' or
''-0'', set <a for=matrix>is 2D</a> to <code>false</code>.

The <dfn><code>m41</code></dfn> and <dfn><code>e</code></dfn> attributes, on getting, must
return the <a for=matrix>m41 element</a> value. For the {{DOMMatrix}} interface, setting the
{{DOMMatrix/m41}} or the {{DOMMatrix/e}} attribute must set the <a for=matrix>m41 element</a> to
the new value.

The <dfn><code>m42</code></dfn> and <dfn><code>f</code></dfn> attributes, on getting, must
return the <a for=matrix>m42 element</a> value. For the {{DOMMatrix}} interface, setting the
{{DOMMatrix/m42}} or the {{DOMMatrix/f}} attribute must set the <a for=matrix>m42 element</a> to
the new value.

The <dfn><code>m43</code></dfn> attribute, on getting, must return the <a for=matrix>m43
element</a> value. For the {{DOMMatrix}} interface, setting the {{DOMMatrix/m43}} attribute must
set the <a for=matrix>m43 element</a> to the new value and, if the new value is not ''0'' or
''-0'', set <a for=matrix>is 2D</a> to <code>false</code>.

The <dfn><code>m44</code></dfn> attribute, on getting, must return the <a for=matrix>m44
element</a> value. For the {{DOMMatrix}} interface, setting the {{DOMMatrix/m44}} attribute must
set the <a for=matrix>m44 element</a> to the new value and, if the new value is not ''1'', set <a
for=matrix>is 2D</a> to <code>false</code>.
</div>

<div class=note>
The following attributes {{DOMMatrixReadOnly/a}} to {{DOMMatrixReadOnly/f}} correspond to the 2D
components of the matrix interfaces.

The {{DOMMatrixReadOnly/a}} attribute is an alias to the {{DOMMatrixReadOnly/m11}} attribute.

The {{DOMMatrixReadOnly/b}} attribute is an alias to the {{DOMMatrixReadOnly/m12}} attribute.

The {{DOMMatrixReadOnly/c}} attribute is an alias to the {{DOMMatrixReadOnly/m21}} attribute.

The {{DOMMatrixReadOnly/d}} attribute is an alias to the {{DOMMatrixReadOnly/m22}} attribute.

The {{DOMMatrixReadOnly/e}} attribute is an alias to the {{DOMMatrixReadOnly/m41}} attribute.

The {{DOMMatrixReadOnly/f}} attribute is an alias to the {{DOMMatrixReadOnly/m42}} attribute.
</div>

The following attributes provide status information about {{DOMMatrixReadOnly}}.

<div dfn-type=attribute dfn-for=DOMMatrixReadOnly>
The <dfn><code>is2D</code></dfn> attribute must return the value of <a for=matrix>is 2D</a>.

The <dfn><code>isIdentity</code></dfn> attribute must return <code>true</code> if <a
for=matrix>m12 element</a>, <a for=matrix>m13 element</a>, <a for=matrix>m14 element</a>, <a
for=matrix>m21 element</a>, <a for=matrix>m23 element</a>, <a for=matrix>m24 element</a>, <a
for=matrix>m31 element</a>, <a for=matrix>m32 element</a>, <a for=matrix>m34 element</a>, <a
for=matrix>m41 element</a>, <a for=matrix>m42 element</a>, <a for=matrix>m43 element</a> are ''0''
or ''-0'' and <a for=matrix>m11 element</a>, <a for=matrix>m22 element</a>, <a for=matrix>m33
element</a>, <a for=matrix>m44 element</a> are ''1''. Otherwise it must return <code>false</code>.
</div>

Every {{DOMMatrixReadOnly}} object must be flagged with a boolean <dfn for=matrix
export>is 2D</dfn>. This flag indicates that:

1. The current matrix was initialized as a 2D matrix. See individual <a
    href="#dommatrix-create">creators</a> for more details.
2. Only 2D transformation operations were applied. Each <a
    href="#mutable-transformation-methods">mutable</a> or <a
    href="#immutable-transformation-methods">immutable transformation method</a> defines if <a
    for=matrix>is 2D</a> must be set to <code>false</code>.

Note: <a for=matrix>Is 2D</a> can never be set to <code>true</code> when it was set to
<code>false</code> before on a {{DOMMatrix}} object with the exception of calling the
{{DOMMatrix/setMatrixValue()}} method.


Immutable transformation methods {#immutable-transformation-methods}
--------------------------------------------------------------------

The following methods do not modify the current matrix and return a new {{DOMMatrix}} object.

<dl dfn-type=method dfn-for=DOMMatrixReadOnly>
    : <dfn>translate(<var>tx</var>, <var>ty</var>, <var>tz</var>)</dfn>
    ::
        1. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        2. Perform a {{DOMMatrix/translateSelf()}} transformation on <var>result</var> with the
            arguments <var>tx</var>, <var>ty</var>, <var>tz</var>.
        3. Return <var>result</var>.

        The current matrix is not modified.
    : <dfn>scale(<var>scaleX</var>, <var>scaleY</var>, <var>scaleZ</var>, <var>originX</var>,
        <var>originY</var>, <var>originZ</var>)</dfn>
    ::
        1. If <var>scaleY</var> is missing, set <var>scaleY</var> to the value of <var>scaleX</var>.
        2. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        3. Perform a {{DOMMatrix/scaleSelf()}} transformation on <var>result</var> with the arguments
            <var>scaleX</var>, <var>scaleY</var>, <var>scaleZ</var>, <var>originX</var>,
            <var>originY</var>, <var>originZ</var>.
        4. Return <var>result</var>.

        The current matrix is not modified.
    : <dfn>scaleNonUniform(<var>scaleX</var>, <var>scaleY</var>)</dfn>
    ::
        Note: Supported for legacy reasons to be compatible with {{SVGMatrix}} as defined in SVG 1.1 [[SVG11]]. Authors are encouraged to use {{scale()}} instead.
        1. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        2. Perform a {{DOMMatrix/scaleSelf()}} transformation on <var>result</var> with the arguments
            <var>scaleX</var>, <var>scaleY</var>, <i>1</i>, <i>0</i>,
            <i>0</i>, <i>0</i>.
        3. Return <var>result</var>.

        The current matrix is not modified.
    : <dfn>scale3d(<var>scale</var>, <var>originX</var>, <var>originY</var>, <var>originZ</var>)</dfn>
    ::
        1. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        2. Perform a {{DOMMatrix/scale3dSelf()}} transformation on <var>result</var> with the
            arguments <var>scale</var>, <var>originX</var>, <var>originY</var>, <var>originZ</var>.
        3. Return <var>result</var>.

        The current matrix is not modified.
    : <dfn>rotate(<var>rotX</var>, <var>rotY</var>, <var>rotZ</var>)</dfn>
    ::
        1. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        2. Perform a {{DOMMatrix/rotateSelf()}} transformation on <var>result</var> with the
            arguments <var>rotX</var>, <var>rotY</var>, <var>rotZ</var>.
        3. Return <var>result</var>.

        The current matrix is not modified.
    : <dfn>rotateFromVector(<var>x</var>, <var>y</var>)</dfn>
    ::
        1. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        2. Perform a {{DOMMatrix/rotateFromVectorSelf()}} transformation on <var>result</var> with
            the arguments <var>x</var>, <var>y</var>.
        3. Return <var>result</var>.

        The current matrix is not modified.
    : <dfn>rotateAxisAngle(<var>x</var>, <var>y</var>, <var>z</var>, <var>angle</var>)</dfn>
    ::
        1. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        2. Perform a {{DOMMatrix/rotateAxisAngleSelf()}} transformation on <var>result</var> with the
            arguments <var>x</var>, <var>y</var>, <var>z</var>, <var>angle</var>.
        3. Return <var>result</var>.

        The current matrix is not modified.
    : <dfn>skewX(<var>sx</var>)</dfn>
    ::
        1. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        2. Perform a {{DOMMatrix/skewXSelf()}} transformation on <var>result</var> with the argument
            <var>sx</var>.
        3. Return <var>result</var>.

        The current matrix is not modified.
    : <dfn>skewY(<var>sy</var>)</dfn>
    ::
        1. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        2. Perform a {{DOMMatrix/skewYSelf()}} transformation on <var>result</var> with the argument
            <var>sy</var>.
        3. Return <var>result</var>.

        The current matrix is not modified.
    : <dfn>multiply(<var>other</var>)</dfn>
    ::
        1. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        2. Perform a {{DOMMatrix/multiplySelf()}} transformation on <var>result</var> with the
            argument <var>other</var>.
        3. Return <var>result</var>.

        The current matrix is not modified.
    : <dfn>flipX()</dfn>
    ::
        1. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        2. <a>Post-multiply</a> <var>result</var> with <code>new DOMMatrix([-1, 0, 0, 1, 0,
            0])</code>.
        3. Return <var>result</var>.

        The current matrix is not modified.
    : <dfn>flipY()</dfn>
    ::
        1. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        2. <a>Post-multiply</a> <var>result</var> with <code>new DOMMatrix([1, 0, 0, -1, 0,
            0])</code>.
        3. Return <var>result</var>.

        The current matrix is not modified.
    : <dfn>inverse()</dfn>
    ::
        1. Let <var>result</var> be the resulting matrix initialized to the values of the current
            matrix.
        2. Perform a {{DOMMatrix/invertSelf()}} transformation on <var>result</var>.
        3. Return <var>result</var>.

        The current matrix is not modified.
</dl>

The following methods do not modify the current matrix.

<dl dfn-type=method dfn-for=DOMMatrixReadOnly>
    : <dfn>transformPoint(<var>point</var>)</dfn>
    ::
        Let <var>pointObject</var> be the result of invoking <a>create a <code>DOMPoint</code> from the
        dictionary</a> <var>point</var>. Return the result of invoking <a>transform a point with a
        matrix</a>, given <var>pointObject</var> and the current matrix. The passed argument does not get
        modified.
    : <dfn>toFloat32Array()</dfn>
    ::
        Returns the serialized 16 elements {{DOMMatrixReadOnly/m11}} to {{DOMMatrixReadOnly/m44}} of
        the current matrix in column-major order as {{Float32Array}}.
    : <dfn>toFloat64Array()</dfn>
    ::
        Returns the serialized 16 elements {{DOMMatrixReadOnly/m11}} to {{DOMMatrixReadOnly/m44}} of
        the current matrix in column-major order as {{Float64Array}}.
    : <dfn dfn>stringification behavior</dfn>
    ::
        1. If one or more of <a for=matrix>m11 element</a> through <a for=matrix>m44 element</a> are a
            non-finite value, then throw an "{{InvalidStateError}}" {{DOMException}}.

            Note: The CSS syntax cannot represent ''NaN'' or ''Infinity'' values.
        2. Let <var>string</var> be the empty string.
        3. If <a for=matrix>is 2D</a> is <code>true</code>, then:
            1. Append "<code>matrix(</code>" to <var>string</var>.
            2. Append [=!=] [=ToString=](<a for=matrix>m11 element</a>) to <var>string</var>.
            3. Append "<code>, </code>" to <var>string</var>.
            4. Append [=!=] [=ToString=](<a for=matrix>m12 element</a>) to <var>string</var>.
            5. Append "<code>, </code>" to <var>string</var>.
            6. Append [=!=] [=ToString=](<a for=matrix>m21 element</a>) to <var>string</var>.
            7. Append "<code>, </code>" to <var>string</var>.
            8. Append [=!=] [=ToString=](<a for=matrix>m22 element</a>) to <var>string</var>.
            9. Append "<code>, </code>" to <var>string</var>.
            10. Append [=!=] [=ToString=](<a for=matrix>m41 element</a>) to <var>string</var>.
            11. Append "<code>, </code>" to <var>string</var>.
            12. Append [=!=] [=ToString=](<a for=matrix>m42 element</a>) to <var>string</var>.
            13. Append "<code>)</code>" to <var>string</var>.

            Note: The string will be in the form of a a CSS Transforms <<matrix()>> function.
            [[CSS3-TRANSFORMS]]
        4. Otherwise:
            1. Append "<code>matrix3d(</code>" to <var>string</var>.
            2. Append [=!=] [=ToString=](<a for=matrix>m11 element</a>) to <var>string</var>.
            3. Append "<code>, </code>" to <var>string</var>.
            4. Append [=!=] [=ToString=](<a for=matrix>m12 element</a>) to <var>string</var>.
            5. Append "<code>, </code>" to <var>string</var>.
            6. Append [=!=] [=ToString=](<a for=matrix>m13 element</a>) to <var>string</var>.
            7. Append "<code>, </code>" to <var>string</var>.
            8. Append [=!=] [=ToString=](<a for=matrix>m14 element</a>) to <var>string</var>.
            9. Append "<code>, </code>" to <var>string</var>.
            10. Append [=!=] [=ToString=](<a for=matrix>m21 element</a>) to <var>string</var>.
            11. Append "<code>, </code>" to <var>string</var>.
            12. Append [=!=] [=ToString=](<a for=matrix>m22 element</a>) to <var>string</var>.
            13. Append "<code>, </code>" to <var>string</var>.
            14. Append [=!=] [=ToString=](<a for=matrix>m23 element</a>) to <var>string</var>.
            15. Append "<code>, </code>" to <var>string</var>.
            16. Append [=!=] [=ToString=](<a for=matrix>m24 element</a>) to <var>string</var>.
            17. Append "<code>, </code>" to <var>string</var>.
            18. Append [=!=] [=ToString=](<a for=matrix>m41 element</a>) to <var>string</var>.
            19. Append "<code>, </code>" to <var>string</var>.
            20. Append [=!=] [=ToString=](<a for=matrix>m42 element</a>) to <var>string</var>.
            21. Append "<code>, </code>" to <var>string</var>.
            22. Append [=!=] [=ToString=](<a for=matrix>m43 element</a>) to <var>string</var>.
            23. Append "<code>, </code>" to <var>string</var>.
            24. Append [=!=] [=ToString=](<a for=matrix>m44 element</a>) to <var>string</var>.
            25. Append "<code>)</code>" to <var>string</var>.

            Note: The string will be in the form of a a CSS Transforms <<matrix3d()>> function.
            [[CSS3-TRANSFORMS]]
        5. Return <var>string</var>.
</dl>

<div class=example>
In this example, a matrix is created and several 2D transformation methods are called:

<pre><code highlight=javascript>
var matrix = new DOMMatrix();
matrix.scaleSelf(2);
matrix.translateSelf(20,20);
console.assert(matrix.toString() ===
                "matrix(2, 0, 0, 2, 40, 40)");
</code></pre>
</div>

<div class=example>
In the following example, a matrix is created and several 3D transformation methods are called:

<pre><code highlight=javascript>
var matrix = new DOMMatrix();
matrix.scale3dSelf(2);
console.assert(matrix.toString() ===
                "matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1)");
</code></pre>

For 3D operations, the stringifier returns a string representing a 3D matrix.
</div>

<div class=example>
This example will throw an exception because there are non-finite values in the matrix.

<pre><code highlight=javascript>
var matrix = new DOMMatrix([NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN]);
var string = matrix + " Batman!";
</code></pre>
</div>


Mutable transformation methods {#mutable-transformation-methods}
----------------------------------------------------------------

The following methods modify the current matrix, so that each method returns the matrix where it
was invoked on. The primary benefit of this is allowing content creators to chain method calls.

<div class=example>
The following code example:

<pre><code highlight=javascript>
var matrix = new DOMMatrix();
matrix.translateSelf(20, 20);
matrix.scaleSelf(2);
matrix.translateSelf(-20, -20);
</code></pre>

is equivalent to:

<pre><code highlight=javascript>
var matrix = new DOMMatrix();
matrix.translateSelf(20, 20).scaleSelf(2).translateSelf(-20, -20);
</code></pre>
</div>

Note: Authors who use chained method calls are advised to use mutable transformation methods
to avoid unnecessary memory allocations due to creation of intermediate {{DOMMatrix}} objects in
user agents.

<dl dfn-type=method dfn-for=DOMMatrix>
    : <dfn>multiplySelf(<var>other</var>)</dfn>
    ::
        1. Let <var>otherObject</var> be the result of invoking <a>create a <code>DOMMatrix</code>
            from the dictionary</a> <var>other</var>.
        2. The <var>otherObject</var> matrix gets post-multiplied to the current matrix.
        3. If <a for=matrix>is 2D</a> of <var>otherObject</var> is <code>false</code>, set <a
            for=matrix>is 2D</a> of the current matrix to <code>false</code>.
        4. Return the current matrix.
    : <dfn>preMultiplySelf(<var>other</var>)</dfn>
    ::
        1. Let <var>otherObject</var> be the result of invoking <a>create a <code>DOMMatrix</code>
            from the dictionary</a> <var>other</var>.
        2. The <var>otherObject</var> matrix gets pre-multiplied to the current matrix.
        3. If <a for=matrix>is 2D</a> of <var>otherObject</var> is <code>false</code>, set <a
            for=matrix>is 2D</a> of the current matrix to <code>false</code>.
        4. Return the current matrix.
    : <dfn>translateSelf(<var>tx</var>, <var>ty</var>, <var>tz</var>)</dfn>
    ::
        1. <a>Post-multiply</a> a translation transformation on the current matrix. The 3D
            translation matrix is <a
            href="https://drafts.csswg.org/css-transforms-1/#TranslateDefined">described</a> in CSS
            Transforms. [[!CSS3-TRANSFORMS]]
        2. If <var>tz</var> is specified and not ''0'' or ''-0'', set <a for=matrix>is 2D</a> of the
            current matrix to <code>false</code>.
        3. Return the current matrix.
    :
        <dfn>scaleSelf(<var>scaleX</var>, <var>scaleY</var>, <var>scaleZ</var>, <var>originX</var>,
        <var>originY</var>, <var>originZ</var>)</dfn>
    ::
        1. Perform a {{DOMMatrix/translateSelf()}} transformation on the current matrix with the
            arguments <var>originX</var>, <var>originY</var>, <var>originZ</var>.
        2. If <var>scaleY</var> is missing, set <var>scaleY</var> to the value of <var>scaleX</var>.
        3. <a>Post-multiply</a> a non-uniform scale transformation on the current matrix. The 3D
            scale matrix is <a href="https://drafts.csswg.org/css-transforms-1/#ScaleDefined">described</a>
            in CSS Transforms with <var>sx</var> = <var>scaleX</var>,  <var>sy</var> = <var>scaleY</var> and
            <var>sz</var> = <var>scaleZ</var>. [[!CSS3-TRANSFORMS]]
        4. Negate <var>originX</var>, <var>originY</var> and <var>originZ</var>.
        5. Perform a {{DOMMatrix/translateSelf()}}</a> transformation on the current matrix with the
            arguments <var>originX</var>, <var>originY</var>, <var>originZ</var>.
        6. If <var>scaleZ</var> is not ''1'', set <a
            for=matrix>is 2D</a> of the current matrix to <code>false</code>.
        7. Return the current matrix.
    :
        <dfn>scale3dSelf(<var>scale</var>, <var>originX</var>, <var>originY</var>,
        <var>originZ</var>)</dfn>
    ::
        1. Apply a {{DOMMatrix/translateSelf()}} transformation to the current matrix with the
            arguments <var>originX</var>, <var>originY</var>, <var>originZ</var>.
        2. <a>Post-multiply</a> a uniform 3D scale transformation ({{DOMMatrixReadOnly/m11}} =
            {{DOMMatrixReadOnly/m22}} = {{DOMMatrixReadOnly/m33}} = <var>scale</var>) on the current matrix.
            The 3D scale matrix is <a
            href="https://drafts.csswg.org/css-transforms-1/#ScaleDefined">described</a> in CSS Transforms
            with <var>sx</var> = <var>sy</var> = <var>sz</var> = <var>scale</var>. [[!CSS3-TRANSFORMS]]
        3. Apply a {{DOMMatrix/translateSelf()}} transformation to the current matrix with the
            arguments -<var>originX</var>, -<var>originY</var>, -<var>originZ</var>.
        4. If <var>scale</var> is not ''1'', set <a for=matrix>is 2D</a> of the current matrix to
            <code>false</code>.
        5. Return the current matrix.
    : <dfn>rotateSelf(<var>rotX</var>, <var>rotY</var>, <var>rotZ</var>)</dfn>
    ::
        1. If <var>rotY</var> and <var>rotZ</var> are both missing, set <var>rotZ</var> to the value
            of <var>rotX</var> and set <var>rotX</var> and <var>rotY</var> to ''0''.
        2. If <var>rotY</var> is still missing, set <var>rotY</var> to ''0''.
        3. If <var>rotZ</var> is still missing, set <var>rotZ</var> to ''0''.
        4. If <var>rotX</var> or <var>rotY</var> are not ''0'' or ''-0'', set <a for=matrix>is 2D</a>
            of the current matrix to <code>false</code>.
        5. <a>Post-multiply</a> a rotation transformation on the current matrix around the vector 0,
            0, 1 by the specified rotation <var>rotZ</var> in degrees. The 3D rotation matrix is <a
            href="https://drafts.csswg.org/css-transforms-1/#RotateDefined">described</a> in CSS Transforms
            with <var>alpha</var> = <var>rotZ</var> in degrees. [[!CSS3-TRANSFORMS]]
        6. <a>Post-multiply</a> a rotation transformation on the current matrix around the vector 0,
            1, 0 by the specified rotation <var>rotY</var> in degrees. The 3D rotation matrix is <a
            href="https://drafts.csswg.org/css-transforms-1/#RotateDefined">described</a> in CSS Transforms
            with <var>alpha</var> = <var>rotY</var> in degrees. [[!CSS3-TRANSFORMS]]
        7. <a>Post-multiply</a> a rotation transformation on the current matrix around the vector 1,
            0, 0 by the specified rotation <var>rotX</var> in degrees. The 3D rotation matrix is <a
            href="https://drafts.csswg.org/css-transforms-1/#RotateDefined">described</a> in CSS Transforms
            with <var>alpha</var> = <var>rotX</var> in degrees. [[!CSS3-TRANSFORMS]]
        8. Return the current matrix.
    : <dfn>rotateFromVectorSelf(<var>x</var>, <var>y</var>)</dfn>
    ::
        1. <a>Post-multiply</a> a rotation transformation on the current matrix. The rotation angle
            is determined by the angle between the vector (1,0)<sup>T</sup> and
            (<var>x</var>,<var>y</var>)<sup>T</sup> in the clockwise direction. If <var>x</var> and
            <var>y</var> should both be ''0'' or ''-0'', the angle is specified as ''0''. The 2D rotation
            matrix is <a href="https://drafts.csswg.org/css-transforms-1/#RotateDefined">described</a> in CSS
            Transforms where <code>alpha</code> is the angle between the vector (1,0)<sup>T</sup> and
            (<var>x</var>,<var>y</var>)<sup>T</sup> in degrees. [[!CSS3-TRANSFORMS]]
        2. Return the current matrix.
    : <dfn>rotateAxisAngleSelf(<var>x</var>, <var>y</var>, <var>z</var>, <var>angle</var>)</dfn>
    ::
        1. <a>Post-multiply</a> a rotation transformation on the current matrix around the specified
            vector <var>x</var>, <var>y</var>, <var>z</var> by the specified rotation <var>angle</var> in
            degrees. The 3D rotation matrix is <a
            href="https://drafts.csswg.org/css-transforms-1/#RotateDefined">described</a> in CSS Transforms
            with <var>alpha</var> = <var>angle</var> in degrees. [[!CSS3-TRANSFORMS]]
        2. If <var>x</var> or <var>y</var> are not ''0'' or ''-0'', set <a for=matrix>is 2D</a> of
            the current matrix to <code>false</code>.
        3. Return the current matrix.
    : <dfn>skewXSelf(<var>sx</var>)</dfn>
    ::
        1. <a>Post-multiply</a> a skewX transformation on the current matrix by the specified angle
            <var>sx</var> in degrees. The 2D skewX matrix is <a
            href="https://drafts.csswg.org/css-transforms-1/#SkewXDefined">described</a> in CSS Transforms
            with <var>alpha</var> = <var>sx</var> in degrees. [[!CSS3-TRANSFORMS]]
        2. Return the current matrix.
    : <dfn>skewYSelf(<var>sy</var>)</dfn>
    ::
        1. <a>Post-multiply</a> a skewX transformation on the current matrix by the specified angle
            <var>sy</var> in degrees. The 2D skewY matrix is <a
            href="https://drafts.csswg.org/css-transforms-1/#SkewYDefined">described</a> in CSS Transforms
            with <var ignore>beta</var> = <var>sy</var> in degrees. [[!CSS3-TRANSFORMS]]
        2. Return the current matrix.
    : <dfn>invertSelf()</dfn>
    ::
        1. Invert the current matrix.
        2. If the current matrix is not invertible set all attributes to ''NaN'' and set <a
            for=matrix>is 2D</a> to <code>false</code>.
        3. Return the current matrix.
    : <dfn>setMatrixValue(<var>transformList</var>)</dfn>
    ::
        1. <a lt="parse a string into an abstract matrix">Parse <var>transformList</var> into an
            abstract matrix</a>, and let <var>matrix</var> and <var>2dTransform</var> be the result. If the
            result is failure, then throw a "{{SyntaxError}}" {{DOMException}}.
        2. Set <a for=matrix>is 2D</a> to the value of <var>2dTransform</var>.
        3. Set <a for=matrix>m11 element</a> through <a for=matrix>m44 element</a> to the element
            values of <var>matrix</var> in column-major order.
        4. Return the current matrix.
</dl>


<h2 id="structured-serialization" oldids="cloning">Structured serialization</h2>

{{DOMPointReadOnly}}, {{DOMPoint}}, {{DOMRectReadOnly}}, {{DOMRect}}, {{DOMQuad}},
{{DOMMatrixReadOnly}}, and {{DOMMatrix}} objects are <a>serializable objects</a>. [[!HTML]]

The <a>serialization steps</a> for {{DOMPointReadOnly}} and {{DOMPoint}}, given |value| and
|serialized|, are:

1. Set |serialized|.\[[X]] to |value|'s <a for=point>x coordinate</a>.
2. Set |serialized|.\[[Y]] to |value|'s <a for=point>y coordinate</a>.
3. Set |serialized|.\[[Z]] to |value|'s <a for=point>z coordinate</a>.
4. Set |serialized|.\[[W]] to |value|'s <a for=point>w perspective</a>.

Their <a>deserialization steps</a>, given |serialized| and |value|, are:

1. Set |value|'s <a for=point>x coordinate</a> to |serialized|.\[[X]].
2. Set |value|'s <a for=point>y coordinate</a> to |serialized|.\[[Y]].
3. Set |value|'s <a for=point>z coordinate</a> to |serialized|.\[[Z]].
4. Set |value|'s <a for=point>w perspective</a> to |serialized|.\[[W]].

The <a>serialization steps</a> for {{DOMRectReadOnly}} and {{DOMRect}}, given |value| and
|serialized|, are:

1. Set |serialized|.\[[X]] to |value|'s <a for=rectangle>x coordinate</a>.
2. Set |serialized|.\[[Y]] to |value|'s <a for=rectangle>y coordinate</a>.
3. Set |serialized|.\[[Width]] to |value|'s <a for=rectangle>width dimension</a>.
4. Set |serialized|.\[[Height]] to |value|'s <a for=rectangle>height dimension</a>.

Their <a>deserialization steps</a>, given |serialized| and |value|, are:

1. Set |value|'s <a for=rectangle>x coordinate</a> to |serialized|.\[[X]].
2. Set |value|'s <a for=rectangle>y coordinate</a> to |serialized|.\[[Y]].
3. Set |value|'s <a for=rectangle>width dimension</a> to |serialized|.\[[Width]].
4. Set |value|'s <a for=rectangle>height dimension</a> to |serialized|.\[[Height]].

The <a>serialization steps</a> for {{DOMQuad}}, given |value| and |serialized|, are:

1. Set |serialized|.\[[P1]] to the <a>sub-serialization</a> of |value|'s <a
    for=quadrilateral>point 1</a>.
2. Set |serialized|.\[[P2]] to the <a>sub-serialization</a> of |value|'s <a
    for=quadrilateral>point 2</a>.
3. Set |serialized|.\[[P3]] to the <a>sub-serialization</a> of |value|'s <a
    for=quadrilateral>point 3</a>.
4. Set |serialized|.\[[P4]] to the <a>sub-serialization</a> of |value|'s <a
    for=quadrilateral>point 4</a>.

Their <a>deserialization steps</a>, given |serialized| and |value|, are:

1. Set |value|'s <a for=quadrilateral>point 1</a> to the <a>sub-deserialization</a> of
    |serialized|.\[[P1]].
2. Set |value|'s <a for=quadrilateral>point 2</a> to the <a>sub-deserialization</a> of
    |serialized|.\[[P2]].
3. Set |value|'s <a for=quadrilateral>point 3</a> to the <a>sub-deserialization</a> of
    |serialized|.\[[P3]].
4. Set |value|'s <a for=quadrilateral>point 4</a> to the <a>sub-deserialization</a> of
    |serialized|.\[[P4]].

The <a>serialization steps</a> for {{DOMMatrixReadOnly}} and {{DOMMatrix}}, given |value| and
|serialized|, are:

1. If |value|'s <a for=matrix>is 2D</a> is <code>true</code>:
    1. Set |serialized|.\[[M11]] to |value|'s <a for=matrix>m11 element</a>.
    2. Set |serialized|.\[[M12]] to |value|'s <a for=matrix>m12 element</a>.
    3. Set |serialized|.\[[M21]] to |value|'s <a for=matrix>m21 element</a>.
    4. Set |serialized|.\[[M22]] to |value|'s <a for=matrix>m22 element</a>.
    5. Set |serialized|.\[[M41]] to |value|'s <a for=matrix>m41 element</a>.
    6. Set |serialized|.\[[M42]] to |value|'s <a for=matrix>m42 element</a>.
    7. Set |serialized|.\[[Is2D]] to <code>true</code>.

    Note: It is possible for a 2D {{DOMMatrix}} or {{DOMMatrixReadOnly}} to have ''-0'' for
    some of the other elements, e.g., the <a for=matrix>m13 element</a>, which will not be
    roundtripped by this algorithm.
2. Otherwise:
    1. Set |serialized|.\[[M11]] to |value|'s <a for=matrix>m11 element</a>.
    2. Set |serialized|.\[[M12]] to |value|'s <a for=matrix>m12 element</a>.
    3. Set |serialized|.\[[M13]] to |value|'s <a for=matrix>m13 element</a>.
    4. Set |serialized|.\[[M14]] to |value|'s <a for=matrix>m14 element</a>.
    5. Set |serialized|.\[[M21]] to |value|'s <a for=matrix>m21 element</a>.
    6. Set |serialized|.\[[M22]] to |value|'s <a for=matrix>m22 element</a>.
    7. Set |serialized|.\[[M23]] to |value|'s <a for=matrix>m23 element</a>.
    8. Set |serialized|.\[[M24]] to |value|'s <a for=matrix>m24 element</a>.
    9. Set |serialized|.\[[M31]] to |value|'s <a for=matrix>m31 element</a>.
    10. Set |serialized|.\[[M32]] to |value|'s <a for=matrix>m32 element</a>.
    11. Set |serialized|.\[[M33]] to |value|'s <a for=matrix>m33 element</a>.
    12. Set |serialized|.\[[M34]] to |value|'s <a for=matrix>m34 element</a>.
    13. Set |serialized|.\[[M41]] to |value|'s <a for=matrix>m41 element</a>.
    14. Set |serialized|.\[[M42]] to |value|'s <a for=matrix>m42 element</a>.
    15. Set |serialized|.\[[M43]] to |value|'s <a for=matrix>m43 element</a>.
    16. Set |serialized|.\[[M44]] to |value|'s <a for=matrix>m44 element</a>.
    17. Set |serialized|.\[[Is2D]] to <code>false</code>.

    Their <a>deserialization steps</a>, given |serialized| and |value|, are:

    1. If |serialized|.\[[Is2D]] is <code>true</code>:
        1. Set |value|'s <a for=matrix>m11 element</a> to |serialized|.\[[M11]].
        2. Set |value|'s <a for=matrix>m12 element</a> to |serialized|.\[[M12]].
        3. Set |value|'s <a for=matrix>m13 element</a> to ''0''.
        4. Set |value|'s <a for=matrix>m14 element</a> to ''0''.
        5. Set |value|'s <a for=matrix>m21 element</a> to |serialized|.\[[M21]].
        6. Set |value|'s <a for=matrix>m22 element</a> to |serialized|.\[[M22]].
        7. Set |value|'s <a for=matrix>m23 element</a> to ''0''.
        8. Set |value|'s <a for=matrix>m24 element</a> to ''0''.
        9. Set |value|'s <a for=matrix>m31 element</a> to ''0''.
        10. Set |value|'s <a for=matrix>m32 element</a> to ''0''.
        11. Set |value|'s <a for=matrix>m33 element</a> to ''1''.
        12. Set |value|'s <a for=matrix>m34 element</a> to ''0''.
        13. Set |value|'s <a for=matrix>m41 element</a> to |serialized|.\[[M41]].
        14. Set |value|'s <a for=matrix>m42 element</a> to |serialized|.\[[M42]].
        15. Set |value|'s <a for=matrix>m43 element</a> to ''0''.
        16. Set |value|'s <a for=matrix>m44 element</a> to ''1''.
        17. Set |value|'s <a for=matrix>is 2D</a> to <code>true</code>.
    2. Otherwise:
        1. Set |value|'s <a for=matrix>m11 element</a> to |serialized|.\[[M11]].
        2. Set |value|'s <a for=matrix>m12 element</a> to |serialized|.\[[M12]].
        3. Set |value|'s <a for=matrix>m13 element</a> to |serialized|.\[[M13]].
        4. Set |value|'s <a for=matrix>m14 element</a> to |serialized|.\[[M14]].
        5. Set |value|'s <a for=matrix>m21 element</a> to |serialized|.\[[M21]].
        6. Set |value|'s <a for=matrix>m22 element</a> to |serialized|.\[[M22]].
        7. Set |value|'s <a for=matrix>m23 element</a> to |serialized|.\[[M23]].
        8. Set |value|'s <a for=matrix>m24 element</a> to |serialized|.\[[M24]].
        9. Set |value|'s <a for=matrix>m31 element</a> to |serialized|.\[[M31]].
        10. Set |value|'s <a for=matrix>m32 element</a> to |serialized|.\[[M32]].
        11. Set |value|'s <a for=matrix>m33 element</a> to |serialized|.\[[M33]].
        12. Set |value|'s <a for=matrix>m34 element</a> to |serialized|.\[[M34]].
        13. Set |value|'s <a for=matrix>m41 element</a> to |serialized|.\[[M41]].
        14. Set |value|'s <a for=matrix>m42 element</a> to |serialized|.\[[M42]].
        15. Set |value|'s <a for=matrix>m43 element</a> to |serialized|.\[[M43]].
        16. Set |value|'s <a for=matrix>m44 element</a> to |serialized|.\[[M44]].
        17. Set |value|'s <a for=matrix>is 2D</a> to <code>false</code>.


Privacy and Security Considerations {#priv-sec}
===============================================

The {{DOMMatrix}} and {{DOMMatrixReadOnly}} interfaces have entry-points to parsing a string with
CSS syntax. Therefore the <a href="https://drafts.csswg.org/css-syntax/#priv-sec">privacy and
security considerations</a> of the CSS Syntax specification applies. [[CSS3-SYNTAX]]

<div class=example>
This could potentially be used to exploit bugs in the CSS parser in a user agent.
</div>

There are no other known security or privacy impacts of the interfaces defined in this
specification. However, other specifications that have APIs that use the interfaces defined in this
specification could potentially introduce security or privacy issues.

<div class=example>
For example, the {{Element/getBoundingClientRect()}} API defined in CSSOM View returns a
{{DOMRect}} that could be used to measure the size of an inline element containing some text of a
particular font, which exposes information about whether the user has that font installed. That
information, if used to test many common fonts, can then be personally-identifiable information.
[[CSSOM-VIEW]]
</div>


Historical {#historical}
========================

<em>This section is non-normative.</em>

The interfaces in this specification are intended to replace earlier similar interfaces found in
various specifications as well as proprietary interfaces found in some user agents. This section
attempts to enumerate these interfaces.


CSSOM View {#historical-cssom-view}
-----------------------------------

Earlier revisions of CSSOM View defined a <code>ClientRect</code> interface, which is replaced by
{{DOMRect}}. Implementations conforming to this specification will not support
<code>ClientRect</code>. [[CSSOM-VIEW]]


SVG {#historical-svg}
---------------------

Earlier revisions of SVG defined {{SVGPoint}}, {{SVGRect}}, {{SVGMatrix}}, which are defined in
this specifications as aliases to {{DOMPoint}}, {{DOMRect}}, {{DOMMatrix}}, respectively. [[SVG11]]


Non-standard {#historical-non-standard}
---------------------------------------

Some user agents supported a <code>WebKitPoint</code> interface. Implementations conforming to
this specification will not support <code>WebKitPoint</code>.

Several user agents supported a {{WebKitCSSMatrix}} interface, which is also widely used on the
Web. It is defined in this specification as an alias to {{DOMMatrix}}.

Some user agents supported a <code>MSCSSMatrix</code> interface. Implementations conforming to
this specification will not support <code>MSCSSMatrix</code>.


<h2 class="no-num" id="changes">Changes since last publication</h2>

<em>This section is non-normative.</em>

The following changes were made since the <a
href="https://www.w3.org/TR/2014/CR-geometry-1-20141125/">25 November 2014 Candidate Recommendation</a>.

* Changed the interfaces to generally use specific static operations for construction instead
    of using overloaded constructors, and made the interfaces more consistent. However, {{DOMMatrix}}
    still uses an overloaded constructor for compatibility with {{WebKitCSSMatrix}}.
* Introduced the {{DOMMatrixInit}} dictionary.
* Added JSON serializers for the interfaces.
* Changed {{DOMMatrixReadOnly}} and {{DOMMatrix}} to be compatible with {{WebKitCSSMatrix}}:
    * Changed {{DOMMatrixReadOnly/rotate()}} and {{DOMMatrix/rotateSelf()}} arguments from
        <code>(angle, originX, originY)</code> to <code>(rotX, rotY, rotZ)</code>.
    * Changed the {{DOMMatrixReadOnly/scale()}} and {{DOMMatrix/scaleSelf()}} methods to be more
        like the previous <code>scaleNonUniform()</code>/<code>scaleNonUniformSelf()</code> methods,
        and dropped the <code>scaleNonUniformSelf()</code> method. Keep support for <code>scaleNonUniform()</code>
        for legacy reasons.
    * Made all arguments optional for {{DOMMatrix}}/{{DOMMatrixReadOnly}} methods, except for
        {{DOMMatrix/setMatrixValue()}}.
    * Added no-argument constructor.
    * Defined {{WebKitCSSMatrix}} to be a legacy window alias for {{DOMMatrix}}.
* In workers, {{DOMMatrix}} and {{DOMMatrixReadOnly}} do not support parsing or stringifying with CSS syntax.
* Defined structured serialization of the interfaces.
* The live <code>bounds</code> attribute on {{DOMQuad}} was replaced with a non-live
    {{DOMQuad/getBounds()}} method. The "associated bounding rectangle" concept was also removed.
* Changed the string parser for {{DOMMatrix}} and {{DOMMatrixReadOnly}} to use CSS rules
    instead of SVG rules.
* The stringifier for {{DOMMatrix}} and {{DOMMatrixReadOnly}} now throws if there are
    non-finite values, and otherwise uses the [=ToString=] algorithm. [[ECMA-262]]
* Made comparisons treat ''0'' and ''-0'' as equal throughout.
* Added [[#priv-sec]] and [[#historical]] sections.

The following changes were made since the <a
href="https://www.w3.org/TR/2014/WD-geometry-1-20140918/">18 September 2014 Working Draft</a>.

* Exposed {{DOMPointReadOnly}}, {{DOMPoint}}, {{DOMRectReadOnly}}, {{DOMRect}}, {{DOMQuad}},
    {{DOMMatrixReadOnly}} and {{DOMMatrix}} to {{Window}} and {{Worker}}. Defined cloning of
    the interface.

The following changes were made since the <a
href="https://www.w3.org/TR/2014/WD-geometry-1-20140626/">26 June 2014 Last Call Public Working
Draft</a>.

* {{DOMPointReadOnly}} got a constructor taking 4 arguments.
* {{DOMRectReadOnly}} got a constructor taking 4 arguments.
* {{DOMMatrixReadOnly}} got a constructor taking a sequence of numbers as argument.
* {{DOMRectList}} turned to an ArrayClass. The interfaces can just be used for legacy
    interfaces.
* Put {{DOMRectList}} on at-Risk awaiting browser feedback.
* All interfaces are described in the sense of internal elements to describe the
    read-only/writable and inheriting behavior.
* Replace {{IndexSizeError}} exception with {{TypeError}}.


The following changes were made since the <a
href="https://www.w3.org/TR/2014/WD-geometry-1-20140522/">22 May 2014 First Public Working Draft</a>.

* Renamed mutable transformation methods *By to *Self. (E.g. <code>translateBy()</code> got
    renamed to {{DOMMatrix/translateSelf()}}.)
* Renamed <code>invert()</code> to {{DOMMatrix/invertSelf()}}.
* Added {{DOMMatrix/setMatrixValue()}} which takes a transformation list as {{DOMString}}.
* {{DOMMatrixReadOnly/is2D}} and {{DOMMatrixReadOnly/isIdentity}} are read-only attributes now.
* {{DOMMatrixReadOnly}} gets flagged to track 3D transformation and attribute settings for
    {{DOMMatrixReadOnly/is2D}}.
* {{DOMMatrix/invertSelf()}} and {{DOMMatrixReadOnly/inverse()}} do not throw exceptions anymore.


<h2 class=no-num id=acknowledgments>Acknowledgments</h2>

The editors would like to thank Robert O’Callahan for contributing to this specification.
Many thanks to Dean Jackson for his initial proposal of DOMMatrix.
Thanks to
Adenilson Cavalcanti,
Benoit Jacob,
Boris Zbarsky,
Brian Birtles,
Cameron McCormack,
Domenic Denicola,
Kari Pihkala,
Max Vujovic,
Mike Taylor,
Peter Hall,
Philip Jägenstedt,
Simon Fraser,
and
Timothy Loh
for their careful reviews, comments, and corrections.
