Make the Brightness estimator public (#10508)
This commit is contained in:
parent
2ff2274cd3
commit
ca4f4fc8d1
@ -43,32 +43,6 @@ const Color _kLightThemeSplashColor = const Color(0x66C8C8C8);
|
|||||||
const Color _kDarkThemeHighlightColor = const Color(0x40CCCCCC);
|
const Color _kDarkThemeHighlightColor = const Color(0x40CCCCCC);
|
||||||
const Color _kDarkThemeSplashColor = const Color(0x40CCCCCC);
|
const Color _kDarkThemeSplashColor = const Color(0x40CCCCCC);
|
||||||
|
|
||||||
// See <https://www.w3.org/TR/WCAG20/#relativeluminancedef>
|
|
||||||
double _linearizeColorComponent(double component) {
|
|
||||||
if (component <= 0.03928)
|
|
||||||
return component / 12.92;
|
|
||||||
return math.pow((component + 0.055) / 1.055, 2.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
Brightness _estimateBrightnessForColor(Color color) {
|
|
||||||
// See <https://www.w3.org/TR/WCAG20/#relativeluminancedef>
|
|
||||||
final double R = _linearizeColorComponent(color.red / 0xFF);
|
|
||||||
final double G = _linearizeColorComponent(color.green / 0xFF);
|
|
||||||
final double B = _linearizeColorComponent(color.blue / 0xFF);
|
|
||||||
final double L = 0.2126 * R + 0.7152 * G + 0.0722 * B;
|
|
||||||
|
|
||||||
// See <https://www.w3.org/TR/WCAG20/#contrast-ratiodef>
|
|
||||||
// The spec says to use kThreshold=0.0525, but Material Design appears to bias
|
|
||||||
// more towards using light text than WCAG20 recommends. Material Design spec
|
|
||||||
// doesn't say what value to use, but 0.15 seemed close to what the Material
|
|
||||||
// Design spec shows for its color palette on
|
|
||||||
// <https://material.io/guidelines/style/color.html#color-color-palette>.
|
|
||||||
const double kThreshold = 0.15;
|
|
||||||
if ((L + 0.05) * (L + 0.05) > kThreshold )
|
|
||||||
return Brightness.light;
|
|
||||||
return Brightness.dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Holds the color and typography values for a material design theme.
|
/// Holds the color and typography values for a material design theme.
|
||||||
///
|
///
|
||||||
/// Use this class to configure a [Theme] widget.
|
/// Use this class to configure a [Theme] widget.
|
||||||
@ -134,10 +108,10 @@ class ThemeData {
|
|||||||
final bool isDark = brightness == Brightness.dark;
|
final bool isDark = brightness == Brightness.dark;
|
||||||
primarySwatch ??= Colors.blue;
|
primarySwatch ??= Colors.blue;
|
||||||
primaryColor ??= isDark ? Colors.grey[900] : primarySwatch[500];
|
primaryColor ??= isDark ? Colors.grey[900] : primarySwatch[500];
|
||||||
primaryColorBrightness ??= _estimateBrightnessForColor(primaryColor);
|
primaryColorBrightness ??= estimateBrightnessForColor(primaryColor);
|
||||||
final bool primaryIsDark = primaryColorBrightness == Brightness.dark;
|
final bool primaryIsDark = primaryColorBrightness == Brightness.dark;
|
||||||
accentColor ??= isDark ? Colors.tealAccent[200] : primarySwatch[500];
|
accentColor ??= isDark ? Colors.tealAccent[200] : primarySwatch[500];
|
||||||
accentColorBrightness ??= _estimateBrightnessForColor(accentColor);
|
accentColorBrightness ??= estimateBrightnessForColor(accentColor);
|
||||||
final bool accentIsDark = accentColorBrightness == Brightness.dark;
|
final bool accentIsDark = accentColorBrightness == Brightness.dark;
|
||||||
canvasColor ??= isDark ? Colors.grey[850] : Colors.grey[50];
|
canvasColor ??= isDark ? Colors.grey[850] : Colors.grey[50];
|
||||||
scaffoldBackgroundColor ??= canvasColor;
|
scaffoldBackgroundColor ??= canvasColor;
|
||||||
@ -467,6 +441,37 @@ class ThemeData {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See <https://www.w3.org/TR/WCAG20/#relativeluminancedef>
|
||||||
|
static double _linearizeColorComponent(double component) {
|
||||||
|
if (component <= 0.03928)
|
||||||
|
return component / 12.92;
|
||||||
|
return math.pow((component + 0.055) / 1.055, 2.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines whether the given [Color] is [Brightness.light] or
|
||||||
|
/// [Brightness.dark].
|
||||||
|
///
|
||||||
|
/// This compares the luminosity of the given color to a threshold value that
|
||||||
|
/// matches the material design specification.
|
||||||
|
static Brightness estimateBrightnessForColor(Color color) {
|
||||||
|
// See <https://www.w3.org/TR/WCAG20/#relativeluminancedef>
|
||||||
|
final double R = _linearizeColorComponent(color.red / 0xFF);
|
||||||
|
final double G = _linearizeColorComponent(color.green / 0xFF);
|
||||||
|
final double B = _linearizeColorComponent(color.blue / 0xFF);
|
||||||
|
final double L = 0.2126 * R + 0.7152 * G + 0.0722 * B;
|
||||||
|
|
||||||
|
// See <https://www.w3.org/TR/WCAG20/#contrast-ratiodef>
|
||||||
|
// The spec says to use kThreshold=0.0525, but Material Design appears to bias
|
||||||
|
// more towards using light text than WCAG20 recommends. Material Design spec
|
||||||
|
// doesn't say what value to use, but 0.15 seemed close to what the Material
|
||||||
|
// Design spec shows for its color palette on
|
||||||
|
// <https://material.io/guidelines/style/color.html#color-color-palette>.
|
||||||
|
const double kThreshold = 0.15;
|
||||||
|
if ((L + 0.05) * (L + 0.05) > kThreshold )
|
||||||
|
return Brightness.light;
|
||||||
|
return Brightness.dark;
|
||||||
|
}
|
||||||
|
|
||||||
/// Linearly interpolate between two themes.
|
/// Linearly interpolate between two themes.
|
||||||
///
|
///
|
||||||
/// The arguments must not be null.
|
/// The arguments must not be null.
|
||||||
|
@ -90,7 +90,20 @@ void main() {
|
|||||||
expect(themeData.accentTextTheme.display4.fontFamily, equals('Ahem'));
|
expect(themeData.accentTextTheme.display4.fontFamily, equals('Ahem'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can estimate brightness', () {
|
test('Can estimate brightness - directly', () {
|
||||||
|
expect(ThemeData.estimateBrightnessForColor(Colors.white), equals(Brightness.light));
|
||||||
|
expect(ThemeData.estimateBrightnessForColor(Colors.black), equals(Brightness.dark));
|
||||||
|
expect(ThemeData.estimateBrightnessForColor(Colors.blue), equals(Brightness.dark));
|
||||||
|
expect(ThemeData.estimateBrightnessForColor(Colors.yellow), equals(Brightness.light));
|
||||||
|
expect(ThemeData.estimateBrightnessForColor(Colors.deepOrange), equals(Brightness.dark));
|
||||||
|
expect(ThemeData.estimateBrightnessForColor(Colors.orange), equals(Brightness.light));
|
||||||
|
expect(ThemeData.estimateBrightnessForColor(Colors.lime), equals(Brightness.light));
|
||||||
|
expect(ThemeData.estimateBrightnessForColor(Colors.grey), equals(Brightness.light));
|
||||||
|
expect(ThemeData.estimateBrightnessForColor(Colors.teal), equals(Brightness.dark));
|
||||||
|
expect(ThemeData.estimateBrightnessForColor(Colors.indigo), equals(Brightness.dark));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Can estimate brightness - indirectly', () {
|
||||||
expect(new ThemeData(primaryColor: Colors.white).primaryColorBrightness, equals(Brightness.light));
|
expect(new ThemeData(primaryColor: Colors.white).primaryColorBrightness, equals(Brightness.light));
|
||||||
expect(new ThemeData(primaryColor: Colors.black).primaryColorBrightness, equals(Brightness.dark));
|
expect(new ThemeData(primaryColor: Colors.black).primaryColorBrightness, equals(Brightness.dark));
|
||||||
expect(new ThemeData(primaryColor: Colors.blue).primaryColorBrightness, equals(Brightness.dark));
|
expect(new ThemeData(primaryColor: Colors.blue).primaryColorBrightness, equals(Brightness.dark));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user