跳至主要內容

寬色域色彩遷移指南

摘要

#

dart:uiColor 類別的 API 正在變更,以支援廣色域色彩空間

背景

#

Flutter 引擎 已透過 Impeller 支援廣色域色彩,現在正將支援加入框架中。

Flutter 支援的 iOS 裝置會以較大的顏色陣列進行渲染,特別是在 DisplayP3 色彩空間中。在此變更之後,Flutter 框架可以在 iOS Impeller 上渲染所有這些顏色,而 Color 類別將更能為未來的色彩空間或色彩元件位元深度變更做好準備。

變更描述

#

Color 的變更

  1. 新增一個列舉欄位,指定其ColorSpace
  2. 新增 API 以使用標準化的浮點數色彩元件。
  3. 移除使用 8 位元無號整數色彩元件的 API,這可能會導致資料遺失。

ColorSpace 的變更

  1. 新增 displayP3 屬性。

遷移指南

#

8 位元無符號整數建構子

#

Color.fromARGB 等建構函式保持不變,並繼續支援。若要利用 Display P3 顏色,您必須使用新的 Color.from 建構函式,它會接收標準化的浮點數色彩元件。

dart
// 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.aColor.b。最終,實作人員應該遷移以利用新的 API。在短期內,這些方法可以輕鬆實作,而無需變更類別的基礎結構。

例如

dart
class Foo implements Color {
  int _red;

  @override
  double get r => _red * 255.0;
}

色彩空間支援

#

使用 Color 並對色彩元件執行任何計算的用戶端現在應該先檢查色彩空間元件,然後再執行計算。為了協助您完成此操作,您可以使用新的 Color.withValues 方法來執行色彩空間轉換。

遷移範例

dart
// 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 元件,請考慮利用浮點數元件。在短期內,您可以輕鬆縮放元件本身。

dart
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 有「不透明度」的概念,該概念出現在方法 opacitywithOpacity() 中。引入不透明度是為了以浮點數值與 Color 通訊其 alpha 通道。既然 alpha 是一個浮點數值,不透明度就變得多餘,opacitywithOpacity 已棄用,並計劃將其移除。

opacity 遷移

#
dart
// Before
final x = color.opacity;
// After
final x = color.a;

withOpacity 遷移

#
dart
// Before
final x = color.withOpacity(0.0);
// After
final x = color.withValues(alpha: 0.0);

相等性

#

一旦 Color 將其色彩元件儲存為浮點數,等式運作方式會稍微不同。在計算顏色時,值可能會有微小的差異,這些差異可以被視為相等。為了配合這一點,請使用 closeTo matcher 或 isColorSameAs matcher。

dart
// Before
expect(calculateColor(), const Color(0xffff00ff));
// After
expect(calculateColor(), isSameColorAs(const Color(0xffff00ff)));

時間軸

#

階段 1 - 推出新的 API,並棄用舊的 API

#

發佈至穩定版本: 待定 PR:PR 54737

階段 2 - 移除舊的 API

#

發佈至穩定版本: 待定

參考

#

相關 PR