Pomyślałem o następujących już na chwilę, więc teraz chcę poznać twoje opinie, możliwe rozwiązania i tak dalej.

Szukam wtyczki lub techniki, która zmienia kolor tekstu lub przełącza między predefiniowanymi obrazami / ikonami w zależności od średniej jasności zadaszonych pikseli z tła rodzica lub -Coloru.

Jeśli obszar zadaszony jest dość ciemny, wykonaj tekst biały lub przełączyć ikony.

Dodatkowo byłoby wspaniale, jeśli skrypt zauważy, czy rodzic nie ma zdefiniowanego koloru tła lub -obraz, a następnie kontynuować wyszukiwanie najbliższe (od elementu macierzystego do elementu macierzystego ..).

Jak myślisz, wiem o tym pomysłem? Czy jest już coś podobnego? Skrypt - przykłady?

Cheers, J.

136
James Cazzetta 8 sierpień 2012, 19:08

7 odpowiedzi

Najlepsza odpowiedź

Ciekawe zasoby dla tego:

Oto algorytm W3C (z JSFiddle Demo też):

const rgb = [255, 0, 0];

// Randomly change to showcase updates
setInterval(setContrast, 1000);

function setContrast() {
  // Randomly update colours
  rgb[0] = Math.round(Math.random() * 255);
  rgb[1] = Math.round(Math.random() * 255);
  rgb[2] = Math.round(Math.random() * 255);

  // http://www.w3.org/TR/AERT#color-contrast
  const brightness = Math.round(((parseInt(rgb[0]) * 299) +
                      (parseInt(rgb[1]) * 587) +
                      (parseInt(rgb[2]) * 114)) / 1000);
  const textColour = (brightness > 125) ? 'black' : 'white';
  const backgroundColour = 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
  $('#bg').css('color', textColour); 
  $('#bg').css('background-color', backgroundColour);
}
#bg {
  width: 200px;
  height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="bg">Text Example</div>
187
Edwin Pratt 11 marzec 2020, 03:11

W tym artykule na 24 sposoby na obliczający kontrast kolorów może być zainteresowany Ciebie. Ignoruj pierwszy zestaw funkcji, ponieważ są błędne, ale formuła Yiq pomoże Ci ustalić, czy używać lekkiego lub ciemnego koloru pierwszego planu.

Po uzyskaniu koloru tła elementu (lub przodków) można użyć tej funkcji z artykułu, aby określić odpowiedni kolor pierwszego planu:

function getContrastYIQ(hexcolor){
    hexcolor = hexcolor.replace("#", "");
    var r = parseInt(hexcolor.substr(0,2),16);
    var g = parseInt(hexcolor.substr(2,2),16);
    var b = parseInt(hexcolor.substr(4,2),16);
    var yiq = ((r*299)+(g*587)+(b*114))/1000;
    return (yiq >= 128) ? 'black' : 'white';
}
74
radu122 7 czerwiec 2019, 11:59

Interesujące pytanie. Moją najbliższą myślą było odwrócenie koloru tła jako tekstu. Obejmuje to po prostu parsowanie tła i odwracając wartość RGB.

Coś takiego: http://jsfiddle.net/2vtnz/2/

var rgb = $('#test').css('backgroundColor');
var colors = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
var brightness = 1;

var r = colors[1];
var g = colors[2];
var b = colors[3];

var ir = Math.floor((255-r)*brightness);
var ig = Math.floor((255-g)*brightness);
var ib = Math.floor((255-b)*brightness);

$('#test').css('color', 'rgb('+ir+','+ig+','+ib+')');
15
Shaz 19 sierpień 2012, 22:04

mix-blend-mode Czy sztuczka:

header {
  overflow: hidden;
  height: 100vh;
  background: url(https://www.w3schools.com/html/pic_mountain.jpg) 50%/cover;
}

h2 {
  color: white;
  font: 900 35vmin/50vh arial;
  text-align: center;
  mix-blend-mode: difference;
  filter: drop-shadow(0.05em 0.05em orange);
}
<header>
  <h2 contentEditable role='textbox' aria-multiline='true' >Edit me here</h2>
</header>

Dodatek (marzec 2018): Podążając, ładny samouczek wyjaśniający wszystkie różne rodzaje trybów / implementacji: https://css-tricks.com/css-techniques-and-Effects-for-knockout-text/.

11
James Cazzetta 8 marzec 2018, 12:52

Znalazłem tła skrypt, aby być bardzo przydatnym.

Wykrywa overal jasność tła (czy to obraz tła lub kolor) i stosuje klasę do przypisanego elementu tekstowego (background--light lub background--dark), zależne od jasności tła .

Może być stosowany do elementów nieruchomych i ruchomych.

(Źródło)

5
cptstarling 3 wrzesień 2015, 15:10

Jeśli używasz ES6, konwertuj HEX do RGB, a następnie można użyć tego:

const hexToRgb = hex => {
    // turn hex val to RGB
    const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
    return result
        ? {
              r: parseInt(result[1], 16),
              g: parseInt(result[2], 16),
              b: parseInt(result[3], 16)
          }
        : null
}

// calc to work out if it will match on black or white better
const setContrast = rgb =>
    (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000 > 125 ? 'black' : 'white'

const getCorrectColor = setContrast(hexToRgb(#ffffff))
5
rjb 15 sierpień 2019, 18:32

Oto moja próba:

(function ($) {
    $.fn.contrastingText = function () {
        var el = this,
            transparent;
        transparent = function (c) {
            var m = c.match(/[0-9]+/g);
            if (m !== null) {
                return !!m[3];
            }
            else return false;
        };
        while (transparent(el.css('background-color'))) {
            el = el.parent();
        }
        var parts = el.css('background-color').match(/[0-9]+/g);
        this.lightBackground = !!Math.round(
            (
                parseInt(parts[0], 10) + // red
                parseInt(parts[1], 10) + // green
                parseInt(parts[2], 10) // blue
            ) / 765 // 255 * 3, so that we avg, then normalize to 1
        );
        if (this.lightBackground) {
            this.css('color', 'black');
        } else {
            this.css('color', 'white');
        }
        return this;
    };
}(jQuery));

Następnie, aby go użyć:

var t = $('#my-el');
t.contrastingText();

Zostanie to od razu, wykonaj tekst czarny lub biały odpowiednio. Aby zrobić ikony:

if (t.lightBackground) {
    iconSuffix = 'black';
} else {
    iconSuffix = 'white';
}

Wtedy każda ikona może wyglądać jak 'save' + iconSuffix + '.jpg'.

Należy zauważyć, że nie działa, gdy którykolwiek pojemnik przepełnia rodzic (na przykład, jeśli wysokość CSS wynosi 0, a przepełnienie nie jest ukryte). Aby uzyskać pracę, byłoby dużo bardziej złożone.

4
Tammy Tee 28 styczeń 2020, 17:55