Skip to content

Commit e210552

Browse files
committed
Adding corner shaping behavior for marin box as border-radius approaches 0
1 parent 8121f20 commit e210552

File tree

5 files changed

+41
-21
lines changed

5 files changed

+41
-21
lines changed

shapes-polyfill.js

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,24 +1453,34 @@ function adjustBounds(bounds, sign, offsets) {
14531453
bounds.height += sign * (top + bottom);
14541454
}
14551455

1456+
// See http://dev.w3.org/csswg/css-shapes/#margin-box
1457+
function adjustRadius(radius, sign, offset) {
1458+
if (sign < 0)
1459+
return Math.max(radius + sign * offset, 0);
1460+
var ratio = Math.abs(radius / offset);
1461+
if (ratio < 1)
1462+
return Math.max(radius + offset * (1 + Math.pow(ratio - 1, 3)), 0);
1463+
return radius + offset;
1464+
}
1465+
14561466
function adjustRadii(radii, sign, offsets) {
14571467
var top = offsets.reduce(function(prev, curr) { return prev + curr[0]; }, 0);
14581468
var right = offsets.reduce(function(prev, curr) { return prev + curr[1]; }, 0);
14591469
var bottom = offsets.reduce(function(prev, curr) { return prev + curr[2]; }, 0);
14601470
var left = offsets.reduce(function(prev, curr) { return prev + curr[3]; }, 0);
14611471

14621472
// Still need to max these with 0
1463-
radii[0][0] = Math.max(radii[0][0] + sign * left, 0);
1464-
radii[0][1] = Math.max(radii[0][1] + sign * top, 0);
1473+
radii[0][0] = adjustRadius(radii[0][0], sign, left);
1474+
radii[0][1] = adjustRadius(radii[0][1], sign, top);
14651475

1466-
radii[1][0] = Math.max(radii[1][0] + sign * right, 0);
1467-
radii[1][1] = Math.max(radii[1][1] + sign * top, 0);
1476+
radii[1][0] = adjustRadius(radii[1][0], sign, right);
1477+
radii[1][1] = adjustRadius(radii[1][1], sign, top);
14681478

1469-
radii[2][0] = Math.max(radii[2][0] + sign * right, 0);
1470-
radii[2][1] = Math.max(radii[2][1] + sign * bottom, 0);
1479+
radii[2][0] = adjustRadius(radii[2][0], sign, right);
1480+
radii[2][1] = adjustRadius(radii[2][1], sign, bottom);
14711481

1472-
radii[3][0] = Math.max(radii[3][0] + sign * left, 0);
1473-
radii[3][1] = Math.max(radii[3][1] + sign * bottom, 0);
1482+
radii[3][0] = adjustRadius(radii[3][0], sign, left);
1483+
radii[3][1] = adjustRadius(radii[3][1], sign, bottom);
14741484
}
14751485

14761486
ShapeValue.prototype.parseBox = function(text, metrics) {

shapes-polyfill.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/shape-value.js

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,34 @@ function adjustBounds(bounds, sign, offsets) {
6969
bounds.height += sign * (top + bottom);
7070
}
7171

72+
// See http://dev.w3.org/csswg/css-shapes/#margin-box
73+
function adjustRadius(radius, sign, offset) {
74+
if (sign < 0)
75+
return Math.max(radius + sign * offset, 0);
76+
var ratio = Math.abs(radius / offset);
77+
if (ratio < 1)
78+
return Math.max(radius + offset * (1 + Math.pow(ratio - 1, 3)), 0);
79+
return radius + offset;
80+
}
81+
7282
function adjustRadii(radii, sign, offsets) {
7383
var top = offsets.reduce(function(prev, curr) { return prev + curr[0]; }, 0);
7484
var right = offsets.reduce(function(prev, curr) { return prev + curr[1]; }, 0);
7585
var bottom = offsets.reduce(function(prev, curr) { return prev + curr[2]; }, 0);
7686
var left = offsets.reduce(function(prev, curr) { return prev + curr[3]; }, 0);
7787

7888
// Still need to max these with 0
79-
radii[0][0] = Math.max(radii[0][0] + sign * left, 0);
80-
radii[0][1] = Math.max(radii[0][1] + sign * top, 0);
89+
radii[0][0] = adjustRadius(radii[0][0], sign, left);
90+
radii[0][1] = adjustRadius(radii[0][1], sign, top);
8191

82-
radii[1][0] = Math.max(radii[1][0] + sign * right, 0);
83-
radii[1][1] = Math.max(radii[1][1] + sign * top, 0);
92+
radii[1][0] = adjustRadius(radii[1][0], sign, right);
93+
radii[1][1] = adjustRadius(radii[1][1], sign, top);
8494

85-
radii[2][0] = Math.max(radii[2][0] + sign * right, 0);
86-
radii[2][1] = Math.max(radii[2][1] + sign * bottom, 0);
95+
radii[2][0] = adjustRadius(radii[2][0], sign, right);
96+
radii[2][1] = adjustRadius(radii[2][1], sign, bottom);
8797

88-
radii[3][0] = Math.max(radii[3][0] + sign * left, 0);
89-
radii[3][1] = Math.max(radii[3][1] + sign * bottom, 0);
98+
radii[3][0] = adjustRadius(radii[3][0], sign, left);
99+
radii[3][1] = adjustRadius(radii[3][1], sign, bottom);
90100
}
91101

92102
ShapeValue.prototype.parseBox = function(text, metrics) {

tests/shape-info-tests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ function register(mocha, expect) {
7979
{ top: 160, bottom: 180, offset: 246, cssFloat: 'left' },
8080
{ top: 180, bottom: 200, offset: 246, cssFloat: 'left' },
8181
{ top: 200, bottom: 220, offset: 246, cssFloat: 'left' },
82-
{ top: 220, bottom: 240, offset: 246, cssFloat: 'left' }
82+
{ top: 220, bottom: 224, offset: 246, cssFloat: 'left' }
8383
]
8484
},
8585
{

tests/shape-value-tests.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ function register(mocha, expect) {
150150
{
151151
name: 'margin-box',
152152
input: 'margin-box',
153-
output: 'margin-box { x: -20, y: -5, width: 130, height: 120, radii: 30 30 40 60 / 15 25 45 55 }'
153+
output: 'margin-box { x: -20, y: -5, width: 130, height: 120, radii: 27.5 30 40 60 / 15 25 45 55 }'
154154
},
155155
{
156156
name: 'border-box',
@@ -199,7 +199,7 @@ function register(mocha, expect) {
199199
name: 'circle() margin-box',
200200
input: 'circle() margin-box',
201201
shape: 'circle(60 at 65 60)',
202-
box: 'margin-box { x: -20, y: -5, width: 130, height: 120, radii: 30 30 40 60 / 15 25 45 55 }'
202+
box: 'margin-box { x: -20, y: -5, width: 130, height: 120, radii: 27.5 30 40 60 / 15 25 45 55 }'
203203
},
204204
{
205205
name: 'circle() border-box',

0 commit comments

Comments
 (0)