宽色域 Color 的迁移指南
摘要
#dart:ui
中的 Color
类 API 正在发生变化,以支持 宽色域色彩空间。
上下文
#Flutter 引擎 已经支持宽色域颜色,并与 Impeller 配合使用,并且该支持现在正在 添加到框架中。
Flutter 支持的 iOS 设备渲染到更大的颜色数组,特别是在 DisplayP3 色彩空间中。此更改后,Flutter 框架可以在 iOS Impeller 上渲染所有这些颜色,并且 Color
类将为未来的色彩空间或颜色组件位深度的更改做好更好的准备。
更改说明
#对 Color
的更改
- 添加了一个枚举字段,用于指定其
ColorSpace
。 - 添加了使用归一化浮点颜色组件的 API。
- 删除了使用 8 位无符号整数颜色组件的 API,这些组件可能导致数据丢失。
对 ColorSpace
的更改
- 添加了一个
displayP3
属性。
迁移指南
#8 位无符号整数构造函数
#Color.fromARGB
等构造函数保持不变并继续支持。要利用 Display P3 颜色,必须使用新的 Color.from
构造函数,该构造函数采用归一化浮点颜色组件。
// Before
final magenta = Color.fromARGB(0xff, 0xff, 0x0, 0xff);
// After
final magenta = Color.from(alpha: 1.0, red: 1.0, green: 0.0, blue: 1.0)
Color
的实现者
#正在向 Color
添加新的方法,因此任何implements
Color 的类都将中断,并且必须实现新的方法,如 Color.a
和 Color.b
。最终,实现者应该迁移以利用新的 API。在短期内,这些方法可以很容易地实现,而无需更改类的底层结构。
例如
class Foo implements Color {
int _red;
@override
double get r => _red * 255.0;
}
色彩空间支持
#使用 Color
并对颜色组件执行任何类型的计算的客户端现在应该首先检查颜色空间组件,然后再执行计算。为此,您可以使用新的 Color.withValues
方法执行颜色空间转换。
迁移示例
// Before
double redRatio(Color x, Color y) => x.red / y.red;
// After
double redRatio(Color x, Color y) {
final xPrime = x.withValues(colorSpace: ColorSpace.extendedSRGB);
final yPrime = y.withValues(colorSpace: ColorSpace.extendedSRGB);
return xPrime.r / yPrime.r;
}
在不调整颜色空间的情况下对颜色组件执行计算可能会导致细微的意外结果。在上面的示例中,当使用不同的颜色空间与调整后的颜色空间计算时,redRatio
将存在 0.09 的差异。
访问颜色组件
#如果您的应用程序曾经访问过 Color
组件,请考虑利用浮点组件。在短期内,您可以轻松地缩放组件本身。
extension IntColorComponents on Color {
int get intAlpha => this.a ~/ 255;
int get intRed => this.r ~/ 255;
int get intGreen => this.g ~/ 255;
int get intBlue => this.b ~/ 255;
}
不透明度
#以前,Color 具有“不透明度”的概念,它出现在 opacity
和 withOpacity()
方法中。不透明度作为一种使用浮点值与 Color
通信其 alpha 通道的方式引入。现在 alpha 是一个浮点值,不透明度是冗余的,并且 opacity
和 withOpacity
已弃用,并计划删除。
opacity
迁移
#// Before
final x = color.opacity;
// After
final x = color.a;
withOpacity
迁移
#// Before
final x = color.withOpacity(0.0);
// After
final x = color.withValues(alpha: 0.0);
相等性
#一旦 Color
将其颜色组件存储为浮点数,相等性就会略有不同。在计算颜色时,可能存在微小的值差异,这些差异可以被认为是相等的。为了适应这一点,请使用 closeTo
匹配器或 isColorSameAs
匹配器。
// Before
expect(calculateColor(), const Color(0xffff00ff));
// After
expect(calculateColor(), isSameColorAs(const Color(0xffff00ff)));
时间线
#阶段 1 - 新 API 引入,旧 API 弃用
#发布到稳定版:待定 PR:: PR 54737
阶段 2 - 旧 API 移除
#发布到稳定版:待定
参考
#相关 PR
- 问题 127855: 在框架中实现宽色域颜色支持
除非另有说明,否则本网站上的文档反映了 Flutter 的最新稳定版本。页面上次更新于 2024 年 9 月 13 日。 查看源代码 或 报告问题。