Update docs on Color
to be more clear about normalized channel values. (#160798)
Closes https://github.com/flutter/flutter/issues/160592. ~Made a few other tiny non-breaking refactors, for example changing `withValues` internally.~
This commit is contained in:
parent
36e0099c4a
commit
840ef1cac8
@ -52,45 +52,52 @@ Color _scaleAlpha(Color x, double factor) {
|
|||||||
return x.withValues(alpha: clampDouble(x.a * factor, 0, 1));
|
return x.withValues(alpha: clampDouble(x.a * factor, 0, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An immutable 32 bit color value in ARGB format.
|
/// An immutable color value in ARGB format.
|
||||||
///
|
///
|
||||||
/// Consider the light teal of the Flutter logo. It is fully opaque, with a red
|
/// Consider the light teal of the [Flutter logo](https://flutter.dev/brand). It
|
||||||
/// channel value of 0x42 (66), a green channel value of 0xA5 (165), and a blue
|
/// is fully opaque, with a red [r] channel value of `0.2588` (or `0x42` or `66`
|
||||||
/// channel value of 0xF5 (245). In the common "hash syntax" for color values,
|
/// as an 8-bit value), a green [g] channel value of `0.6471` (or `0xA5` or
|
||||||
/// it would be described as `#42A5F5`.
|
/// `165` as an 8-bit value), and a blue [b] channel value of `0.9608` (or
|
||||||
|
/// `0xF5` or `245` as an 8-bit value). In a common [CSS hex color syntax](https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color)
|
||||||
|
/// for RGB color values, it would be described as `#42A5F5`.
|
||||||
///
|
///
|
||||||
/// Here are some ways it could be constructed:
|
/// Here are some ways it could be constructed:
|
||||||
///
|
///
|
||||||
/// ```dart
|
/// ```dart
|
||||||
/// Color c1 = const Color(0xFF42A5F5);
|
/// const Color c1 = Color.from(alpha: 1.0, red: 0.2588, green: 0.6471, blue: 0.9608);
|
||||||
/// Color c2 = const Color.fromARGB(0xFF, 0x42, 0xA5, 0xF5);
|
/// const Color c2 = Color(0xFF42A5F5);
|
||||||
/// Color c3 = const Color.fromARGB(255, 66, 165, 245);
|
/// const Color c3 = Color.fromARGB(0xFF, 0x42, 0xA5, 0xF5);
|
||||||
/// Color c4 = const Color.fromRGBO(66, 165, 245, 1.0);
|
/// const Color c4 = Color.fromARGB(255, 66, 165, 245);
|
||||||
|
/// const Color c5 = Color.fromRGBO(66, 165, 245, 1.0);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// If you are having a problem with `Color` wherein it seems your color is just
|
/// If you are having a problem with [Color.new] wherein it seems your color is
|
||||||
/// not painting, check to make sure you are specifying the full 8 hexadecimal
|
/// just not painting, check to make sure you are specifying the full 8
|
||||||
/// digits. If you only specify six, then the leading two digits are assumed to
|
/// hexadecimal digits. If you only specify six, then the leading two digits are
|
||||||
/// be zero, which means fully-transparent:
|
/// assumed to be zero, which means fully-transparent:
|
||||||
///
|
///
|
||||||
/// ```dart
|
/// ```dart
|
||||||
/// Color c1 = const Color(0xFFFFFF); // fully transparent white (invisible)
|
/// const Color c1 = Color(0xFFFFFF); // fully transparent white (invisible)
|
||||||
/// Color c2 = const Color(0xFFFFFFFF); // fully opaque white (visible)
|
/// const Color c2 = Color(0xFFFFFFFF); // fully opaque white (visible)
|
||||||
|
///
|
||||||
|
/// // Or use double-based channel values:
|
||||||
|
/// const Color c3 = Color.from(alpha: 1.0, red: 1.0, green: 1.0, blue: 1.0);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [Color]'s color components are stored as floating-point values. Care should
|
/// [Color]'s color components are stored as floating-point values. Care should
|
||||||
/// be taken if one does not want the literal equality provided by `operator==`.
|
/// be taken if one does not want the literal equality provided by `operator==`.
|
||||||
/// To test equality inside of Flutter tests consider using `package:test`'s
|
/// To test equality inside of Flutter tests consider using [`isSameColorAs`][].
|
||||||
/// `isSameColorAs`.
|
|
||||||
///
|
///
|
||||||
/// See also:
|
/// See also:
|
||||||
///
|
///
|
||||||
/// * [Colors](https://api.flutter.dev/flutter/material/Colors-class.html),
|
/// * [Colors](https://api.flutter.dev/flutter/material/Colors-class.html),
|
||||||
/// which defines the colors found in the Material Design specification.
|
/// which defines the colors found in the Material Design specification.
|
||||||
/// * [`isSameColorAs`](https://api.flutter.dev/flutter/flutter_test/isSameColorAs.html),
|
/// * [`isSameColorAs`][],
|
||||||
/// a Matcher to handle floating-point deltas when checking [Color] equality.
|
/// a Matcher to handle floating-point deltas when checking [Color] equality.
|
||||||
|
///
|
||||||
|
/// [`isSameColorAs`]: https://api.flutter.dev/flutter/flutter_test/isSameColorAs.html
|
||||||
class Color {
|
class Color {
|
||||||
/// Construct an sRGB color from the lower 32 bits of an [int].
|
/// Construct an [ColorSpace.sRGB] color from the lower 32 bits of an [int].
|
||||||
///
|
///
|
||||||
/// The bits are interpreted as follows:
|
/// The bits are interpreted as follows:
|
||||||
///
|
///
|
||||||
@ -101,19 +108,40 @@ class Color {
|
|||||||
///
|
///
|
||||||
/// In other words, if AA is the alpha value in hex, RR the red value in hex,
|
/// In other words, if AA is the alpha value in hex, RR the red value in hex,
|
||||||
/// GG the green value in hex, and BB the blue value in hex, a color can be
|
/// GG the green value in hex, and BB the blue value in hex, a color can be
|
||||||
/// expressed as `const Color(0xAARRGGBB)`.
|
/// expressed as `Color(0xAARRGGBB)`.
|
||||||
///
|
///
|
||||||
/// For example, to get a fully opaque orange, you would use `const
|
/// For example, to get a fully opaque orange, you would use `const
|
||||||
/// Color(0xFFFF9000)` (`FF` for the alpha, `FF` for the red, `90` for the
|
/// Color(0xFFFF9000)` (`FF` for the alpha, `FF` for the red, `90` for the
|
||||||
/// green, and `00` for the blue).
|
/// green, and `00` for the blue).
|
||||||
|
///
|
||||||
|
/// {@template dart.ui.Color.componentsStoredAsFloatingPoint}
|
||||||
|
/// > [!NOTE]
|
||||||
|
/// > Each color is stored as normalized floating-point color components,
|
||||||
|
/// > where the final value of each component is approximated by storing
|
||||||
|
/// > `c / 255`, where `c` is one of the four components (alpha, red, green,
|
||||||
|
/// > blue).
|
||||||
|
/// {@endtemplate}
|
||||||
const Color(int value)
|
const Color(int value)
|
||||||
: this._fromARGBC(value >> 24, value >> 16, value >> 8, value, ColorSpace.sRGB);
|
: this._fromARGBC(value >> 24, value >> 16, value >> 8, value, ColorSpace.sRGB);
|
||||||
|
|
||||||
/// Construct a color with normalized color components.
|
/// Construct a color with normalized color components from `0.0` to `1.0`.
|
||||||
///
|
///
|
||||||
/// Normalized color components allows arbitrary bit depths for color
|
/// Normalized color components allows arbitrary bit depths for color
|
||||||
/// components to be be supported. The values will be normalized relative to
|
/// components to be be supported. The values will be normalized relative to
|
||||||
/// the [ColorSpace] argument.
|
/// the [ColorSpace] argument.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
///
|
||||||
|
/// ```dart
|
||||||
|
/// // Fully opaque maximum red color
|
||||||
|
/// const Color c1 = Color.from(alpha: 1.0, red: 1.0, green: 0.0, blue: 0.0);
|
||||||
|
///
|
||||||
|
/// // Partially transparent moderately blue and green color
|
||||||
|
/// const Color c2 = Color.from(alpha: 0.5, red: 0.0, green: 0.5, blue: 0.5);
|
||||||
|
///
|
||||||
|
/// // Fully transparent color
|
||||||
|
/// const Color c3 = Color.from(alpha: 0.0, red: 0.0, green: 0.0, blue: 0.0);
|
||||||
|
/// ```
|
||||||
const Color.from({
|
const Color.from({
|
||||||
required double alpha,
|
required double alpha,
|
||||||
required double red,
|
required double red,
|
||||||
@ -137,6 +165,8 @@ class Color {
|
|||||||
///
|
///
|
||||||
/// See also [fromRGBO], which takes the alpha value as a floating point
|
/// See also [fromRGBO], which takes the alpha value as a floating point
|
||||||
/// value.
|
/// value.
|
||||||
|
///
|
||||||
|
/// {@macro dart.ui.Color.componentsStoredAsFloatingPoint}
|
||||||
const Color.fromARGB(int a, int r, int g, int b) : this._fromARGBC(a, r, g, b, ColorSpace.sRGB);
|
const Color.fromARGB(int a, int r, int g, int b) : this._fromARGBC(a, r, g, b, ColorSpace.sRGB);
|
||||||
|
|
||||||
const Color._fromARGBC(int alpha, int red, int green, int blue, ColorSpace colorSpace)
|
const Color._fromARGBC(int alpha, int red, int green, int blue, ColorSpace colorSpace)
|
||||||
@ -154,6 +184,8 @@ class Color {
|
|||||||
/// Out of range values are brought into range using modulo 255.
|
/// Out of range values are brought into range using modulo 255.
|
||||||
///
|
///
|
||||||
/// See also [fromARGB], which takes the opacity as an integer value.
|
/// See also [fromARGB], which takes the opacity as an integer value.
|
||||||
|
///
|
||||||
|
/// {@macro dart.ui.Color.componentsStoredAsFloatingPoint}
|
||||||
const Color.fromRGBO(int r, int g, int b, double opacity)
|
const Color.fromRGBO(int r, int g, int b, double opacity)
|
||||||
: this._fromRGBOC(r, g, b, opacity, ColorSpace.sRGB);
|
: this._fromRGBOC(r, g, b, opacity, ColorSpace.sRGB);
|
||||||
|
|
||||||
@ -163,19 +195,28 @@ class Color {
|
|||||||
g = (g & 0xff) / 255,
|
g = (g & 0xff) / 255,
|
||||||
b = (b & 0xff) / 255;
|
b = (b & 0xff) / 255;
|
||||||
|
|
||||||
/// The alpha channel of this color.
|
/// The normalized alpha channel of this color.
|
||||||
///
|
///
|
||||||
/// A value of 0.0 means this color is fully transparent. A value of 1.0 means
|
/// A value of `0.0` means this color is fully transparent. A value of `1.0`
|
||||||
/// this color is fully opaque.
|
/// means this color is fully opaque.
|
||||||
final double a;
|
final double a;
|
||||||
|
|
||||||
/// The red channel of this color.
|
/// The normalized red channel of this color.
|
||||||
|
///
|
||||||
|
/// A value of `0.0` represents no red in this color. A value of `1.0`
|
||||||
|
/// represents the maximum amount of red.
|
||||||
final double r;
|
final double r;
|
||||||
|
|
||||||
/// The green channel of this color.
|
/// The normalized green channel of this color.
|
||||||
|
///
|
||||||
|
/// A value of `0.0` represents no red in this color. A value of `1.0`
|
||||||
|
/// represents the maximum amount of green.
|
||||||
final double g;
|
final double g;
|
||||||
|
|
||||||
/// The blue channel of this color.
|
/// The blue channel of this color.
|
||||||
|
///
|
||||||
|
/// A value of `0.0` represents no blue in this color. A value of `1.0`
|
||||||
|
/// represents the maximum amount of blue.
|
||||||
final double b;
|
final double b;
|
||||||
|
|
||||||
/// The color space of this color.
|
/// The color space of this color.
|
||||||
@ -187,17 +228,17 @@ class Color {
|
|||||||
|
|
||||||
/// A 32 bit value representing this color.
|
/// A 32 bit value representing this color.
|
||||||
///
|
///
|
||||||
/// The bits are assigned as follows:
|
/// This getter is a _stub_. It is recommended instead to use the explicit
|
||||||
///
|
/// [toARGB32] method.
|
||||||
/// * Bits 24-31 are the alpha value.
|
|
||||||
/// * Bits 16-23 are the red value.
|
|
||||||
/// * Bits 8-15 are the green value.
|
|
||||||
/// * Bits 0-7 are the blue value.
|
|
||||||
@Deprecated('Use component accessors like .r or .g, or toARGB32 for an explicit conversion')
|
@Deprecated('Use component accessors like .r or .g, or toARGB32 for an explicit conversion')
|
||||||
int get value => toARGB32();
|
int get value => toARGB32();
|
||||||
|
|
||||||
/// Returns a 32-bit value representing this color.
|
/// Returns a 32-bit value representing this color.
|
||||||
///
|
///
|
||||||
|
/// The returned value is compatible with the default constructor
|
||||||
|
/// ([Color.new]) but does _not_ guarantee to result in the same color due to
|
||||||
|
/// [imprecisions in numeric conversions](https://en.wikipedia.org/wiki/Floating-point_error_mitigation).
|
||||||
|
///
|
||||||
/// Unlike accessing the floating point equivalent channels individually
|
/// Unlike accessing the floating point equivalent channels individually
|
||||||
/// ([a], [r], [g], [b]), this method is intentionally _lossy_, and scales
|
/// ([a], [r], [g], [b]), this method is intentionally _lossy_, and scales
|
||||||
/// each channel using `(channel * 255.0).round() & 0xff`.
|
/// each channel using `(channel * 255.0).round() & 0xff`.
|
||||||
@ -212,6 +253,13 @@ class Color {
|
|||||||
/// * Bits 16-23 represents the [r] channel as an 8-bit unsigned integer.
|
/// * Bits 16-23 represents the [r] channel as an 8-bit unsigned integer.
|
||||||
/// * Bits 8-15 represents the [g] channel as an 8-bit unsigned integer.
|
/// * Bits 8-15 represents the [g] channel as an 8-bit unsigned integer.
|
||||||
/// * Bits 0-7 represents the [b] channel as an 8-bit unsigned integer.
|
/// * Bits 0-7 represents the [b] channel as an 8-bit unsigned integer.
|
||||||
|
///
|
||||||
|
/// > [!WARNING]
|
||||||
|
/// > The value returned by this getter implicitly converts normalized
|
||||||
|
/// > component values (such as `0.5`) into their 8-bit equivalent by using
|
||||||
|
/// > the [toARGB32] method; the returned value is not guaranteed to be stable
|
||||||
|
/// > across different platforms or executions due to the complexity of
|
||||||
|
/// > floating-point math.
|
||||||
int toARGB32() {
|
int toARGB32() {
|
||||||
return _floatToInt8(a) << 24 |
|
return _floatToInt8(a) << 24 |
|
||||||
_floatToInt8(r) << 16 |
|
_floatToInt8(r) << 16 |
|
||||||
@ -245,11 +293,15 @@ class Color {
|
|||||||
@Deprecated('Use .b.')
|
@Deprecated('Use .b.')
|
||||||
int get blue => (0x000000ff & value) >> 0;
|
int get blue => (0x000000ff & value) >> 0;
|
||||||
|
|
||||||
/// Returns a new color that matches this color with the passed in components
|
/// Returns a new color with the provided components updated.
|
||||||
/// changed.
|
|
||||||
///
|
///
|
||||||
/// Changes to color components will be applied before applying changes to the
|
/// Each component ([alpha], [red], [green], [blue]) represents a normalized
|
||||||
/// color space.
|
/// floating-point value wher `0.0` is the minimum and `1.0` is the maximum;
|
||||||
|
/// see [Color.from] for details and examples.
|
||||||
|
///
|
||||||
|
/// If [colorSpace] is provided, and is different than the current color
|
||||||
|
/// space, the component values are updated before transforming them to the
|
||||||
|
/// provided color space.
|
||||||
Color withValues({
|
Color withValues({
|
||||||
double? alpha,
|
double? alpha,
|
||||||
double? red,
|
double? red,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user