Изменить цвет текста на основе яркости покрытой фоновой области?



Я уже некоторое время думал о следующем, поэтому теперь я хочу знать Ваше мнение, возможные решения и так далее.



Я ищу плагин или метод, который изменяет цвет текста или переключается между предопределенными изображениями/значками в зависимости от средней яркости покрытых пикселей его родительского фонового изображения или цвета.



Если покрытая область его фона довольно темная, сделайте текст белым или переключите значки.



кроме того, было бы здорово, если бы скрипт заметил, что у родителя нет определенного цвета фона или изображения, а затем продолжил поиск наиболее близкого (от родительского элемента до его родительского элемента..).



Что вы думаете, знаете об этой идее? Есть ли что-то подобное там уже? сценарий-примеры?



Ура, Ж.

721   7  

7 ответов:

Интересные ресурсы для этого:

вот алгоритм W3C (с JSFiddle демо тоже):

var rgb = [255, 0, 0];

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

function setContrast() {
  // randomly update
  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
  var o = Math.round(((parseInt(rgb[0]) * 299) +
                      (parseInt(rgb[1]) * 587) +
                      (parseInt(rgb[2]) * 114)) / 1000);
  var fore = (o > 125) ? 'black' : 'white';
  var back = 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
  $('#bg').css('color', fore); 
  $('#bg').css('background-color', back);
  

}
#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>

эта статья о 24 способах Расчет Цветовой Контраст может быть вам интересно. Игнорируйте первый набор функций, потому что они неверны, но формула YIQ поможет вам определить, следует ли использовать светлый или темный цвет переднего плана.

Как только вы получите цвет фона элемента (или предка), вы можете использовать эту функцию из статьи, чтобы определить подходящий цвет переднего плана:

function getContrastYIQ(hexcolor){
    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';
}

интересный вопрос. Моя непосредственная мысль состояла в том, чтобы инвертировать цвет фона в качестве текста. Это включает в себя простой анализ фона и инвертирование его значения RGB.

что-то вроде этого: 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+')');

Я нашел BackgroundCheck скрипт будет очень полезен.

он определяет общую яркость фона (будь то фоновое изображение или цвет) и применяет класс к назначенному текстовому элементу (background--light или background--dark), зависит от яркости фона.

Он может быть применен к неподвижным и подвижным элементам.

(источник)

вот моя попытка:

(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();
        }
        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 normalise to 1
        );
        if (this.lightBackground) {
            this.css('color', 'black');
        } else {
            this.css('color', 'white');
        }
        return this;
    };
}(jQuery));

затем использовать это:

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

это будет сразу, сделать текст либо черный или белый, как это необходимо. Чтобы сделать значки:

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

тогда каждый значок может выглядеть как 'save' + iconSuffix + '.jpg'.

обратите внимание, что это не будет работать, когда какой-либо контейнер переполняет своего родителя (например, если высота CSS равна 0, и переполнение не скрыто). Чтобы получить эту работу было бы намного сложнее.

mix-blend-mode не работает:

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>

Дополнение (Март 2018): Далее, хороший учебник, объясняющий все различные типы режимов / реализаций:https://css-tricks.com/css-techniques-and-effects-for-knockout-text/

Если вы используете ES6, преобразуйте hex в RBG, а затем можете использовать это:

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))

Comments

    Ничего не найдено.