这是一个从TypeScript翻译过来的算法。
该算法适用于Avatar显示的场景下,假如头像图片不存在的情况下,根据用户名来算出一个显示的背景色。
其运行的效果如下:
import 'package:flutter/material.dart';
/// 字符串到十六进制代码颜色
/// 翻译自TypeScript库:https://github.com/HugoJBello/string-to-hex-code-color
/// 在线转换工具:https://string-to-hex-code-color.firebaseapp.com/
class String2HexCodeColor {
double defaultShadePercentage = 0;
String2HexCodeColor({double? defaultShadePercentage}) {
if (defaultShadePercentage != null) {
this.defaultShadePercentage = defaultShadePercentage;
}
}
_shadeColor(String color, double? percent) {
percent ??= defaultShadePercentage;
final f = int.parse(color.substring(1), radix: 16);
final t = percent < 0 ? 0 : 255;
final p = percent < 0 ? percent * -1 : percent;
final R = f >> 16;
final G = f >> 8 & 0x00FF;
final B = f & 0x0000FF;
final n1 = ((t - R) * p).round();
final n2 = ((t - G) * p).round();
final n3 = ((t - B) * p).round();
final total = 0x1000000 + (n1 + R) * 0x10000 + (n2 + G) * 0x100 + (n3 + B);
final result = '#${total.toRadixString(16).substring(1)}';
return result;
}
int _hash(String text) {
int hash = 0;
for (int i = 0; i < text.length; i++) {
final char = text.codeUnitAt(i);
hash = char + ((hash << 5) - hash);
}
return hash;
}
_preHash(String text) {
int hash = 0;
if (text.isEmpty) {
return hash;
}
for (int i = 0; i < text.length; i++) {
final char = text.codeUnitAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
static Color fromHex(String hexString) {
final buffer = StringBuffer();
if (hexString.length == 6 || hexString.length == 7) buffer.write('ff');
buffer.write(hexString.replaceFirst('#', ''));
return Color(int.parse(buffer.toString(), radix: 16));
}
Color stringToColor(String text, {double? shadePercentage}) {
if (text.length < 4) {
text = text + _preHash(text).toString();
}
var hash = _hash(text);
String colour = '#';
for (int i = 0; i < 3; i++) {
final value = (hash >> (i * 8)) & 0xFF;
String str = value.toRadixString(16).padLeft(2, '0');
str = '00$str';
colour += str.substring(str.length - 2);
}
if (shadePercentage != null || (defaultShadePercentage != 0)) {
colour = _shadeColor(colour, shadePercentage);
}
// debugPrint('[$text] 颜色值: $colour');
return fromHex(colour);
}
}
测试代码:
void main() {
group("String2HexCodeColor", () {
test('color test', () async {
final string2HexCodeColor = String2HexCodeColor();
Color cName = string2HexCodeColor.stringToColor("name");
debugPrint('name: $cName');
expect(cName, const Color(0xff8b7a33));
final cA = string2HexCodeColor.stringToColor("a");
expect(cA, const Color(0xff3f7301));
debugPrint('a: $cA');
final cB = string2HexCodeColor.stringToColor("b");
expect(cB, const Color(0xff017701));
debugPrint('b: $cB');
final cC = string2HexCodeColor.stringToColor("c");
expect(cC, const Color(0xffc37a01));
debugPrint('c: $cC');
});
test('shade test', () async {
final string2HexCodeColor = String2HexCodeColor();
expect(string2HexCodeColor.stringToColor("a", shadePercentage: 0.5), const Color(0xff9fb980));
expect(string2HexCodeColor.stringToColor("a", shadePercentage: 0.2), const Color(0xff658f34));
expect(string2HexCodeColor.stringToColor("a"), const Color(0xff3f7301));
expect(string2HexCodeColor.stringToColor("a", shadePercentage: -0.2), const Color(0xff325c01));
expect(string2HexCodeColor.stringToColor("a", shadePercentage: -0.5), const Color(0xff1f3900));
});
});
}