25 lines
1.6 KiB
JavaScript
25 lines
1.6 KiB
JavaScript
export const accents = { green: '#d2ef92', blue: '#8ac7ff', red: '#ff9e99' };
|
|
export function palette(color, light = false) {
|
|
color = /^#[0-9a-f]{6}$/i.test(color) ? color : accents.green;
|
|
const rgb = [1, 3, 5].map(i => parseInt(color.slice(i, i + 2), 16));
|
|
const luminance = c => { const n = c / 255; return n <= .04045 ? n / 12.92 : ((n + .055) / 1.055) ** 2.4; };
|
|
const lum = values => values.map(luminance).reduce((n, v, i) => n + v * [.2126, .7152, .0722][i], 0);
|
|
// Maintain readable accent text on either background, even for arbitrary colors.
|
|
for (let i = 0; i < 40 && (light ? lum(rgb) > .17 : lum(rgb) < .36); i++) {
|
|
rgb.forEach((n, j) => rgb[j] = Math.round(light ? n * .9 : n + (255 - n) * .12));
|
|
}
|
|
return { accent: `#${rgb.map(n => n.toString(16).padStart(2, '0')).join('')}`, ink: light ? '#ffffff' : '#101313' };
|
|
}
|
|
export function applyTheme(storage) {
|
|
const light = storage.get('theme') === 'light';
|
|
const color = accents[storage.get('accent', 'green')] || storage.get('customColor', accents.green);
|
|
const values = palette(color, light);
|
|
document.body.classList.toggle('light', light);
|
|
document.body.classList.toggle('digital-dials', storage.get('dialStyle') === 'digital');
|
|
document.body.classList.toggle('luminous-dials', storage.get('dialStyle') === 'luminous');
|
|
document.querySelectorAll('.gauge > svg').forEach(svg => svg.setAttribute('viewBox', '12 10 276 340'));
|
|
document.body.style.setProperty('--accent', values.accent);
|
|
document.body.style.setProperty('--ink', values.ink);
|
|
document.dispatchEvent(new Event('caria-theme'));
|
|
}
|