calculate new CSS tinting when we change theme
This commit is contained in:
parent
b2ddcb8027
commit
e72e30197a
2 changed files with 86 additions and 82 deletions
226
src/Tinter.js
226
src/Tinter.js
|
@ -80,7 +80,115 @@ const svgAttrs = [
|
|||
|
||||
let cached = false;
|
||||
|
||||
function calcCssFixups() {
|
||||
function hexToRgb(color) {
|
||||
if (color[0] === '#') color = color.slice(1);
|
||||
if (color.length === 3) {
|
||||
color = color[0] + color[0] +
|
||||
color[1] + color[1] +
|
||||
color[2] + color[2];
|
||||
}
|
||||
const val = parseInt(color, 16);
|
||||
const r = (val >> 16) & 255;
|
||||
const g = (val >> 8) & 255;
|
||||
const b = val & 255;
|
||||
return [r, g, b];
|
||||
}
|
||||
|
||||
function rgbToHex(rgb) {
|
||||
const val = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
|
||||
return '#' + (0x1000000 + val).toString(16).slice(1);
|
||||
}
|
||||
|
||||
// List of functions to call when the tint changes.
|
||||
const tintables = [];
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Register a callback to fire when the tint changes.
|
||||
* This is used to rewrite the tintable SVGs with the new tint.
|
||||
*
|
||||
* It's not possible to unregister a tintable callback. So this can only be
|
||||
* used to register a static callback. If a set of tintables will change
|
||||
* over time then the best bet is to register a single callback for the
|
||||
* entire set.
|
||||
*
|
||||
* @param {Function} tintable Function to call when the tint changes.
|
||||
*/
|
||||
registerTintable: function(tintable) {
|
||||
tintables.push(tintable);
|
||||
},
|
||||
|
||||
getKeyRgb: function() {
|
||||
return keyRgb;
|
||||
},
|
||||
|
||||
tint: function(primaryColor, secondaryColor, tertiaryColor) {
|
||||
if (!cached) {
|
||||
this.calcCssFixups();
|
||||
cached = true;
|
||||
}
|
||||
|
||||
if (!primaryColor) {
|
||||
const theme = UserSettingsStore.getTheme();
|
||||
primaryColor = keyRgb[0];
|
||||
secondaryColor = keyRgb[1];
|
||||
}
|
||||
|
||||
if (!secondaryColor) {
|
||||
const x = 0.16; // average weighting factor calculated from vector green & light green
|
||||
const rgb = hexToRgb(primaryColor);
|
||||
rgb[0] = x * rgb[0] + (1 - x) * 255;
|
||||
rgb[1] = x * rgb[1] + (1 - x) * 255;
|
||||
rgb[2] = x * rgb[2] + (1 - x) * 255;
|
||||
secondaryColor = rgbToHex(rgb);
|
||||
}
|
||||
|
||||
if (!tertiaryColor) {
|
||||
const x = 0.19;
|
||||
const rgb1 = hexToRgb(primaryColor);
|
||||
const rgb2 = hexToRgb(secondaryColor);
|
||||
rgb1[0] = x * rgb1[0] + (1 - x) * rgb2[0];
|
||||
rgb1[1] = x * rgb1[1] + (1 - x) * rgb2[1];
|
||||
rgb1[2] = x * rgb1[2] + (1 - x) * rgb2[2];
|
||||
tertiaryColor = rgbToHex(rgb1);
|
||||
}
|
||||
|
||||
if (colors[0] === primaryColor &&
|
||||
colors[1] === secondaryColor &&
|
||||
colors[2] === tertiaryColor) {
|
||||
return;
|
||||
}
|
||||
|
||||
colors[0] = primaryColor;
|
||||
colors[1] = secondaryColor;
|
||||
colors[2] = tertiaryColor;
|
||||
|
||||
if (DEBUG) console.log("Tinter.tint");
|
||||
|
||||
// go through manually fixing up the stylesheets.
|
||||
this.applyCssFixups();
|
||||
|
||||
// tell all the SVGs to go fix themselves up
|
||||
// we don't do this as a dispatch otherwise it will visually lag
|
||||
tintables.forEach(function(tintable) {
|
||||
tintable();
|
||||
});
|
||||
},
|
||||
|
||||
tintSvgWhite: function(whiteColor) {
|
||||
if (!whiteColor) {
|
||||
whiteColor = colors[3];
|
||||
}
|
||||
if (colors[3] === whiteColor) {
|
||||
return;
|
||||
}
|
||||
colors[3] = whiteColor;
|
||||
tintables.forEach(function(tintable) {
|
||||
tintable();
|
||||
});
|
||||
},
|
||||
|
||||
calcCssFixups: function() {
|
||||
if (DEBUG) console.log("calcCssFixups start");
|
||||
|
||||
// update keyRgb from the current theme CSS itself, if it defines it
|
||||
|
@ -148,123 +256,15 @@ function calcCssFixups() {
|
|||
}
|
||||
}
|
||||
if (DEBUG) console.log("calcCssFixups end");
|
||||
}
|
||||
},
|
||||
|
||||
function applyCssFixups() {
|
||||
applyCssFixups: function() {
|
||||
if (DEBUG) console.log("applyCssFixups start");
|
||||
for (let i = 0; i < cssFixups.length; i++) {
|
||||
const cssFixup = cssFixups[i];
|
||||
cssFixup.style[cssFixup.attr] = colors[cssFixup.index];
|
||||
}
|
||||
if (DEBUG) console.log("applyCssFixups end");
|
||||
}
|
||||
|
||||
function hexToRgb(color) {
|
||||
if (color[0] === '#') color = color.slice(1);
|
||||
if (color.length === 3) {
|
||||
color = color[0] + color[0] +
|
||||
color[1] + color[1] +
|
||||
color[2] + color[2];
|
||||
}
|
||||
const val = parseInt(color, 16);
|
||||
const r = (val >> 16) & 255;
|
||||
const g = (val >> 8) & 255;
|
||||
const b = val & 255;
|
||||
return [r, g, b];
|
||||
}
|
||||
|
||||
function rgbToHex(rgb) {
|
||||
const val = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
|
||||
return '#' + (0x1000000 + val).toString(16).slice(1);
|
||||
}
|
||||
|
||||
// List of functions to call when the tint changes.
|
||||
const tintables = [];
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Register a callback to fire when the tint changes.
|
||||
* This is used to rewrite the tintable SVGs with the new tint.
|
||||
*
|
||||
* It's not possible to unregister a tintable callback. So this can only be
|
||||
* used to register a static callback. If a set of tintables will change
|
||||
* over time then the best bet is to register a single callback for the
|
||||
* entire set.
|
||||
*
|
||||
* @param {Function} tintable Function to call when the tint changes.
|
||||
*/
|
||||
registerTintable: function(tintable) {
|
||||
tintables.push(tintable);
|
||||
},
|
||||
|
||||
getKeyRgb: function() {
|
||||
return keyRgb;
|
||||
},
|
||||
|
||||
tint: function(primaryColor, secondaryColor, tertiaryColor) {
|
||||
if (!cached) {
|
||||
calcCssFixups();
|
||||
cached = true;
|
||||
}
|
||||
|
||||
if (!primaryColor) {
|
||||
const theme = UserSettingsStore.getTheme();
|
||||
primaryColor = keyRgb[0];
|
||||
secondaryColor = keyRgb[1];
|
||||
}
|
||||
|
||||
if (!secondaryColor) {
|
||||
const x = 0.16; // average weighting factor calculated from vector green & light green
|
||||
const rgb = hexToRgb(primaryColor);
|
||||
rgb[0] = x * rgb[0] + (1 - x) * 255;
|
||||
rgb[1] = x * rgb[1] + (1 - x) * 255;
|
||||
rgb[2] = x * rgb[2] + (1 - x) * 255;
|
||||
secondaryColor = rgbToHex(rgb);
|
||||
}
|
||||
|
||||
if (!tertiaryColor) {
|
||||
const x = 0.19;
|
||||
const rgb1 = hexToRgb(primaryColor);
|
||||
const rgb2 = hexToRgb(secondaryColor);
|
||||
rgb1[0] = x * rgb1[0] + (1 - x) * rgb2[0];
|
||||
rgb1[1] = x * rgb1[1] + (1 - x) * rgb2[1];
|
||||
rgb1[2] = x * rgb1[2] + (1 - x) * rgb2[2];
|
||||
tertiaryColor = rgbToHex(rgb1);
|
||||
}
|
||||
|
||||
if (colors[0] === primaryColor &&
|
||||
colors[1] === secondaryColor &&
|
||||
colors[2] === tertiaryColor) {
|
||||
return;
|
||||
}
|
||||
|
||||
colors[0] = primaryColor;
|
||||
colors[1] = secondaryColor;
|
||||
colors[2] = tertiaryColor;
|
||||
|
||||
if (DEBUG) console.log("Tinter.tint");
|
||||
|
||||
// go through manually fixing up the stylesheets.
|
||||
applyCssFixups();
|
||||
|
||||
// tell all the SVGs to go fix themselves up
|
||||
// we don't do this as a dispatch otherwise it will visually lag
|
||||
tintables.forEach(function(tintable) {
|
||||
tintable();
|
||||
});
|
||||
},
|
||||
|
||||
tintSvgWhite: function(whiteColor) {
|
||||
if (!whiteColor) {
|
||||
whiteColor = colors[3];
|
||||
}
|
||||
if (colors[3] === whiteColor) {
|
||||
return;
|
||||
}
|
||||
colors[3] = whiteColor;
|
||||
tintables.forEach(function(tintable) {
|
||||
tintable();
|
||||
});
|
||||
},
|
||||
|
||||
// XXX: we could just move this all into TintableSvg, but as it's so similar
|
||||
|
@ -299,7 +299,9 @@ module.exports = {
|
|||
for (let k = 0; k < svgAttrs.length; k++) {
|
||||
const attr = svgAttrs[k];
|
||||
for (let l = 0; l < keyHex.length; l++) {
|
||||
if (tag.getAttribute(attr) && tag.getAttribute(attr).toUpperCase() === keyHex[l]) {
|
||||
if (tag.getAttribute(attr) &&
|
||||
tag.getAttribute(attr).toUpperCase() === keyHex[l])
|
||||
{
|
||||
fixups.push({
|
||||
node: tag,
|
||||
attr: attr,
|
||||
|
|
|
@ -919,6 +919,8 @@ module.exports = React.createClass({
|
|||
});
|
||||
styleElements[theme].disabled = false;
|
||||
|
||||
Tinter.calcCssFixups();
|
||||
|
||||
if (theme === 'dark') {
|
||||
// abuse the tinter to change all the SVG's #fff to #2d2d2d
|
||||
// XXX: obviously this shouldn't be hardcoded here.
|
||||
|
|
Loading…
Reference in a new issue