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
[css-borders-4] Constrain radii for concave opposite corners (#12272)
* [css-borders-4] Constrain radii for concave opposite corners
If the hulls of opposite corners overlap, find a scale factor that would prevent the overlap, and apply to all radii.
Resolution: #12098 (comment)Closes#12098
* Fix hull computation for convex/concave
Copy file name to clipboardExpand all lines: css-borders-4/Overview.bs
+57-1Lines changed: 57 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -394,7 +394,8 @@ Each shadow of [=/element=]'s 'box shadow' is shaped by the [=border contour pat
394
394
To compute an [=/element=] |element|'s <dfn>border contour path</dfn> given an an [=edge=] |targetEdge| and an optional number |spread| (default 0):
395
395
1. Let |outerLeft|, |outerTop|, |outerRight|, |outerBottom| be |element|'s [=unshaped edge|unshaped=][=border edge=].
396
396
1. Let |topLeftHorizontalRadius|, |topLeftVericalRadius|, |topRightHorizontalRadius|, |topRightVerticalRadius|, |bottomRightHorizontalRadius|,
397
-
|bottomRightVerticalRadius|, |bottomLeftHorizontalRadius|, and |bottomLeftVerticalRadius| be |element| [=border edge=]'s radii.
397
+
|bottomRightVerticalRadius|, |bottomLeftHorizontalRadius|, and |bottomLeftVerticalRadius| be |element| [=border edge=]'s radii,
398
+
scaled by |element|'s [=opposite corner scale factor=].
398
399
1. Let |topLeftShape|, |topRightShape|, |bottomRightShape|, and |bottomLeftShape| be |element|'s [=computed value|computed=] 'corner-*-shape' values.
399
400
1. Let |targetLeft|, |targetTop|, |targetRight|, |targetBottom| [=unshaped edge|unshaped=] |targetEdge|.
400
401
1. Let |path| be a new path [[SVG2]].
@@ -503,6 +504,47 @@ To compute the <dfn>corner path</dfn> given a rectangle |cornerRect|, a rectangl
503
504
1. Return |cornerPath|.
504
505
</div>
505
506
507
+
<h4 id=corner-shape-constrain-radii>
508
+
Constraining opposite radii</h4>
509
+
510
+
When concave 'corner-shape' values are present (the [=superellipse parameter=] is negative), diagonally opposite corners might overlap each other.
511
+
512
+
<div class="example">
513
+
<p>The following example would create overlapping corners if not constrained.</p>
514
+
<pre class="lang-css">
515
+
div {
516
+
corner-shape: scoop;
517
+
border-top-left-radius: 80%;
518
+
border-bottom-right-radius: 80%;
519
+
}
520
+
</pre>
521
+
</div>
522
+
523
+
To prevent this, the four radii are constrained to prevent overlaps.
524
+
This is done by computing a hull polygon for each of the opposite corners, and finding the highest downscale factor which, if applied to both corners, would make it so that the polygons would not intersect.
1. Let |topLeftHull| be a the [=normalized inner corner hull=] given |element|'s [=computed value|computed=] 'corner-top-left-shape',
540
+
rotated by 270deg with (0.5, 0.5) as an origin,
541
+
mapped to (0, 0, |element|'s [=computed value|computed=] 'border-top-left-radius').
542
+
1. Let |scaleFactorA| be the highest number which, if both |topLeftHull| and |bottomRightHull| were scaled by, using their first point as the origin, those polygons would not intersect.
543
+
1. Let |scaleFactorB| be the highest number which, if both |topRightHull| and |bottomLeftHull| were scaled by, using their first point as the origin, those polygons would not intersect.
@@ -660,6 +702,20 @@ To compute the <dfn>normalized superellipse half corner</dfn> given a [=superell
660
702
1. Return |convexHalfCorner|.
661
703
</dl>
662
704
705
+
<div algorithm="superellipse-param-to-hull">
706
+
To compute the <dfn>normalized inner corner hull</dfn> given a [=superellipse parameter=] |curvature|:
707
+
1. If |curvature| is greater than or equal to zero, return a triangle betwen « (1, 1), (1, 0), (0, 1) ».
708
+
1. Let |axisLineA| be a line between <code>(1, 0)</code> and <code>(1, 1)</code>.
709
+
1. Let |axisLineB| be a line between <code>(0, 1)</code> and <code>(1, 1)</code>.
710
+
1. Let |normalizedHalfCorner| be the [=normalized superellipse half corner=] given |curvature|.
711
+
1. Let |halfCornerPoint| be <code>(|normalizedHalfCorner|, 1 - |normalizedHalfCorner|)</code>.
712
+
1. Let |lineFromCenterToHalfCorner| be a line between <code>(0, 0)</code> and |halfCornerPoint|.
713
+
1. Let |tangentLine| be the line perpendicular to |lineFromCenterToHalfCorner|, at |halfCornerPoint|.
714
+
1. Let |intersectionA| be the intersection between |axisLineA| and |tangentLine|.
715
+
1. Let |intersectionB| be the intersection between |axisLineB| and |tangentLine|.
716
+
1. Return a pentagon between the points « (1, 1), (1, 0), |intersectionA|, |intersectionB|, (0, 1), (1, 1) ».
717
+
</div>
718
+
663
719
To interpolate a [=superellipse parameter=] |s| to an interpolation value between 0 and 1, return the [=normalized superellipse half corner=] given |s|.
664
720
665
721
To convert a <<number [0,1]>> |interpolationValue| back to a [=superellipse parameter=], switch on |interpolationValue|:
0 commit comments