Skip to content

Commit

Permalink
Add roundRect() canvas method
Browse files Browse the repository at this point in the history
  • Loading branch information
mysteryDate authored and mfreed7 committed Jun 3, 2022
1 parent 32ef08c commit 50ec03d
Showing 1 changed file with 194 additions and 0 deletions.
194 changes: 194 additions & 0 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -3746,6 +3746,10 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li>The <dfn data-x-href="https://drafts.fxtf.org/geometry/#create-a-dommatrix-from-the-dictionary">create a <code>DOMMatrix</code> from a dictionary</dfn>
and <dfn data-x-href="https://drafts.fxtf.org/geometry/#create-a-dommatrix-from-the-2d-dictionary">create a <code>DOMMatrix</code> from a 2D dictionary</dfn>
algorithms for <code>DOMMatrix2DInit</code> or <code>DOMMatrixInit</code></li>

<li>The <dfn data-x-href="https://drafts.fxtf.org/geometry/#dictdef-dompointinit"><code>DOMPointInit</code></dfn> dictionary, and associated
<dfn data-x="DOMPointInit-x" data-xref="https://drafts.fxtf.org/geometry/#dom-dompointinit-x">x</dfn> and
<dfn data-x="DOMPointInit-y" data-xref="https://drafts.fxtf.org/geometry/#dom-dompointinit-y">y</dfn> members</li>
</ul>

<p>The following terms are defined in the <cite>CSS Scoping</cite>: <ref spec=CSSSCOPING></p>
Expand Down Expand Up @@ -60917,6 +60921,7 @@ interface mixin <dfn interface>CanvasPath</dfn> {
undefined <span data-x="dom-context-2d-bezierCurveTo">bezierCurveTo</span>(unrestricted double cp1x, unrestricted double cp1y, unrestricted double cp2x, unrestricted double cp2y, unrestricted double x, unrestricted double y);
undefined <span data-x="dom-context-2d-arcTo">arcTo</span>(unrestricted double x1, unrestricted double y1, unrestricted double x2, unrestricted double y2, unrestricted double radius); <!-- see ARC-ORDER note below -->
undefined <span data-x="dom-context-2d-rect">rect</span>(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h);
undefined <span data-x="dom-context-2d-roundRect">roundRect</span>(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h, sequence&lt;(unrestricted double or <span>DOMPointInit</span>)> radii);
undefined <span data-x="dom-context-2d-arc">arc</span>(unrestricted double x, unrestricted double y, unrestricted double radius, unrestricted double startAngle, unrestricted double endAngle, optional boolean counterclockwise = false); <!-- see ARC-ORDER note below -->
undefined <span data-x="dom-context-2d-ellipse">ellipse</span>(unrestricted double x, unrestricted double y, unrestricted double radiusX, unrestricted double radiusY, unrestricted double rotation, unrestricted double startAngle, unrestricted double endAngle, optional boolean counterclockwise = false); <!-- see ARC-ORDER note below -->
};
Expand Down Expand Up @@ -62921,6 +62926,51 @@ try {
<dd>
<p>Adds a new closed subpath to the path, representing the given rectangle.</p>
</dd>

<dt><var>context</var> . <code subdfn data-x="dom-context-2d-roundRect">roundRect</code>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>, <var>radii</var>)</dt>
<dt><var>path</var> . <code data-x="dom-context-2d-roundRect">roundRect</code>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>, <var>radii</var>)</dt>

<dd>
<p>Adds a new closed subpath to the path representing the given rounded rectangle.
<var>radii</var> represents a list of radii for the corners of the rectangle, in pixels. The
number and order of these radii function in the same way as the CSS <span>'border-radius'</span>
property.</p>

<p>If <var>w</var> and <var>h</var> are both greater than or equal to 0, or if both are smaller
than 0, then the path is drawn clockwise. Otherwise, it is drawn counterclockwise.</p>

<p>When <var>w</var> is negative, the rounded rectangle is flipped horizontally, which means
that the radius values that normally apply to the left corners are used on the right and vice
versa. Similarly, when <var>h</var> is negative, the rounded rect is flipped vertically.</p>

<p>When a value <var>r</var> in <var>radii</var> is a number, the corresponding corner(s) are
drawn as circular arcs of radius <var>r</var>.</p>

<p>When a value <var>r</var> in <var>radii</var> is an object with <code data-x="">{ x, y
}</code> properties, the corresponding corner(s) are drawn as elliptical arcs whose <var>x</var>
and <var>y</var> radii are equal to <var>r.x</var> and <var>r.y</var>, respectively.</p>

