Re: [csswg-drafts] [css-backgrounds] The shape of box-shadow should be a circle for a box with border-radius:50% and big spread (#7103)

@Loirooriol , would you be able to apply the following patch to your set of examples, which adds 3 additional options?  One of them is the old (discontinuous) behavior which is still what non-Chromium engines implement (along with old Chromium).  The other two are an additional capping method that I came up with (with 2 variants).

<details>
<summary>Patch (expand for details)</summary>

```diff
--- shadow-radius.html 2022-08-04 15:53:41.000000000 -0400
+++ shadow-radius.html 2022-08-05 09:33:16.000000000 -0400
@@ -30,16 +30,20 @@
     <input type="radio" name="algorithm" value="do-not-polyfill" checked>
     Do not polyfill
   </label>
   <label>
     <input type="radio" name="algorithm" value="increase-by-spread">
     Increase radius by spread
   </label>
   <label>
+    <input type="radio" name="algorithm" value="old-spec">
+    Old spec (discontinuous)
+  </label>
+  <label>
     <input type="radio" name="algorithm" value="current-spec">
     Current spec
   </label>
   <label>
     <input type="radio" name="algorithm" value="percentage-min-axis">
     Percentage of min axis
   </label>
   <label>
@@ -49,16 +53,24 @@
   <label>
     <input type="radio" name="algorithm" value="percentage-same-axis">
     Percentage of same axis
   </label>
   <label>
     <input type="radio" name="algorithm" value="percentage-same-axis-ratio">
     Percentage of same axis,<br>ceiling to keep ratio if possible
   </label>
+  <label>
+    <input type="radio" name="algorithm" value="linear-edge-portion">
+    Rounded portion of edges (linear)
+  </label>
+  <label>
+    <input type="radio" name="algorithm" value="cubic-edge-portion">
+    Rounded portion of edges (cubic)
+  </label>
 </form>
 <div id="output"></div>
 <script>
 const output = document.getElementById("output");
 const {algorithm} = document.forms[0].elements;
 const testCases = [
   {width: 50, height: 50, spread: 50, borderRadius: "0px"},
   {width: 50, height: 50, spread: 50, borderRadius: "1px"},
@@ -138,16 +150,30 @@
       r = {
         topLeft: radii.topLeft.map(map),
         topRight: radii.topRight.map(map),
         bottomLeft: radii.bottomLeft.map(map),
         bottomRight: radii.bottomRight.map(map),
       };
       break;
     }
+    case "old-spec": {
+      const map = (value) => {
+        if (value == 0)
+          return 0;
+        return value + testCase.spread;
+      }
+      r = {
+        topLeft: radii.topLeft.map(map),
+        topRight: radii.topRight.map(map),
+        bottomLeft: radii.bottomLeft.map(map),
+        bottomRight: radii.bottomRight.map(map),
+      };
+      break;
+    }
     case "current-spec": {
       const map = (value) => {
         if (value >= testCase.spread) {
           return value + testCase.spread;
         }
         let r = value / testCase.spread;
         return value + testCase.spread * (1 + (r - 1)**3);
       }
@@ -230,16 +256,48 @@
         }
       }
       adjust("topLeft", "topRight", 0);
       adjust("bottomLeft", "bottomRight", 0);
       adjust("topLeft", "bottomLeft", 1);
       adjust("topRight", "bottomRight", 1);
       break;
     }
+    case "linear-edge-portion":
+    case "cubic-edge-portion": {
+      // The portion of each edge that is rounded
+      const portion = {
+        top:    (radii.topLeft[0] + radii.topRight[0]) / testCase.width,
+        right:  (radii.topRight[1] + radii.bottomRight[1]) / testCase.height,
+        bottom: (radii.bottomLeft[0] + radii.bottomRight[0]) / testCase.width,
+        left:   (radii.topLeft[1] + radii.bottomLeft[1]) / testCase.height,
+      };
+      const map = (value, cap) => {
+        if (value >= testCase.spread) {
+          return value + testCase.spread;
+        }
+        switch (algorithm.value) {
+          case "linear-edge-portion": {
+            let r = value / testCase.spread;
+            return value + testCase.spread * Math.max(1 + (r - 1)**3, cap);
+          }
+          case "cubic-edge-portion": {
+            let r = Math.max(value / testCase.spread, cap);
+            return value + testCase.spread * (1 + (r - 1)**3);
+          }
+        }
+      }
+      r = {
+        topLeft: radii.topLeft.map((r) => map(r, Math.max(portion.top, portion.left))),
+        topRight: radii.topRight.map((r) => map(r, Math.max(portion.top, portion.right))),
+        bottomLeft: radii.bottomLeft.map((r) => map(r, Math.max(portion.bottom, portion.left))),
+        bottomRight: radii.bottomRight.map((r) => map(r, Math.max(portion.bottom, portion.right))),
+      };
+      break;
+    }
     default: {
       throw "Not implemented: " + algorithm.value;
       break;
     }
   }
   return `${r.topLeft[0]}px ${r.topRight[0]}px ${r.bottomRight[0]}px ${r.bottomLeft[0]}px / ${r.topLeft[1]}px ${r.topRight[1]}px ${r.bottomRight[1]}px ${r.bottomLeft[1]}px`;
 }
 show();
```

</details>

-- 
GitHub Notification of comment by dbaron
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/7103#issuecomment-1206468926 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Friday, 5 August 2022 13:37:33 UTC