mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 19:08:58 +03:00
Update user id color generation
Update the author color generation. Now, instead of generating an entire hex string based on the user id, the user id instead is used to generate a hue value. After this hue value is created, there is some logic to tweak first the lightness and then saturation values to achieve a readable color (in contrast to the background). This change makes it so that user colors will not vary as wildly between the different themes. The values still are not cached and still do not update initially when the theme is changed. Both of these things will be resolved.
This commit is contained in:
parent
98102f4f09
commit
b3f7c13e2f
2 changed files with 69 additions and 61 deletions
122
src/Utils.cpp
122
src/Utils.cpp
|
@ -382,19 +382,6 @@ utils::linkColor()
|
||||||
return QPalette().color(QPalette::Link).name();
|
return QPalette().color(QPalette::Link).name();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
|
||||||
utils::generateHexColor(const int hash)
|
|
||||||
{
|
|
||||||
QString colour("#");
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
int value = (hash >> (i * 8)) & 0xFF;
|
|
||||||
colour.append(("00" + QString::number(value, 16)).right(2));
|
|
||||||
}
|
|
||||||
// nhlog::ui()->debug("Hex Generated {} -> {}", QString::number(hash).toStdString(),
|
|
||||||
// colour.toStdString());
|
|
||||||
return colour.toUpper();
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
utils::hashQString(const QString &input)
|
utils::hashQString(const QString &input)
|
||||||
{
|
{
|
||||||
|
@ -404,8 +391,6 @@ utils::hashQString(const QString &input)
|
||||||
hash = input.at(i).digitValue() + ((hash << 5) - hash);
|
hash = input.at(i).digitValue() + ((hash << 5) - hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
hash *= 13;
|
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,58 +403,83 @@ utils::generateContrastingHexColor(const QString &input, const QString &backgrou
|
||||||
|
|
||||||
// Create a color for the input
|
// Create a color for the input
|
||||||
auto hash = hashQString(input);
|
auto hash = hashQString(input);
|
||||||
auto colorHex = generateHexColor(hash);
|
// create a hue value based on the hash of the input.
|
||||||
|
auto userHue = qAbs(hash % 360);
|
||||||
|
nhlog::ui()->debug(
|
||||||
|
"User Hue {} : {}", input.toStdString(), QString::number(userHue).toStdString());
|
||||||
|
// start with moderate saturation and lightness values.
|
||||||
|
auto sat = 220;
|
||||||
|
auto lightness = 125;
|
||||||
|
|
||||||
// converting to a QColor makes the luminance calc easier.
|
// converting to a QColor makes the luminance calc easier.
|
||||||
QColor inputColor = QColor(colorHex);
|
QColor inputColor = QColor::fromHsl(userHue, sat, lightness);
|
||||||
|
|
||||||
// attempt to score both the luminance and the contrast.
|
// calculate the initial luminance and contrast of the
|
||||||
// contrast should have a higher precedence, but luminance
|
// generated color. It's possible that no additional
|
||||||
// helps dictate how exciting the colors are.
|
// work will be necessary.
|
||||||
auto colorLum = luminance(inputColor);
|
auto lum = luminance(inputColor);
|
||||||
auto contrast = computeContrast(colorLum, backgroundLum);
|
auto contrast = computeContrast(lum, backgroundLum);
|
||||||
|
|
||||||
// If the contrast or luminance don't meet our criteria,
|
// If the contrast doesn't meet our criteria,
|
||||||
// try again and again until they do. After 10 tries,
|
// try again and again until they do by modifying first
|
||||||
// the best-scoring color will be chosen.
|
// the lightness and then the saturation of the color.
|
||||||
int att = 0;
|
while (contrast < 5) {
|
||||||
while ((contrast < 5 || (colorLum < 0.05 || colorLum > 0.95)) && ++att < 10) {
|
// if our lightness is at it's bounds, try changing
|
||||||
hash = hashQString(input) + ((hash << 2) * 13);
|
// saturation instead.
|
||||||
auto newHex = generateHexColor(hash);
|
if (lightness == 242 || lightness == 13) {
|
||||||
inputColor.setNamedColor(newHex);
|
qreal newSat = qBound(26.0, sat * 1.25, 242.0);
|
||||||
|
nhlog::ui()->info("newSat {}", QString::number(newSat).toStdString());
|
||||||
|
|
||||||
|
inputColor.setHsl(userHue, qFloor(newSat), lightness);
|
||||||
auto tmpLum = luminance(inputColor);
|
auto tmpLum = luminance(inputColor);
|
||||||
auto tmpContrast = computeContrast(tmpLum, backgroundLum);
|
auto higherContrast = computeContrast(tmpLum, backgroundLum);
|
||||||
|
if (higherContrast > contrast) {
|
||||||
|
contrast = higherContrast;
|
||||||
|
sat = newSat;
|
||||||
|
} else {
|
||||||
|
newSat = qBound(26.0, sat / 1.25, 242.0);
|
||||||
|
inputColor.setHsl(userHue, qFloor(newSat), lightness);
|
||||||
|
tmpLum = luminance(inputColor);
|
||||||
|
auto lowerContrast = computeContrast(tmpLum, backgroundLum);
|
||||||
|
if (lowerContrast > contrast) {
|
||||||
|
contrast = lowerContrast;
|
||||||
|
sat = newSat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qreal newLightness = qBound(13.0, lightness * 1.25, 242.0);
|
||||||
|
|
||||||
// Prioritize contrast over luminance
|
inputColor.setHsl(userHue, sat, qFloor(newLightness));
|
||||||
// If both values are better, it's a no brainer.
|
|
||||||
if (tmpContrast > contrast && (tmpLum > 0.05 && tmpLum < 0.95)) {
|
auto tmpLum = luminance(inputColor);
|
||||||
contrast = tmpContrast;
|
auto higherContrast = computeContrast(tmpLum, backgroundLum);
|
||||||
colorHex = newHex;
|
|
||||||
colorLum = tmpLum;
|
// Check to make sure we have actually improved contrast
|
||||||
}
|
if (higherContrast > contrast) {
|
||||||
// Otherwise, if we still can get a more
|
contrast = higherContrast;
|
||||||
// vibrant color and have met our contrast
|
lightness = newLightness;
|
||||||
// threshold, pick the more vibrant color,
|
// otherwise, try going the other way instead.
|
||||||
// even if contrast will drop somewhat.
|
} else {
|
||||||
// choosing 50% luminance as ideal.
|
newLightness = qBound(13.0, lightness / 1.25, 242.0);
|
||||||
else if ((qAbs(tmpLum - 0.50) < qAbs(colorLum - 0.50)) && tmpContrast >= 5) {
|
inputColor.setHsl(userHue, sat, qFloor(newLightness));
|
||||||
contrast = tmpContrast;
|
tmpLum = luminance(inputColor);
|
||||||
colorHex = newHex;
|
auto lowerContrast = computeContrast(tmpLum, backgroundLum);
|
||||||
colorLum = tmpLum;
|
if (lowerContrast > contrast) {
|
||||||
}
|
contrast = lowerContrast;
|
||||||
// Otherwise, just take the better contrast.
|
lightness = newLightness;
|
||||||
else if (tmpContrast > contrast) {
|
|
||||||
contrast = tmpContrast;
|
|
||||||
colorHex = newHex;
|
|
||||||
colorLum = tmpLum;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the hex value of the generated color.
|
||||||
|
auto colorHex = inputColor.name();
|
||||||
|
|
||||||
nhlog::ui()->debug("Hex Generated for {}: [hex: {}, contrast: {}, luminance: {}]",
|
nhlog::ui()->debug("Hex Generated for {}: [hex: {}, contrast: {}, luminance: {}]",
|
||||||
input.toStdString(),
|
input.toStdString(),
|
||||||
colorHex.toStdString(),
|
colorHex.toStdString(),
|
||||||
QString::number(contrast).toStdString(),
|
QString::number(contrast).toStdString(),
|
||||||
QString::number(colorLum).toStdString());
|
QString::number(lum).toStdString());
|
||||||
return colorHex;
|
return colorHex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,7 +506,9 @@ utils::luminance(const QColor &col)
|
||||||
v <= 0.03928 ? lumRgb[i] = v / 12.92 : lumRgb[i] = qPow((v + 0.055) / 1.055, 2.4);
|
v <= 0.03928 ? lumRgb[i] = v / 12.92 : lumRgb[i] = qPow((v + 0.055) / 1.055, 2.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
return lumRgb[0] * 0.2126 + lumRgb[1] * 0.7152 + lumRgb[2] * 0.0722;
|
auto lum = lumRgb[0] * 0.2126 + lumRgb[1] * 0.7152 + lumRgb[2] * 0.0722;
|
||||||
|
|
||||||
|
return lum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -229,10 +229,6 @@ markdownToHtml(const QString &text);
|
||||||
QString
|
QString
|
||||||
linkColor();
|
linkColor();
|
||||||
|
|
||||||
//! Given an input integer, create a color string in #RRGGBB format
|
|
||||||
QString
|
|
||||||
generateHexColor(const int hash);
|
|
||||||
|
|
||||||
//! Returns the hash code of the input QString
|
//! Returns the hash code of the input QString
|
||||||
int
|
int
|
||||||
hashQString(const QString &input);
|
hashQString(const QString &input);
|
||||||
|
|
Loading…
Reference in a new issue