You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
spec:geometry-1; type: dfn; text: x coordinate; for: rectangle
26
+
spec:geometry-1; type: dfn; text: y coordinate; for: rectangle
27
+
spec:geometry-1; type: dfn; text: rectangle
28
+
spec:dom; type: dfn; text: element;
23
29
</pre>
24
30
25
31
<link rel="stylesheet" href="style.css" />
@@ -358,10 +364,144 @@ Like 'border-radius', 'corner-shape' clips elements according to the [=overflow=
358
364
Since stroking a superellipse accurately may be computationally intensive, user agents may approximate the path using bezier curves,
359
365
as well as account for sharp edges and overlaps.
360
366
361
-
Issue: 'border-radius' already handles *adjacent* corners overlapping by shrinking the radiuses proportionally.
362
-
A negative ''superellipse()'' parameter allows for *opposite* corners to sometimes overlap, and needs additional restrictions defined.
363
-
364
-
Issue <a href="https://github.com/w3c/csswg-drafts/issues/11610">#11610</a>: check if we need additional rendering restrictions.
367
+
When rendering a [=border=] for a box that has a 'border-radius' and a 'corner-shape',
368
+
the inner border follows the curve of the outer shape, with a nearly consistent distance from the outer path throughout,
369
+
or a linearly increasing distance if the 'border-width' of the two edges of the corner is not uniform.
370
+
371
+
In contrast, when rendering a 'box shadow' or when extending the [=overflow clip edge=], the resulting path does not trace border contour.
372
+
Instead, it preserves the original shape and scales it in an axis-aligned manner.
373
+
374
+
<figure>
375
+
<img src="images/corner-shape-adjusting.svg"
376
+
style="background: white;"
377
+
alt="Adjusting corner shapes">
378
+
<figcaption>Borders are aligned to the curve, shadows and clip are aligned to the axis.</figcaption>
379
+
</figure>
380
+
381
+
382
+
An [=/element=] |element|'s <dfn>outer contour</dfn> is the [=border contour path=] given |element| and |element|'s [=border edge=].
383
+
384
+
An [=/element=] |element|'s <dfn>inner contour</dfn> is the [=border contour path=] given |element| and |element|'s [=padding edge=].
385
+
386
+
An [=/element=]'s [=border=] is rendered in the area between its [=outer contour=] and its [=inner contour=].
387
+
388
+
An [=/element=]'s [=overflow=] area is shaped by its [=inner contour=].
389
+
An [=/element=]'s [=overflow clip edge=] is shaped by the [=border contour path=] given |element|, and |element|'s [=padding edge=], and |element|'s [=used value|used=] 'overflow-clip-margin'.
390
+
391
+
Each shadow of [=/element=]'s 'box shadow' is shaped by the [=border contour path=] given |element|, and |element|'s [=border edge=], and the shadow's [=used value|used=]'box-shadow-spread'.
1. Translate |path| by <code>-|spread|, -|spread|</code>.
420
+
421
+
Note: this creates an effect where the resulting path has the same shape as the original path, but scaled to fit the given spread.
422
+
1. Return |path|.
423
+
424
+
To compute the <dfn>corner path</dfn> given a rectangle |cornerRect|, a rectangle |trimRect|, and numbers |startThickness|, |endThickness|, |orientation|, and |curvature|:
425
+
1. Assert: |orientation| is 0, 1, 2, or 3.
426
+
1. If |curvature| is less than zero, then:
427
+
1. Set |curvature| to <code>-|curvature|</code>.
428
+
1. Swap between |startThickness| and |endThickness|.
429
+
1. Set |orientation| to (|orientation| + 2) % 4.
430
+
1. Let |cornerPath| be a path that begins at <code>(0, 1)</code>.
431
+
1. Switch on |curvature|:
432
+
<dl class=switch>
433
+
: 0
434
+
:: Extend |cornerPath| by adding a straight line to <code>(1, 0)</code>.
435
+
436
+
: ∞
437
+
::
438
+
1. Extend |cornerPath| by adding a straight line to <code>(1, 1)</code>.
439
+
1. Extend |cornerPath| by adding a straight line to <code>(1, 0)</code>.
440
+
441
+
: Otherwise
442
+
::
443
+
1. Let |K| be <code>0.5<sup>|curvature|</sup></code>.
444
+
1. For each |T| between 0 and 1, extend |cornerPath| through <code>(|T|<sup>|K|</sup>, (1−|T|)<sup>|K|</sup>)</code>.
445
+
446
+
User agents may approximate this path, for instance, by using concatenated Bezier curves, to balance between performance and rendering accuracy.
447
+
</dl>
448
+
449
+
1. Let (|x|, |y|, |width|, |height|) be |targetRect|.
<figcaption>When the 'corner-shape' is ''corner-shape/round'' or more convex (<code>>= 1</code>), the unit vector is <code>1, 0</code>.
470
+
</figcaption>
471
+
</figure>
472
+
473
+
1. If |curvature| is less than 1:
474
+
1. Let |halfCorner| be the [=normalized superellipse half corner=] given |curvature|.
475
+
1. Let |offsetX| be <code>max(0, (|halfCorner| - 1) * 2 + √2)</code>.
476
+
1. Let |offsetY| be <code>max(0, √2 - |halfCorner| * 2)</code>.
477
+
478
+
Note: This formula defines the tangent of a quadratic Bezier curve that's equivalent to a superellipse quadrant.
479
+
Notably, convex hypoellipses (superellipses with a [=superellipse parameter|parameter=] between 0 and 1) can be very precisely represented by quadratic curves.
480
+
481
+
1. Let |length| be <code>hypot(|offsetX|, |offsetY|)</code>.
482
+
1. Set |tangentUnitVector| to <code>(|offsetX| / |length|, |offsetY| / |length|)</code>.
483
+
484
+
At this point |curvature| is guaranteed to be convex (>=1), so ther resulting |tangentUnitVector| would be in the range between <code>(1, 0)</code> and <code>(√2/2, √2/2)</code>.
@@ -396,7 +536,7 @@ Issue <a href="https://github.com/w3c/csswg-drafts/issues/11610">#11610</a>: che
396
536
It is a number between <css>-infinity</css> and <css>infinity</css>, with <css>-infinity</css> corresponding to a straight concave corner,
397
537
<css>infinity</css> corresponding to a square convex corner.
398
538
399
-
The <dfn>canonical superellipse formula</dfn> can be described in Cartesian coordinates, as follows,
539
+
The <dfn export>canonical superellipse formula</dfn> can be described in Cartesian coordinates, as follows,
400
540
where <code>s</code> is the [=superellipse parameter=]:
401
541
402
542
<pre>
@@ -415,10 +555,10 @@ Issue <a href="https://github.com/w3c/csswg-drafts/issues/11610">#11610</a>: che
415
555
416
556
<figure>
417
557
<img src="images/superellipse-param.svg"
418
-
width="320" height="240"
419
-
style="background: white; padding: 8px;"
420
-
title="rendering of different superellipse parameter values"
421
-
alt="Rendering of different superellipse parameter values.">
558
+
width="320" height="240"
559
+
style="background: white; padding: 8px;"
560
+
title="rendering of different superellipse parameter values"
561
+
alt="Rendering of different superellipse parameter values.">
422
562
<figcaption>
423
563
Rendering examples of different ''superellipse()'' values.
424
564
</figcaption>
@@ -504,7 +644,7 @@ Since it uses a <code>log2</code>, interpolating it linearly would result in an
504
644
To balance that, the <dfn>superellipse interpolation</dfn> formula describes how a [=superellipse parameter=] is converted to a value between 0 and 1, and vice versa:
To interpolate a <<number [-∞,∞]>> |s| to an interpolation value between 0 and 1, return the first matching statement, switch on |s|:
647
+
To compute the <dfn>normalized superellipse half corner</dfn> given a [=superellipse parameter=] |s|, return the first matching statement, switching on |s|:
508
648
<dl class=switch>
509
649
: -∞
510
650
:: Return 0.
@@ -518,9 +658,10 @@ To interpolate a <<number [-∞,∞]>> |s| to an interpolation value bet
518
658
1. Let |convexHalfCorner| be <code>0.5<sup>|k|</sup></code>.
519
659
1. If |param| is less than 0, return <code>1 - |convexHalfCorner|</code>.
520
660
1. Return |convexHalfCorner|.
521
-
522
661
</dl>
523
662
663
+
To interpolate a [=superellipse parameter=] |s| to an interpolation value between 0 and 1, return the [=normalized superellipse half corner=] given |s|.
664
+
524
665
To convert a <<number [0,1]>> |interpolationValue| back to a [=superellipse parameter=], switch on |interpolationValue|:
0 commit comments