<p>When the sum of the <var>radii</var> of two corners of the same edge is greater than the
length of the edge, all the <var>radii</var> of the rounded rectangle are scaled by a factor of
length / (<var>r1</var> + <var>r2</var>). If multiple edges have this property, the scale factor
of the edge with the smallest scale factor is used. This is consistent with CSS behavior.</p>

<p>Throws a <code data-x="js-RangeError">RangeError</code> if <var>radii</var> not a list of
size one, two, three, or four.</p>

<p>Throws a <code data-x="js-RangeError">RangeError</code> if a value in <var>radii</var> is a
negative number, or is an <code data-x="">{ x, y }</code> object whose <code data-x="">x</code>
or <code data-x="">y</code> properties are negative numbers.</p>

<!-- Consider adding this useful information to all the methods which behave this way: -->
<!--
<p>If any of <var>x</var>, <var>y</var>, <var>width</var> or <var>height</var> are non-finite
numbers, or if a value in <var>radii</var> is a non-finite number, or if a value in
<var>radii</var> is an <code data-x="">{ x, y }</code> object whose <code data-x="">x</code> or
<code data-x="">y</code> properties are non-finite numbers, then the method aborts without
throwing an exception and without adding anything to the current path.</p>
-->
</dd>
</dl>

<div w-nodev>
Expand Down Expand Up @@ -63141,6 +63191,150 @@ try {
subpath.</p></li>
</ol>

<p>The <dfn method for="CanvasPath"><code
data-x="dom-context-2d-roundRect">roundRect(<var>x</var>, <var>y</var>, <var>w</var>,
<var>h</var>, <var>radii</var>)</code></dfn> method steps are:</p>

<ol>
<li><p>If any of <var>x</var>, <var>y</var>, <var>w</var>, or <var>h</var> are infinite or NaN,
then return.</p></li>

<li><p>If <var>radii</var> is not a list of size one, two, three, or four, then throw a <code
data-x="js-RangeError">RangeError</code>.</p></li>

<li><p>Let <var>normalizedRadii</var> be an empty list.</p></li>

<li>
<p>For each <var>radius</var> of <var>radii</var>:</p>

<ol>
<li>
<p>If <var>radius</var> is a <code>DOMPointInit</code>:</p>

<ol>
<li><p>If <var>radius</var>["<code data-x="DOMPointInit-x">x</code>"] or
<var>radius</var>["<code data-x="DOMPointInit-y">y</code>"] is infinite or NaN, then
return.</p></li>

<li><p>If <var>radius</var>["<code data-x="DOMPointInit-x">x</code>"] or
<var>radius</var>["<code data-x="DOMPointInit-y">y</code>"] is negative, then throw a <code
data-x="js-RangeError">RangeError</code>.</p></li>

<li><p>Otherwise, append <var>radius</var> to <var>normalizedRadii</var>.</p></li>
</ol>
</li>

<li>
<p>If <var>radius</var> is a <code data-x="idl-unrestricted-double">unrestricted
double</code>:</p>

<ol>
<li><p>If <var>radius</var> is infinite or NaN, then return.</p></li>

<li><p>If <var>radius</var> is negative, then throw a <code
data-x="js-RangeError">RangeError</code>.</p></li>

<li><p>Otherwise append «[ "<code data-x="DOMPointInit-x">x</code>" → <var>radius</var>,
"<code data-x="DOMPointInit-x">y</code>" → <var>radius</var> ]» to
<var>normalizedRadii</var>.</p></li>
</ol>
</li>
</ol>
</li>

<li><p>Let <var>upperLeft</var>, <var>upperRight</var>, <var>lowerRight</var>, and
<var>lowerLeft</var> be null.</p></li>

<li><p>If <var>normalizedRadii</var>'s size is 4, then set <var>upperLeft</var> to
<var>normalizedRadii</var>[0], set <var>upperRight</var> to <var>normalizedRadii</var>[1], set
<var>lowerRight</var> to <var>normalizedRadii</var>[2], and set <var>lowerLeft</var> to
<var>normalizedRadii</var>[3].</p></li>

<li><p>If <var>normalizedRadii</var>'s size is 3, then set <var>upperLeft</var> to
<var>normalizedRadii</var>[0], set <var>upperRight</var> and <var>lowerLeft</var> to
<var>normalizedRadii</var>[1], and set <var>lowerRight</var> to
<var>normalizedRadii</var>[2].</p></li>

<li><p>If <var>normalizedRadii</var>'s size is 2, then set <var>upperLeft</var> and
<var>lowerRight</var> to <var>normalizedRadii</var>[0] and set <var>upperRight</var> and
<var>lowerLeft</var> to <var>normalizedRadii</var>[1].</p></li>

<li><p>If <var>normalizedRadii</var>'s size is 1, then set <var>upperLeft</var>,
<var>upperRight</var>, <var>lowerRight</var>, and <var>lowerLeft</var> to
<var>normalizedRadii</var>[0].<p></li>

<li>
<p>Corner curves must not overlap. Scale all radii to prevent this:</p>

<ol>
<li><p>Let <var>top</var> be <var>upperLeft</var>["<code data-x="DOMPointInit-x">x</code>"] +
<var>upperRight</var>["<code data-x="DOMPointInit-x">x</code>"].</p></li>

<li><p>Let <var>right</var> be <var>upperRight</var>["<code
data-x="DOMPointInit-y">y</code>"] + <var>lowerRight</var>["<code
data-x="DOMPointInit-y">y</code>"].</p></li>

<li><p>Let <var>bottom</var> be <var>lowerRight</var>["<code
data-x="DOMPointInit-x">x</code>"] + <var>lowerLeft</var>["<code
data-x="DOMPointInit-x">x</code>"].</p></li>

<li><p>Let <var>left</var> be <var>lowerLeft</var>["<code data-x="DOMPointInit-y">y</code>"]
+ <var>lowerRight</var>["<code data-x="DOMPointInit-y">y</code>"]</p></li>

<li><p>Let <var>scale</var> be the minimum value of the ratios <var>w</var> / <var>top</var>,
<var>h</var> / <var>right</var>, <var>w</var> / <var>bottom</var>, <var>h</var> /
<var>left</var>.</p></li>

<li><p>If <var>scale</var> is less than 1, then set the <code data-x="DOMPointInit-x">x</code>
and <code data-x="DOMPointInit-y">y</code> members of <var>upperLeft</var>,
<var>upperRight</var>, <var>lowerLeft</var>, and <var>lowerRight</var> to their current values
multiplied by <var>scale</var>.</p></li>
</ol>
</li>

<li>
<p>Create a new subpath:</p>

<ol>
<li><p>Move to the point (<var>x</var> + <var>upperLeft</var>["<code
data-x="DOMPointInit-x">x</code>"], <var>y</var>).</p></li>

<li><p>Draw a straight line to the point (<var>x</var> + <var>w</var> &minus;
<var>upperRight</var>["<code data-x="DOMPointInit-x">x</code>"], <var>y</var>).</p></li>

<li><p>Draw an arc to the point (<var>x</var> + <var>w</var>, <var>y</var> +
<var>upperRight</var>["<code data-x="DOMPointInit-y">y</code>"]).</p></li>

<li><p>Draw a straight line to the point (<var>x</var> + <var>w</var>, <var>y</var> +
<var>h</var> &minus; <var>lowerRight</var>["<code data-x="DOMPointInit-y">y</code>"]).</p></li>

<li><p>Draw an arc to the point (<var>x</var> + <var>w</var> &minus;
<var>lowerRight</var>["<code data-x="DOMPointInit-x">x</code>"], <var>y</var> +
<var>h</var>).</p></li>

<li><p>Draw a straight line to the point (<var>x</var> + <var>lowerLeft</var>["<code
data-x="DOMPointInit-x">x</code>"], <var>y</var> + <var>h</var>).</p></li>

<li><p>Draw an arc to the point (<var>x</var>, <var>y</var> + <var>h</var> &minus;
<var>lowerLeft</var>["<code data-x="DOMPointInit-y">y</code>"]).</p></li>

<li><p>Draw a straight line to the point (<var>x</var>, <var>y</var> +
<var>upperLeft</var>["<code data-x="DOMPointInit-y">y</code>"]).</p></li>

<li><p>Draw an arc to the point (<var>x</var> + <var>upperLeft</var>["<code
data-x="DOMPointInit-x">x</code>"], <var>y</var>).</p></li>
</ol>
</li>

<li><p>Mark the subpath as closed.</p></li>

<li><p>Create a new subpath with the point (<var>x</var>, <var>y</var>) as the only point in the
subpath.</p></li>
</ol>

<p class="note">This is designed to behave similarly to the CSS <span
data-x="'border-radius'">'border-radius'</span> property.</p>

<!-- v6 feature request:
* points as a primitive shape
http://home.comcast.net/~urbanjost/canvas/vogle4.html
Expand Down

0 comments on commit 50ec03d

Please sign in to comment.