Skip to content

Commit 2a29c11

Browse files
committed
Update radius-expansion.html
Add Noam's algorithm. Change my algorithms to use min instead of max. Add testcase.
1 parent 8392df9 commit 2a29c11

File tree

1 file changed

+59
-2
lines changed

1 file changed

+59
-2
lines changed

css-backgrounds-3/radius-expansion.html

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@
7878
<input type="radio" name="algorithm" value="oriol2">
7979
Oriol's variant of current spec (adding a linear factor)
8080
</label>
81+
<label>
82+
<input type="radio" name="algorithm" value="spectrum">
83+
Noam's old/new spectrum
84+
</label>
8185
</form>
8286
<output id="output"></output>
8387
<script>
@@ -101,6 +105,7 @@
101105
{width: 200, height: 40, spread: 50, borderRadius: "0 50% / 50%"},
102106
{width: 0, height: 0, spread: 30, borderRadius: "50px 0px 0px 0px"},
103107
{width: 500, height: 500, spread: 30, borderRadius: "50px"},
108+
{width: 250, height: 30, spread: 100, borderRadius: "10px"},
104109
];
105110

106111
function show({incremental = false} = {}) {
@@ -295,7 +300,7 @@
295300
}
296301
else if (algorithm === "oriol") {
297302
for (let corner in radii) {
298-
let coverage = Math.max(
303+
let coverage = Math.min(
299304
2 * radii[corner][0] / testCase.width,
300305
2 * radii[corner][1] / testCase.height,
301306
) || 0;
@@ -310,7 +315,7 @@
310315
}
311316
else if (algorithm === "oriol2") {
312317
for (let corner in radii) {
313-
let coverage = Math.max(
318+
let coverage = Math.min(
314319
2 * radii[corner][0] / testCase.width,
315320
2 * radii[corner][1] / testCase.height,
316321
) || 0;
@@ -323,6 +328,58 @@
323328
});
324329
}
325330
}
331+
else if (algorithm === "spectrum") {
332+
const old_spec = (value) => {
333+
if (value == 0)
334+
return 0;
335+
return value + testCase.spread;
336+
}
337+
338+
const new_spec = (value) => {
339+
if (value >= testCase.spread) {
340+
return value + testCase.spread;
341+
}
342+
let r = value / testCase.spread;
343+
return value + testCase.spread * (1 + (r - 1)**3);
344+
}
345+
346+
const map_dim = (radius, dim) => {
347+
// If there's no radius, there's no spread to apply.
348+
if (radius === 0) {
349+
return 0;
350+
}
351+
352+
// Calculate the radius's ratio to the spread, clamping at 1.
353+
const spreadRatio = 1 - Math.min(1, radius / testCase.spread);
354+
355+
// Calculate the diameter's ratio to the overall dimension, clamping at 1.
356+
const dimRatio = Math.min(1, (2 * radius) / dim);
357+
358+
// These factors determine the amount of easing. They both approach 0
359+
// as their respective ratios approach 1, which reduces the easing effect.
360+
const spreadEasingFactor = spreadRatio ** 3;
361+
const dimEasingFactor = 1 - dimRatio ** 3;
362+
363+
// The total reduction in spread is the product of the two easing factors.
364+
const totalReduction = dimEasingFactor * spreadEasingFactor;
365+
366+
// Apply the reduction to the spread and add it to the original radius.
367+
const easedSpread = testCase.spread * (1 - totalReduction);
368+
369+
return radius + easedSpread;
370+
}
371+
372+
const map = ([h, v]) => {
373+
return [map_dim(h, testCase.width), map_dim(v, testCase.height)];
374+
}
375+
376+
r = {
377+
topLeft: map(radii.topLeft),
378+
topRight: map(radii.topRight),
379+
bottomRight: map(radii.bottomRight),
380+
bottomLeft: map(radii.bottomLeft)
381+
};
382+
}
326383

327384
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`;
328385
}

0 commit comments

Comments
 (0)