Skip to content

Commit

Permalink
fix: account for when no good color can be found (#64)
Browse files Browse the repository at this point in the history
Co-authored-by: Liam DeBeasi <[email protected]>
  • Loading branch information
liamdebeasi and liamdebeasi authored Apr 12, 2024
1 parent abce934 commit f38d274
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 16 deletions.
16 changes: 2 additions & 14 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<script setup lang="ts">
import { ref, watch } from 'vue';
import { ColorContrastCalc } from 'color-contrast-calc';
import { computeContrast } from './utils';
import { computeContrast, computeFallbackColors } from './utils';
import DropperButton from './components/DropperButton.vue';
import CopyButton from './components/CopyButton.vue';
Expand Down Expand Up @@ -86,18 +85,7 @@ watch([foreground, background], () => {
* Compare white text and black text contrast on chosen
* background and use whichever one has the higher ratio.
*/
const whiteForegroundRGB = ColorContrastCalc.colorFrom('#ffffff');
const blackForegroundRGB = ColorContrastCalc.colorFrom('#000000');
const backgroundRGB = ColorContrastCalc.colorFrom(background.value);
const whiteRatio = whiteForegroundRGB.contrastRatioAgainst(backgroundRGB);
const blackRatio = blackForegroundRGB.contrastRatioAgainst(backgroundRGB);
if (whiteRatio >= blackRatio) {
foregroundTextColor.value = backgroundTextColor.value = '#ffffff';
} else {
foregroundTextColor.value = backgroundTextColor.value = '#000000';
}
foregroundTextColor.value = backgroundTextColor.value = computeFallbackColors(background.value);
} else {
foregroundTextColor.value = background.value;
backgroundTextColor.value = foreground.value;
Expand Down
15 changes: 13 additions & 2 deletions src/components/AdjustButton.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { colorWand, checkmark } from 'ionicons/icons';
import { computeContrast } from '../utils';
import { computeContrast, computeFallbackColors } from '../utils';
import { ColorContrastCalc } from 'color-contrast-calc';
import { ref } from 'vue';
Expand All @@ -16,7 +16,18 @@
const foregroundColor = ColorContrastCalc.colorFrom(props.foreground);
const backgroundColor = ColorContrastCalc.colorFrom(props.modelValue);
const adjustedBackgroundColor = foregroundColor.findBrightnessThreshold(backgroundColor, 'AA');
let adjustedBackgroundColor = foregroundColor.findBrightnessThreshold(backgroundColor, 'AA');
/**
* Sometimes findBrightnessThreshold can't find a color with sufficient contrast.
* When that happens use either #000 or #fff, whichever has the higher contrast.
*/
const computeContrastAgain = computeContrast(props.foreground, adjustedBackgroundColor.hexCode);
if (computeContrastAgain < 4.5) {
const fallbackColor = computeFallbackColors(props.modelValue);
adjustedBackgroundColor = ColorContrastCalc.colorFrom(fallbackColor);
}
emit('update:modelValue', adjustedBackgroundColor.hexCode);
}
Expand Down
19 changes: 19 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,23 @@ export const computeContrast = (foreground: string, background: string) => {
* because a ratio of 4.995 should not be rounded up to 4.5.
*/
return ratio.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0];
}

export const computeFallbackColors = (background: string) => {
/**
* Compare white text and black text contrast on chosen
* background and use whichever one has the higher ratio.
*/
const whiteForegroundRGB = ColorContrastCalc.colorFrom('#ffffff');
const blackForegroundRGB = ColorContrastCalc.colorFrom('#000000');
const backgroundRGB = ColorContrastCalc.colorFrom(background);

const whiteRatio = whiteForegroundRGB.contrastRatioAgainst(backgroundRGB);
const blackRatio = blackForegroundRGB.contrastRatioAgainst(backgroundRGB);

if (whiteRatio >= blackRatio) {
return '#ffffff';
} else {
return '#000000';
}
}

0 comments on commit f38d274

Please sign in to comment.