142

親の背景画像または色の覆われたピクセルの平均輝度に応じて、テキストの色を変更したり、定義済みの画像/アイコンを切り替えたりするプラグインまたは手法を探しています。

背景の覆われた領域がかなり暗い場合は、テキストを白にするか、アイコンを切り替えます。

さらに、親に background-color または -image が定義されていない場合にスクリプトが認識し、最も近いもの (親要素からその親要素まで..) を検索し続けるとよいでしょう。

どう思いますか、このアイデアについて知っていますか? すでに似たようなものはありますか?例?

4

8 に答える 8

217

これに関する興味深いリソース:

これがW3Cアルゴリズムです(JSFiddleデモもあり):

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>

于 2012-08-08T15:38:24.210 に答える
95

色のコントラストの計算に関する 24 の方法に関するこの記事は、あなたにとって興味深いかもしれません。関数の最初のセットは間違っているため無視しますが、YIQ 式は明るい前景色を使用するか暗い前景色を使用するかを決定するのに役立ちます。

要素 (または先祖) の背景色を取得したら、この記事の関数を使用して、適切な前景色を決定できます。

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';
}
于 2012-08-08T15:52:34.273 に答える
16

興味深い質問です。すぐに思いついたのは、背景の色をテキストとして反転させることでした。これには、背景を解析してその 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+')');
于 2012-08-08T15:22:44.637 に答える
4

これが私の試みです:

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

それを使用するには:

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

これにより、テキストが適切に黒または白になります。アイコンを実行するには:

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

次に、各アイコンは のようになります'save' + iconSuffix + '.jpg'

これは、コンテナーがその親をオーバーフローしている場合には機能しないことに注意してください (たとえば、CSS の高さが 0 で、オーバーフローが非表示になっていない場合)。それを機能させるには、はるかに複雑になります。

于 2012-08-19T22:10:53.443 に答える