Sith/doc/Color Theory - Palette Creator/js/index.js

103 lines
3.8 KiB
JavaScript

/* jshint esversion: 6 */
// This is using Sass.js to use Sass built-in color mixing functions
const firstColorChooser = document.forms['color-theory']['first-color'];
const firstColor = document.querySelector('.first-color');
const secondColor = document.querySelector('.second-color');
let hue = undefined;
let comp = undefined;
updateColors();
Sass.options({
precision: 1
});
computeScss();
document.forms['color-theory']['first-color'].addEventListener('input', updateColors);
document.forms['color-theory']['first-color'].addEventListener('change', computeScss);
function updateColors(ev) {
hue = parseInt(firstColorChooser.value);
comp = (hue + 180) % 360;
setColorPreview([firstColor], `hsl(${hue}, 100%, 50%)`);
setColorPreview([secondColor], `hsl(${comp}, 100%, 50%)`);
}
function setColorPreview(fieldsets, color) {
Array.from(fieldsets).forEach(fieldset => {
const preview = fieldset.querySelector('.color-preview');
preview.style.backgroundColor = fieldset.querySelector('.color-code').value = color;
const text = fieldset.querySelector('.color-text')
if(text)
text.style.color = computeTextColor(window.getComputedStyle(preview).backgroundColor);
});
}
function setColorText(fieldsets, bg, text) {
Array.from(fieldsets).forEach(fieldset => {
fieldset.querySelector('.color-preview').style.backgroundColor = bg;
fieldset.querySelector('.color-text').style.color = fieldset.querySelector('.color-code').value = text;
});
}
function computeScss() {
Sass.compile(
`$first-color: hsl(${hue}, 100%, 50%);` +
document.querySelector('#scss-template').content.firstElementChild.textContent, computedScssHandler);
}
function computedScssHandler(result) {
let colors = {};
result.text.split('\n\n').forEach(rule => {
const color = /\.([\w\-]+) {\s*color: (hsl\() (\d{1,3}(?:\.\d+)?)deg(.*) (\));\s*}/.exec(rule).splice(1, 5).join('').split('hsl');
colors[color[0]] = `hsl${color[1]}`;
});
for (let colorName in colors)
if (document.querySelector(`.${colorName}`)) setColorPreview(document.querySelectorAll(`.${colorName}`), colors[colorName]);
const primaryTextColor = computeTextColor(window.getComputedStyle(document.querySelector('.primary-color .color-preview')).backgroundColor);
const complementaryTextColor = computeTextColor(window.getComputedStyle(document.querySelector('.complementary-color .color-preview')).backgroundColor);
setColorText([document.querySelector('.text-on-primary')], document.querySelector('.primary-color .color-preview').style.backgroundColor, primaryTextColor);
setColorText([document.querySelector('.text-on-complementary')], document.querySelector('.complementary-color .color-preview').style.backgroundColor, complementaryTextColor)
}
function computeTextColor(colorStr) {
const black = [0, 0, 0, .87];
const white = [255, 255, 255, 1];
[, , r, g, b, a] = /(rgba?)\((\d{1,3}), (\d{1,3}), (\d{1,3})(?:, (\d(?:\.\d+)))?\)/.exec(colorStr);
const color = [parseInt(r), parseInt(g), parseInt(b), parseFloat(a == undefined ? 1 : a)]
const blackContrast = computeConstrastRatio(black, color);
const whiteContrast = computeConstrastRatio(white, color);
return blackContrast < whiteContrast ? `hsl(0, 0%, 100%)` : `hsla(0, 0%, 0%, 0.87)`
}
function computeConstrastRatio([fr, fg, fb, fa], [br, bg, bb, ba]) {
if (fa < 1) {
fr = fr * fa + br * (1 - fa);
fg = fg * fa + bg * (1 - fa);
fb = fb * fa + bb * (1 - fa);
fa = 1;
}
const fl = luminance([fr, fg, fb]);
const bl = luminance([br, bg, bb]);
if (fl < bl)
return (bl + .05) / (fl + .05);
else
return (fl + .05) / (bl + .05);
}
function luminance([r, g, b]) {
return .2126 * colorComponent(r) + .7152 * colorComponent(g) + .0722 * colorComponent(b);
}
function colorComponent(color) {
const c = color / 255;
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
}