Skip to content
This repository has been archived by the owner on Sep 21, 2022. It is now read-only.

Commit

Permalink
Correctly handle box-shadows
Browse files Browse the repository at this point in the history
Now box-shadows rects are calculated the same way as in Blink
engine.
  • Loading branch information
Sergey Tatarintsev committed Feb 25, 2014
1 parent 9f02fbc commit b9f7bcc
Showing 1 changed file with 34 additions and 21 deletions.
55 changes: 34 additions & 21 deletions lib/element-rect.js
Expand Up @@ -27,39 +27,52 @@ exports.get = function get(element) {
.then(function(rect) {
return element.getCssValue('box-shadow').then(function(boxShadow) {
var shadows = parseBoxShadow(boxShadow);
return shadows.reduce(addBoxShadowRect, rect);
return adjustRect(rect, shadows);
});
});
};

function parseBoxShadow(value) {
var regex = /.+? ((?:\d*)(?:\.\d+)?)px ((?:\d*)(?:\.\d+)?)px ((?:\d*)(?:\.\d+)?)px ((?:\d*)(?:\.\d+)?)px( inset)?/,
var regex = /.+? ([-+]?\d*\.?\d+)px ([-+]?\d*\.?\d+)px ([-+]?\d*\.?\d+)px ([-+]?\d*\.?\d+)px( inset)?/,
results = [],
match;

while ((match = value.match(regex))) {
//ignore inset shadows
if (!match[5]) {
results.push({
offsetX: +match[1],
offsetY: +match[2],
blurRadius: +match[3],
spreadRadius: +match[4]
});
}

results.push({
offsetX: +match[1],
offsetY: +match[2],
blurRadius: +match[3],
spreadRadius: +match[4],
inset: !!match[5]
});
value = value.substring(match.index + match[0].length);
}
return results;
}

function addBoxShadowRect(rect, shadow) {
var size = shadow.blurRadius + shadow.spreadRadius,
shadowRect = new Rect(
rect.x + shadow.offsetX - size,
rect.y + shadow.offsetY - size,
rect.width - shadow.offsetX + 2 * size,
rect.height - shadow.offsetY + 2 *size
);
return rect.merge(shadowRect);
function adjustRect(rect, shadows) {
var extent = calculateShadowExtent(shadows);
return new Rect(
Math.max(0, rect.x + extent.left),
Math.max(0, rect.y + extent.top),
rect.width - extent.left + extent.right,
rect.height - extent.top + extent.bottom
);
}

function calculateShadowExtent(shadows) {
var result = {top: 0, left: 0, right: 0, bottom: 0};
shadows.forEach(function(shadow) {
if (shadow.inset) {
//skip inset shadows
return;
}

var blurAndSpread = shadow.spreadRadius + shadow.blurRadius;
result.left = Math.min(shadow.offsetX - blurAndSpread, result.left);
result.right = Math.max(shadow.offsetX + blurAndSpread, result.right);
result.top = Math.min(shadow.offsetY - blurAndSpread, result.top);
result.bottom = Math.max(shadow.offsetY + blurAndSpread, result.bottom);
});
return result;
}

0 comments on commit b9f7bcc

Please sign in to comment.