This repository was archived by the owner on Sep 21, 2022. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathelement-rect.js
More file actions
79 lines (71 loc) · 2.48 KB
/
Copy pathelement-rect.js
File metadata and controls
79 lines (71 loc) · 2.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
'use strict';
var q = require('q'),
Rect = require('./geometery/rect');
exports.getMultiple = function getMultiple(elements) {
var aliveElements = elements.filter(function(element) {
return !!element;
});
return q.all(aliveElements.map(function(element) {
return element.isVisible();
}))
.then(function(visibilities) {
var visibleElements = aliveElements.filter(function(element, index) {
return visibilities[index];
});
return q.all(visibleElements.map(exports.get));
})
.then(function(rects) {
return rects.reduce(function(first, second) {
return first.merge(second);
});
});
};
exports.get = function get(element) {
return element.getClientRect()
.then(function(rect) {
return element.getComputedCss('box-shadow').then(function(boxShadow) {
var shadows = parseBoxShadow(boxShadow);
return adjustRect(rect, shadows);
});
});
};
function parseBoxShadow(value) {
var regex = /.+? ([-+]?\d*\.?\d+)px ([-+]?\d*\.?\d+)px ([-+]?\d*\.?\d+)px ([-+]?\d*\.?\d+)px( inset)?/,
results = [],
match;
while ((match = value.match(regex))) {
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 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;
}