Created
December 17, 2019 13:00
-
-
Save JaminQ/32cd8b6c2d4975ec48db4f5e507d5ed5 to your computer and use it in GitHub Desktop.
参考Google Chrome内核实现的反色算法
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function fixDarkMode() { | |
function rgb2lab(rgb) { | |
var r = rgb[0] / 255, | |
g = rgb[1] / 255, | |
b = rgb[2] / 255, | |
x, y, z; | |
r = (r > 0.04045) ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92; | |
g = (g > 0.04045) ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92; | |
b = (b > 0.04045) ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92; | |
x = (r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047; | |
y = (r * 0.2126 + g * 0.7152 + b * 0.0722) / 1.00000; | |
z = (r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883; | |
x = (x > 0.008856) ? Math.pow(x, 1 / 3) : (7.787 * x) + 16 / 116; | |
y = (y > 0.008856) ? Math.pow(y, 1 / 3) : (7.787 * y) + 16 / 116; | |
z = (z > 0.008856) ? Math.pow(z, 1 / 3) : (7.787 * z) + 16 / 116; | |
return [(116 * y) - 16, 500 * (x - y), 200 * (y - z)] | |
} | |
function lab2rgb(lab){ | |
var y = (lab[0] + 16) / 116, | |
x = lab[1] / 500 + y, | |
z = y - lab[2] / 200, | |
r, g, b; | |
x = 0.95047 * ((x * x * x > 0.008856) ? x * x * x : (x - 16/116) / 7.787); | |
y = 1.00000 * ((y * y * y > 0.008856) ? y * y * y : (y - 16/116) / 7.787); | |
z = 1.08883 * ((z * z * z > 0.008856) ? z * z * z : (z - 16/116) / 7.787); | |
r = x * 3.2406 + y * -1.5372 + z * -0.4986; | |
g = x * -0.9689 + y * 1.8758 + z * 0.0415; | |
b = x * 0.0557 + y * -0.2040 + z * 1.0570; | |
r = (r > 0.0031308) ? (1.055 * Math.pow(r, 1/2.4) - 0.055) : 12.92 * r; | |
g = (g > 0.0031308) ? (1.055 * Math.pow(g, 1/2.4) - 0.055) : 12.92 * g; | |
b = (b > 0.0031308) ? (1.055 * Math.pow(b, 1/2.4) - 0.055) : 12.92 * b; | |
return [Math.max(0, Math.min(1, r)) * 255, | |
Math.max(0, Math.min(1, g)) * 255, | |
Math.max(0, Math.min(1, b)) * 255] | |
} | |
function hex2RGB (hex) { | |
var num = parseInt(hex, 16) | |
return [num >> 16, num >> 8 & 255, num & 255]; | |
}; | |
function RGB2Hex(red, green, blue) { | |
return ((blue | green << 8 | red << 16) | 1 << 24).toString(16).slice(1); | |
} | |
function adjustGray([red, green, blue]) { | |
var brightnessThreshold = 32 | |
var adjustedBrightness = 18 | |
if (red == green && red == blue && red < brightnessThreshold && red > adjustedBrightness) { | |
return [adjustedBrightness, adjustedBrightness, adjustedBrightness] | |
} | |
return [red, green, blue] | |
} | |
function convertDarkModeColor(rgb) { | |
var lab = rgb2lab(rgb) | |
var convertLab = [Math.min(110 - lab[0], 100), lab[1], lab[2]] | |
var convertRgb = lab2rgb(convertLab) | |
var finalResult = adjustGray(convertRgb) | |
console.log(rgb) | |
console.log(lab) | |
console.log(convertLab) | |
console.log(convertRgb) | |
return finalResult.map((x) => Math.round(x)) | |
} | |
Array.prototype.forEach.call(document.styleSheets, (style, index) => { | |
if (index == 0) return; | |
var cssText = style.ownerNode.innerText | |
var colorHexReg = /#[a-f\d]{6}|#[a-f\d]{3}/gi | |
var colorRgbReg = /rgb\((\d+),\s*(\d+),\s*(\d+)\)/gi | |
var colorRgbaReg = /rgba\(([\d\.]+),\s*([\d\.]+),\s*([\d\.]+),\s*([\d\.]+)\)/gi | |
var x | |
var newCssText = cssText | |
while (x = colorHexReg.exec(cssText)) { | |
var hex = x[0].replace('#', '') | |
if (hex.length == 3) { | |
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] | |
} | |
var rgb = hex2RGB(hex) | |
var convertResult = convertDarkModeColor(rgb) | |
newCssText = newCssText.replace(x[0], `rgb(${convertResult[0]}, ${convertResult[1]}, ${convertResult[2]})`) | |
} | |
while (x = colorRgbReg.exec(cssText)) { | |
var r = parseFloat(x[1]) | |
var g = parseFloat(x[2]) | |
var b = parseFloat(x[3]) | |
var convertResult = convertDarkModeColor([r, g, b]) | |
newCssText = newCssText.replace(x[0], `rgb(${convertResult[0]}, ${convertResult[1]}, ${convertResult[2]})`) | |
} | |
while (x = colorRgbaReg.exec(cssText)) { | |
var r = parseFloat(x[1]) | |
var g = parseFloat(x[2]) | |
var b = parseFloat(x[3]) | |
var a = x[4] | |
var convertResult = convertDarkModeColor([r, g, b]) | |
newCssText = newCssText.replace(x[0], `rgba(${convertResult[0]}, ${convertResult[1]}, ${convertResult[2]}, ${a})`) | |
} | |
style.ownerNode.innerText = newCssText | |
}) | |
var css = document.createElement('style') | |
css.innerText = 'body { color: #fff; background: #1b1b1b; }' | |
document.head.appendChild(css) | |
} | |
fixDarkMode() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment