Skip to content

Commit a6ae161

Browse files
committed
[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: w3c#12098 (comment) Closes w3c#12098
1 parent f48a484 commit a6ae161

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

css-borders-4/Overview.bs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,8 @@ Each shadow of [=/element=]'s 'box shadow' is shaped by the [=border contour pat
394394
To compute an [=/element=] |element|'s border contour path given an an [=edge=] |targetEdge| and an optional number |spread| (default 0):
395395
1. Let |outerLeft|, |outerTop|, |outerRight|, |outerBottom| be |element|'s [=unshaped edge|unshaped=] [=border edge=].
396396
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=].
398399
1. Let |topLeftShape|, |topRightShape|, |bottomRightShape|, and |bottomLeftShape| be |element|'s [=computed value|computed=] 'corner-*-shape' values.
399400
1. Let |targetLeft|, |targetTop|, |targetRight|, |targetBottom| [=unshaped edge|unshaped=] |targetEdge|.
400401
1. Let |path| be a new path [[SVG2]].
@@ -503,6 +504,47 @@ To compute the corner path given a rectangle |cornerRect|, a rectangl
503504
1. Return |cornerPath|.
504505
505506

507+

508+
Constraining opposite radii
509+
510+
When concave 'corner-shape' values are present (the [=superellipse parameter=] is negative), diagonally opposite corners might overlap each other.
511+
512+
513+

The following example would create overlapping corners if not constrained.

514+
515+
div {
516+
corner-shape: scoop;
517+
border-top-left-radius: 80%;
518+
border-bottom-right-radius: 80%;
519+
}
520+
521+
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.
525+
526+
527+
To compute the opposite corner scale factor given an [=/element=] |element|:
528+
1. Let |rect| be |element|'s [=border box=].
529+
1. Let |topRightHull| be a the [=normalized corner hull=] given |element|'s [=computed value|computed=] 'corner-top-right-shape',
530+
mapped to the rectangle (|rect|'s [=width dimension=] - |element|'s [=computed value|computed=] horizontal 'border-top-right-radius', 0, |rect|'s [=computed value|computed=] 'border-top-right-radius').
531+
1. Let |bottomRightHull| be a the [=normalized corner hull=] given |element|'s [=computed value|computed=] 'corner-bottom-right-shape',
532+
rotated by 90deg with (0.5, 0.5) as an origin,
533+
and mapped to the rectangle (|rect|'s [=width dimension=] - |element|'s [=computed value|computed=] horizontal 'border-bottom-right-radius', |rect|'s [=height dimension=] - |element|'s [=computed value|computed=] vertical 'border-bottom-right-radius',
534+
|element|'s [=computed value|computed=] 'border-bottom-right-radius').
535+
1. Let |bottomLeftHull| be a the [=normalized corner hull=] given |element|'s [=computed value|computed=] 'corner-bottom-right-shape',
536+
rotated by 180deg with (0.5, 0.5) as an origin,
537+
and mapped to the rectangle (0, |rect|'s [=height dimension=] - |element|'s [=computed value|computed=] vertical 'border-bottom-left-radius',
538+
|element|'s [=computed value|computed=] 'border-bottom-left-radius').
539+
1. Let |topLeftHull| be a the [=normalized 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.
544+
1. Return min(1, |scaleFactorA|, |scaleFactorB|).
545+
546+
547+
506548

507549
'corner-shape' values
508550

@@ -660,6 +702,19 @@ To compute the normalized superellipse half corner given a [=superell
660702
1. Return |convexHalfCorner|.
661703
662704

705+
706+
To compute the normalized corner hull given a [=superellipse parameter=] |curvature|:
707+
1. Let |normalizedHalfCorner| be the [=normalized superellipse half corner=] given |curvature|.
708+
1. Let |axisLineA| be a line between (0, 1) and (1, 1).
709+
1. Let |axisLineB| be a line between (1, 0) and (1, 1).
710+
1. Let |halfCornerPoint| be (|normalizedHalfCorner|, 1 - |normalizedHalfCorner|).
711+
1. Let |lineFromCenterToHalfCorner| be a line between (0, 0) and |halfCornerPoint|.
712+
1. Let |tangentLine| be the line perpendicular to |lineFromCenterToHalfCorner|, at |halfCornerPoint|.
713+
1. Let |intersectionA| be the intersection between |axisLineA| and |tangentLine|.
714+
1. Let |intersectionB| be the intersection between |axisLineB| and |tangentLine|.
715+
1. Return a pentagon between the points « (0, 0), (0, 1), |intersectionA|, |intersectionB|, (1, 0), (0, 0) ».
716+
717+
663718
To interpolate a [=superellipse parameter=] |s| to an interpolation value between 0 and 1, return the [=normalized superellipse half corner=] given |s|.
664719

665720
To convert a <> |interpolationValue| back to a [=superellipse parameter=], switch on |interpolationValue|:

0 commit comments

Comments
 (0)