🎨

【Dart】文字色が白に合う背景色を生成する

2022/11/27に公開

概要

ちょっとニッチな課題かもしれないですが、Flutterアプリを作っていて文字色が白で、白が映える背景色をランダムに生成する必要があったので試してみました。

参考

JavaScriptで背景色から適した文字色が白か黒かを判定する方法
↑こちらを参考に考えて行きたいと思います。

W3Cで公開されているアルゴリズムというものがあるそうで、そのアルゴリズムを
Javascriptで実装すると以下になるそうです。

function blackOrWhite ( hexcolor ) {
	var r = parseInt( hexcolor.substr( 1, 2 ), 16 ) ;
	var g = parseInt( hexcolor.substr( 3, 2 ), 16 ) ;
	var b = parseInt( hexcolor.substr( 5, 2 ), 16 ) ;

	return ( ( ( (r * 299) + (g * 587) + (b * 114) ) / 1000 ) < 128 ) ? "white" : "black" ;
}

var color = blackOrWhite( "#d36015" ) ;

このアルゴリズムから逆に白色に合う背景色を生成する実装をJavaScriptで書いてみます

( ( (r * 299) + (g * 587) + (b * 114) ) / 1000 )128 より小さいと文字色は白色になるので、
ランダム値を生成しつつ 128 より小さくなるように調整します。

const getRandam = (n: number, m: number): number => Math.floor(Math.random() * (m + 1 - n)) + n;
const toHex = (r: number, g: number, b: number): string => {
    return `#${r.toString(16).toUpperCase()}${g.toString(16).toUpperCase()}${b.toString(16).toUpperCase()}`;
}

const r = getRandam(0, 255);
let temp = 128000 - r * 299;
const g = getRandam(0, 255);
temp = temp - g * 587;
const b = Math.max(Math.min(Math.floor(temp / 114), 255), 0);
console.log(toHex(r, g, b));

こんな感じでしょうか... これをDartのコードに落とし込んで行きたいと思います。

import 'dart:math' as math;

String toHex(int r, int g, int b) {
  return '#${r.toRadixString(16).padLeft(2, "0")}${g.toRadixString(16).padLeft(2, "0")}${b.toRadixString(16).padLeft(2, "0")}';  
}

void main() {
  var rand = new math.Random();
  
  for (int i = 0; i < 10; i++) {
    int r = rand.nextInt(255);
    var temp = 128000 - r * 299;
    int g = rand.nextInt(255);
    temp = temp - g * 587;
    int b = math.max(math.min((temp / 114).floor(), 255), 0);
    String hex = toHex(r, g, b);
    print(hex);
  }
}

実行結果としては↓になりました。パッと見、文字色が白でも映えそうな感じはします :eyes:
(もっとバラけさせるように改良できそうですが....)

逆にダークモードの時などは、黒に映える背景色など応用が効きそうです。
もしかしたら既存のものがあるかもですが、今回は勉強も兼ねて試してみました。

その他の参考URL

Discussion