Programmatically check and improve contrast ratios on dynamic color palettes
This commit is contained in:
parent
cd6b279d01
commit
68a8c3ba90
@ -4,11 +4,61 @@ const path = require('path');
|
|||||||
const { read } = require('fast-exif');
|
const { read } = require('fast-exif');
|
||||||
const iptc = require('node-iptc');
|
const iptc = require('node-iptc');
|
||||||
const Vibrant = require('node-vibrant');
|
const Vibrant = require('node-vibrant');
|
||||||
const R = require('ramda');
|
|
||||||
const chroma = require('chroma-js');
|
const chroma = require('chroma-js');
|
||||||
|
const chalk = require('chalk');
|
||||||
|
|
||||||
const readFile = util.promisify(fs.readFile);
|
const readFile = util.promisify(fs.readFile);
|
||||||
|
|
||||||
|
const badContrast = (color1, color2) => chroma.contrast(color1, color2) < 4.5;
|
||||||
|
|
||||||
|
function processColors(vibrantData, imagePath) {
|
||||||
|
let Vibrant = chroma(vibrantData.Vibrant.getRgb());
|
||||||
|
let DarkVibrant = chroma(vibrantData.DarkVibrant.getRgb());
|
||||||
|
let LightVibrant = chroma(vibrantData.LightVibrant.getRgb());
|
||||||
|
let Muted = chroma(vibrantData.Muted.getRgb());
|
||||||
|
let DarkMuted = chroma(vibrantData.DarkMuted.getRgb());
|
||||||
|
let LightMuted = chroma(vibrantData.LightMuted.getRgb());
|
||||||
|
|
||||||
|
// first pass - darken bg and lighten relevant fg colors
|
||||||
|
if (badContrast(DarkVibrant, Vibrant) || badContrast(DarkVibrant, LightMuted)) {
|
||||||
|
DarkVibrant = DarkVibrant.darken();
|
||||||
|
if (badContrast(DarkVibrant, Vibrant)) {
|
||||||
|
Vibrant = Vibrant.brighten();
|
||||||
|
}
|
||||||
|
if (badContrast(DarkVibrant, Vibrant)) {
|
||||||
|
Vibrant = Vibrant.brighten();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// second pass - first doesn't always get it right.
|
||||||
|
if (badContrast(DarkVibrant, Vibrant) || badContrast(DarkVibrant, LightMuted)) {
|
||||||
|
DarkVibrant = DarkVibrant.darken();
|
||||||
|
if (badContrast(DarkVibrant, Vibrant)) {
|
||||||
|
Vibrant = Vibrant.brighten(2);
|
||||||
|
}
|
||||||
|
if (badContrast(DarkVibrant, LightMuted)) {
|
||||||
|
LightMuted = LightMuted.brighten(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (badContrast(DarkVibrant, Vibrant)){
|
||||||
|
console.log('contrast still too low', imagePath);
|
||||||
|
console.log(chalk.hex(Vibrant.hex()).bgHex(DarkVibrant.hex())(`DV-V: ${chroma.contrast(DarkVibrant, Vibrant)}`));
|
||||||
|
}
|
||||||
|
if (badContrast(DarkVibrant, LightMuted)){
|
||||||
|
console.log('contrast still too low', imagePath);
|
||||||
|
console.log(chalk.hex(LightMuted.hex()).bgHex(DarkVibrant.hex())(`DV-LM: ${chroma.contrast(DarkVibrant, LightMuted)}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
Vibrant: Vibrant.rgb(),
|
||||||
|
DarkVibrant: DarkVibrant.rgb(),
|
||||||
|
LightVibrant: LightVibrant.rgb(),
|
||||||
|
Muted: Muted.rgb(),
|
||||||
|
DarkMuted: DarkMuted.rgb(),
|
||||||
|
LightMuted: LightMuted.rgb(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function convertDMSToDD(dms, positiveDirection) {
|
function convertDMSToDD(dms, positiveDirection) {
|
||||||
const res = dms
|
const res = dms
|
||||||
@ -19,7 +69,7 @@ function convertDMSToDD(dms, positiveDirection) {
|
|||||||
return positiveDirection ? res : -res;
|
return positiveDirection ? res : -res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformMetaToNodeData(exifData, iptcData, vibrantData) {
|
function transformMetaToNodeData(exifData, iptcData, vibrantData, imagePath) {
|
||||||
const gps = { longitude: null, latitude: null };
|
const gps = { longitude: null, latitude: null };
|
||||||
|
|
||||||
if (exifData) {
|
if (exifData) {
|
||||||
@ -39,22 +89,7 @@ function transformMetaToNodeData(exifData, iptcData, vibrantData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const vbChroma = R.map((swatch) => (chroma(swatch.getRgb()))
|
const vibrant = processColors(vibrantData, imagePath);
|
||||||
, vibrantData);
|
|
||||||
|
|
||||||
|
|
||||||
if (chroma.contrast(vbChroma.DarkVibrant, vbChroma.Vibrant) < 4.5) {
|
|
||||||
// console.log('adjusting colors', chroma.contrast(vbChroma.DarkVibrant, vbChroma.Vibrant));
|
|
||||||
// console.log(vbChroma.DarkVibrant.hex());
|
|
||||||
// console.log(vbChroma.Vibrant.hex());
|
|
||||||
vbChroma.DarkVibrant = vbChroma.DarkVibrant.darken();
|
|
||||||
vbChroma.Vibrant = vbChroma.Vibrant.brighten();
|
|
||||||
// console.log('adjusted', chroma.contrast(vbChroma.DarkVibrant, vbChroma.Vibrant));
|
|
||||||
// console.log(vbChroma.DarkVibrant.hex());
|
|
||||||
// console.log(vbChroma.Vibrant.hex());
|
|
||||||
}
|
|
||||||
|
|
||||||
const vibrantRgb = R.map((color) => color.rgb(), vbChroma);
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -62,7 +97,7 @@ function transformMetaToNodeData(exifData, iptcData, vibrantData) {
|
|||||||
gps,
|
gps,
|
||||||
dateTaken: exifData?.exif?.DateTimeOriginal,
|
dateTaken: exifData?.exif?.DateTimeOriginal,
|
||||||
iptc: iptcData || undefined,
|
iptc: iptcData || undefined,
|
||||||
vibrant: vibrantRgb,
|
vibrant,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +117,7 @@ exports.onCreateNode = async function ({ node, getNode, actions }) {
|
|||||||
createNodeField({
|
createNodeField({
|
||||||
node,
|
node,
|
||||||
name: 'imageMeta',
|
name: 'imageMeta',
|
||||||
value: transformMetaToNodeData(exifData, iptcData, vibrantData),
|
value: transformMetaToNodeData(exifData, iptcData, vibrantData, parent.absolutePath),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"babel-plugin-preval": "^5.0.0",
|
"babel-plugin-preval": "^5.0.0",
|
||||||
"babel-plugin-styled-components": "^1.12.0",
|
"babel-plugin-styled-components": "^1.12.0",
|
||||||
|
"chalk": "^4.1.1",
|
||||||
"chroma-js": "^2.1.2",
|
"chroma-js": "^2.1.2",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
"eslint": "^7.28.0",
|
"eslint": "^7.28.0",
|
||||||
|
@ -3581,7 +3581,7 @@ chalk@^3.0.0:
|
|||||||
ansi-styles "^4.1.0"
|
ansi-styles "^4.1.0"
|
||||||
supports-color "^7.1.0"
|
supports-color "^7.1.0"
|
||||||
|
|
||||||
chalk@^4.0.0, chalk@^4.1.0:
|
chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad"
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad"
|
||||||
integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==
|
integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==
|
||||||
|
Loading…
x
Reference in New Issue
Block a user