mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-08 23:08:35 +07:00
Recognize uncontrasting colors for nations according to WCAG guidelines, and suggest tinted versions to conform
This commit is contained in:
@ -174,8 +174,8 @@
|
||||
"neutralHello": "Hello.",
|
||||
"hateHello": "It's you.",
|
||||
"tradeRequest": "France offers you this exceptional proposition.",
|
||||
"outerColor": [65, 141, 254],
|
||||
"innerColor": [235, 235, 139],
|
||||
"outerColor": [58, 126, 228],
|
||||
"innerColor": [237, 237, 150],
|
||||
"favoredReligion": "Christianity",
|
||||
"uniqueName": "Ancien Régime",
|
||||
"uniques": ["[+2 Culture] [in all cities] <before discovering [Steam Power]>"],
|
||||
|
@ -163,8 +163,8 @@
|
||||
"neutralHello": "Hello.",
|
||||
"hateHello": "It's you.",
|
||||
"tradeRequest": "France offers you this exceptional proposition.",
|
||||
"outerColor": [65, 141, 254],
|
||||
"innerColor": [235, 235, 139],
|
||||
"outerColor": [58, 126, 228],
|
||||
"innerColor": [237, 237, 150],
|
||||
"uniqueName": "Ancien Régime",
|
||||
"uniques": ["[+2 Culture] [in all cities] <before discovering [Steam Power]>"],
|
||||
"cities": ["Paris","Orleans","Lyon","Troyes","Tours","Marseille","Chartres","Avignon","Rouen","Grenoble",
|
||||
|
@ -11,8 +11,9 @@ import com.unciv.ui.civilopedia.CivilopediaScreen.Companion.showReligionInCivilo
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import com.unciv.ui.utils.extensions.colorFromRGB
|
||||
import kotlin.math.pow
|
||||
|
||||
class Nation : RulesetObject() {
|
||||
class Nation : RulesetObject() {
|
||||
var leaderName = ""
|
||||
fun getLeaderDisplayName() = if (isCityState()) name
|
||||
else "[$leaderName] of [$name]"
|
||||
@ -285,4 +286,28 @@ class Nation : RulesetObject() {
|
||||
}
|
||||
}
|
||||
|
||||
fun getContrastRatio() = getContrastRatio(getInnerColor(), getOuterColor())
|
||||
}
|
||||
|
||||
|
||||
/** All defined by https://www.w3.org/TR/WCAG20/#relativeluminancedef */
|
||||
fun getRelativeLuminance(color:Color):Double{
|
||||
fun getRelativeChannelLuminance(channel:Float):Double =
|
||||
if (channel < 0.03928) channel / 12.92
|
||||
else ((channel + 0.055) / 1.055).pow(2.4)
|
||||
|
||||
val R = getRelativeChannelLuminance(color.r)
|
||||
val G = getRelativeChannelLuminance(color.g)
|
||||
val B = getRelativeChannelLuminance(color.b)
|
||||
|
||||
return 0.2126 * R + 0.7152 * G + 0.0722 * B
|
||||
}
|
||||
|
||||
/** https://www.w3.org/TR/WCAG20/#contrast-ratiodef */
|
||||
fun getContrastRatio(color1:Color, color2:Color): Double { // ratio can range from 1 to 21
|
||||
val innerColorLuminance = getRelativeLuminance(color1)
|
||||
val outerColorLuminance = getRelativeLuminance(color2)
|
||||
|
||||
return if (innerColorLuminance > outerColorLuminance) (innerColorLuminance + 0.05) / (outerColorLuminance + 0.05)
|
||||
else (outerColorLuminance + 0.05) / (innerColorLuminance + 0.05)
|
||||
}
|
||||
|
@ -71,6 +71,42 @@ class RulesetValidator(val ruleset: Ruleset) {
|
||||
lines += "${nation.name} can settle cities, but has no city names!"
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast
|
||||
val constrastRatio = nation.getContrastRatio()
|
||||
if (constrastRatio < 3) {
|
||||
val innerColorLuminance = getRelativeLuminance(nation.getInnerColor())
|
||||
val outerColorLuminance = getRelativeLuminance(nation.getOuterColor())
|
||||
|
||||
val innerLerpColor:Color
|
||||
val outerLerpColor:Color
|
||||
|
||||
if (innerColorLuminance > outerColorLuminance) { // inner is brighter
|
||||
innerLerpColor = Color.WHITE
|
||||
outerLerpColor = Color.BLACK
|
||||
}
|
||||
else {
|
||||
innerLerpColor = Color.BLACK
|
||||
outerLerpColor = Color.WHITE
|
||||
}
|
||||
|
||||
var text = "${nation.name}'s colors do not contrast enough - it is unreadable!"
|
||||
|
||||
for (i in 1..10){
|
||||
val newInnerColor = nation.getInnerColor().cpy().lerp(innerLerpColor, 0.05f *i)
|
||||
val newOuterColor = nation.getOuterColor().cpy().lerp(outerLerpColor, 0.05f *i)
|
||||
|
||||
if (getContrastRatio(newInnerColor, newOuterColor) > 3){
|
||||
text += "\n Suggested inner color: (${(newInnerColor.r*255).toInt()}, ${(newInnerColor.g*255).toInt()}, ${(newInnerColor.b*255).toInt()})"
|
||||
text += "\n Suggested outer color: (${(newOuterColor.r*255).toInt()}, ${(newOuterColor.g*255).toInt()}, ${(newOuterColor.b*255).toInt()})"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
lines.add(
|
||||
text, RulesetErrorSeverity.Warning
|
||||
)
|
||||
}
|
||||
|
||||
checkUniques(nation, lines, rulesetInvariant, tryFixUnknownUniques)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user