JSFiddle - React, Tailwind, and code Playground

by Sergei Sokolov

HTML

<div id="testBlock">Lorem ipsum</div>
# <input type="text" id="in-color">
<div>
  <label><input name="method" type="radio" value="a" checked> гипотеза 1</label>
  <br >
  <label><input name="method" type="radio" value="b"> гипотеза 2</label>
</div>

CSS

#testBlock {
    width: 128px;
    height: 64px;
    background: #000;
    color: #fff;
    margin-bottom: 16px;
    text-align: center;
}

JavaScript

/**
 * для вопроса https://qna.habr.com/q/818783
 * Как правильно составить алгоритм, 
 * чтобы цвет текста подбирался под цвет заднего фона?
 */
const elInput = document.getElementById('in-color');
const elDiv = document.getElementById('testBlock');
const radios = document.getElementsByName('method');

const update = () => {
	const inputString = elInput.value;
  if (![3,6].includes(inputString.length)) return;
  
  let inputColor = inputString;
  if (inputColor.length === 3) {
  	inputColor = inputColor.split('').map(c => c.repeat(2)).join('');
  }
  
  let method;
	[...radios].forEach(el => el.checked ? method = el.value : null);

	const textColor = methods[method](inputColor);
  
  elDiv.style.color = `#${textColor}`;
  elDiv.style.backgroundColor = `#${inputColor}`;
}

const complement = (n) => n > 127 ? 0 : 255;
const methods = {};
methods.a = color => {
  const r = parseInt(color.substr(0,2), 16);
  const g = parseInt(color.substr(2,2), 16);
  const b = parseInt(color.substr(4,2), 16);
  
  return [r, g, b]
  	.map(c => complement(c).toString(16).padStart(2, '0'))
  	.join('');  
}

methods.b = color => {
  const r = parseInt(color.substr(0,2), 16);
  const g = parseInt(color.substr(2,2), 16);
  const b = parseInt(color.substr(4,2), 16);
  
  // src: https://stackoverflow.com/a/596243/556876
  const luma = Math.sqrt(0.299*r*r + 0.587*g*g + 0.114*b*b);
  
  return luma > 127 ? '000000' : 'FFFFFF';
}

elInput.addEventListener('input', update);