javascript - Hur kan jag generera motsatt färg enligt aktuell färg?
Jag försöker skapa en färg som är motsatsen till den aktuella färgen. Jag menar om den aktuella färgen är svart, då behöver jag generera vit.
Faktiskt har jag en text (färgen på denna text är dynamisk, dess färg kan göras slumpmässigt). Den texten är i en div och jag behöver sätta motsatt färg av den texten som background-color för div. Jag skulle vilja att texten är tydlig i div (färgperspektiv).
Den motsatta färgen betyder: Mörk/Ljus
Jag har den nuvarande färgen på texten och jag kan skicka den till denna funktion:
var TextColor = #F0F0F0; // for example (it is a bright color)
function create_opp_color(current color) {
// create opposite color according to current color
}
create_opp_color(TextColor); // this should be something like "#202020" (or a dark color)
Finns det någon idé att skapa create_opp_color()-funktionen?
Svar #1
UPPDATERING: Produktionsklar kod på GitHub.
Så här skulle jag göra det:
- Konvertera HEX till RGB
- Invertera R-, G- och B-komponenterna
- Konvertera varje komponent tillbaka till HEX
- Fyll varje komponent med nollor och skriv ut.
function invertColor(hex) {
if (hex.indexOf('#') === 0) {
hex = hex.slice(1);
}
// convert 3-digit hex to 6-digits.
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
if (hex.length !== 6) {
throw new Error('Invalid HEX color.');
}
// invert color components
var r = (255 - parseInt(hex.slice(0, 2), 16)).toString(16),
g = (255 - parseInt(hex.slice(2, 4), 16)).toString(16),
b = (255 - parseInt(hex.slice(4, 6), 16)).toString(16);
// pad each with zeros and return
return '#' + padZero(r) + padZero(g) + padZero(b);
}
function padZero(str, len) {
len = len || 2;
var zeros = new Array(len).join('0');
return (zeros + str).slice(-len);
}
Exempelutdata:
Avancerad version:
Detta har ett bw-alternativ som bestämmer om det ska inverteras till svart eller vitt; så du får mer kontrast vilket generellt är bättre för det mänskliga ögat.
function invertColor(hex, bw) {
if (hex.indexOf('#') === 0) {
hex = hex.slice(1);
}
// convert 3-digit hex to 6-digits.
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
if (hex.length !== 6) {
throw new Error('Invalid HEX color.');
}
var r = parseInt(hex.slice(0, 2), 16),
g = parseInt(hex.slice(2, 4), 16),
b = parseInt(hex.slice(4, 6), 16);
if (bw) {
// https://stackoverflow.com/a/3943023/112731
return (r * 0.299 + g * 0.587 + b * 0.114) > 186
? '#000000'
: '#FFFFFF';
}
// invert color components
r = (255 - r).toString(16);
g = (255 - g).toString(16);
b = (255 - b).toString(16);
// pad each with zeros and return
return "#" + padZero(r) + padZero(g) + padZero(b);
}
Exempelutdata:
Svar #2
Enkelt och elegant.
function invertHex(hex) {
return (Number(`0x1${hex}`) ^ 0xFFFFFF).toString(16).substr(1).toUpperCase()
}
invertHex('00FF00'); // Returns FF00FF
Svar #3
Enkel sätt att uppnå detta med CSS:
mix-blend-mode: difference;
color:white;
Svar #4
Ren CSS-implementering av @Onurs svar bw-del.
<input type="color" oninput="['--r','--g','--b'].forEach((k,i)=>this.nextElementSibling.style.setProperty(k,parseInt(event.target.value.slice(1+i*2,3+i*2),16)))" />
<div style="--r: 0; --g: 0; --b: 0; --c: calc(-1 * ((var(--r) * 0.299 + var(--g) * 0.587 + var(--b) * 0.114) - 186) * 255)">
<div style="background-color: rgb(var(--r), var(--g), var(--b)); color: rgb(var(--c), var(--c), var(--c))">Test</div>
</div>Svar #5
Vad sägs om, CSS filter: invert(1), det har en god kompatibilitet mellan olika webbläsare och det fungerar med text och bilder eller vad ditt innehåll än är.
För en svartvit inverterad färg, lägg till några fler filter, filter: saturate(0) grayscale(1) brightness(.7) contrast(1000%) invert(1)
Här är ett exempel på ColorPicker (Observera textfärgen):
const colorPicker = document.querySelector("input");
const background = document.querySelector("div");
const invertedText = document.querySelector("b");
colorPicker.oninput = (e) => {
const color = e.target.value;
background.style.background = color;
invertedText.style.color = color;
invertedText.innerText = color;
}body {
font-family: Arial;
background: #333;
}
div {
position: relative;
display: inline-flex;
justify-content: center;
align-items: center;
min-width: 100px;
padding: .5em 1em;
border: 2px solid #FFF;
border-radius: 15px;
background: #378ad3;
}
b {
/* Inverting the color ᐯᐯᐯᐯᐯᐯᐯᐯᐯᐯᐯᐯ */
filter: saturate(0) grayscale(1) brightness(.7) contrast(1000%) invert(1);
}
input {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}<div>
<b>#378ad3</b>
<input type="color" value="#378ad3"/>
</div>
