-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchooseOutlineColor.js
79 lines (68 loc) · 2.29 KB
/
chooseOutlineColor.js
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
function calculateRelativeLuminance(color) {
let [r, g, b, a] = color.match(/\d*\.?\d+/g).map(Number);
// If alpha channel exists, apply it to RGB values
if (typeof a !== "undefined") {
// Assuming white background for alpha blending
r = (1 - a) * 255 + a * r;
g = (1 - a) * 255 + a * g;
b = (1 - a) * 255 + a * b;
}
const getSRGB = (c) => {
const sc = c / 255;
return sc <= 0.03928 ? sc / 12.92 : Math.pow((sc + 0.055) / 1.055, 2.4);
};
const rs = getSRGB(r);
const gs = getSRGB(g);
const bs = getSRGB(b);
const luminance = 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
return luminance;
}
function isOpaque(elem) {
const style = window.getComputedStyle(elem);
if (style.opacity == 0) {
return false;
}
if (
style.backgroundColor.includes("rgba") &&
style.backgroundColor.endsWith(" 0)")
) {
return false;
}
return true;
}
function getOpaqueBgElement(element) {
const rect = element.getBoundingClientRect();
let x = rect.left + 1;
let y = rect.top + 1;
const elements = document.elementsFromPoint(x, y);
let firstOpaque = null;
for (let i = 1; i < elements.length; i++) {
if (isOpaque(elements[i])) {
firstOpaque = elements[i];
break;
}
}
if (!firstOpaque) {
let elem = element.parentElement;
while (elem && !isOpaque(elem)) {
elem = elem.parentElement;
}
firstOpaque = elem;
}
return firstOpaque;
}
function chooseOutlineColor(element) {
// The background element's color is used instead of the focused element's
// background due to the outline being shown around the element rather
// than on the element
const bgElement = getOpaqueBgElement(element);
let bgColor = "rgb(255, 255, 255)";
if (bgElement) {
bgColor = window.getComputedStyle(bgElement).backgroundColor;
}
const bgLuminance = calculateRelativeLuminance(bgColor);
const blackContrast = (bgLuminance + 0.05) / 0.05;
const whiteContrast = 1.05 / (bgLuminance + 0.05);
const outlineColor = blackContrast > whiteContrast ? "black" : "white";
return outlineColor;
}