FlexCorePalette.fromSeeds constructor

FlexCorePalette.fromSeeds({
  1. required int primary,
  2. int? secondary,
  3. int? tertiary,
  4. int? error,
  5. int? neutral,
  6. int? neutralVariant,
  7. double? primaryChroma,
  8. double? primaryMinChroma,
  9. double? secondaryChroma,
  10. double? secondaryMinChroma,
  11. double? tertiaryChroma,
  12. double? tertiaryMinChroma,
  13. double? tertiaryHueRotation,
  14. double? neutralChroma = 4,
  15. double? neutralMinChroma,
  16. double? neutralVariantChroma = 8,
  17. double? neutralVariantMinChroma,
  18. double? errorChroma,
  19. double? errorMinChroma,
  20. FlexPaletteType paletteType = FlexPaletteType.common,
})

Create a FlexCorePalette from one to three seed colors.

If only primary ARGB is provided, it is the same as using the FlexCorePalette.of static that returns an instance of FlexCorePalette created from a single ARGB seed color.

When using optional secondary and tertiary int ARGB seed values, the tonal palette generation will use hue and chroma from the provided color values for creation of respective tonal palettes.

The specified fixed chroma value, or minimum allowed chroma value, will if specified be used, but combined with the hue in provided secondary and tertiary key colors. If no min chroma or fixed chroma value is given, the chroma value in the provided seed/key color is used.

To create a FlexCorePalette.fromSeeds that equals Material Color Utilities package CorePalette.of palette results, when it comes to same color tone values. Only specify the primary ARGB seed color and set secondaryChroma and tertiaryChroma to same fixed values that the Material 3 default color system has hard coded, 16 and 24.

Example:

final FlexCorePalette fCorePal = FlexCorePalette.fromSeeds(
  primary: const Color(0xFF6750A4).value,
  secondaryChroma: 16,
  tertiaryChroma: 24,
);

Using above corePal and fCorePal same tones in corresponding palettes will be equal.

var same = fCorePal.primary.get(10) == corePal.primary.get(10); // true

Tones 5 and 98 available in FlexCorePalette are not available in CorePalette. They are an addition in the modified implementation of FlexTonalPalette compared to TonalPalette.

Implementation

//  final CorePalette corePal = CorePalette.of(const Color(0xFF6750A4).value);
/// ```
///
/// Using above `corePal` and `fCorePal` same tones in corresponding palettes
/// will be equal.
///
/// ```dart
/// var same = fCorePal.primary.get(10) == corePal.primary.get(10); // true
/// ```
///
/// Tones 5 and 98 available in [FlexCorePalette] are not available in
/// [CorePalette]. They are an addition in the modified implementation of
/// [FlexTonalPalette] compared to [TonalPalette].
factory FlexCorePalette.fromSeeds({
  /// Integer ARGB value of seed color used for primary tonal palette.
  /// calculation.
  ///
  /// By default a minimum of Cam16 chroma 48 is used to ensure a bright
  /// palette. If chroma of the provided color is higher than 48, it is
  /// used.
  ///
  /// A fixed chroma value can also be specified via [primaryChroma], if it
  /// is, then the given chroma value is used. Alternatively a
  /// [primaryMinChroma] can, be specified, then chroma in [primary] is used
  /// when it is higher than [primaryMinChroma]. If both [primaryChroma] and
  /// [primaryMinChroma] are specified, the higher value is used for chroma.
  required int primary,

  /// Integer ARGB value of seed color used for secondary tonal palette
  /// calculation.
  ///
  /// If not provided, the palette is based on [primary] with Cam16 chroma
  /// fixed at 16.
  ///
  /// A fixed chroma value can also be specified via [secondaryChroma], if it
  /// is, then the given chroma value is used. Alternatively a
  /// [secondaryMinChroma] can, be specified, then chroma in [secondary] is
  /// used when it is higher than [secondaryMinChroma]. If both
  /// [secondaryChroma] and [secondaryMinChroma] are specified, the higher
  /// value is used for chroma.
  int? secondary,

  /// Integer ARGB value of seed color used for tertiary tonal palette
  /// calculation.
  ///
  /// Cam16 chroma is capped at 48 if provided. If not provided, the palette
  /// is based on [primary] with Cam16 hue + 60 degrees (default value for
  /// [tertiaryHueRotation]) and chroma at 24.
  ///
  /// A fixed chroma value can also be specified via [tertiaryChroma], if it
  /// is, then the given chroma value is used. Alternatively a
  /// [tertiaryMinChroma] can, be specified, then chroma in [tertiary] is
  /// used when it is higher than [tertiaryMinChroma]. If both
  /// [tertiaryChroma] and [tertiaryMinChroma] are specified, the higher
  /// value is used for chroma.
  int? tertiary,

  /// Integer ARGB value of seed color used for error tonal palette.
  ///
  /// If not provided, the palette will be based on Material 3 default
  /// `FlexTonalPalette.of(25, 84)`. The error color hue is 25 and chroma 84.
  /// Typically you should stick to this, but if your theme uses a primary
  /// red color that clashes badly with the default M3 error color, you can
  /// specify a new error seed color here with a different hue and also
  /// chroma limit or fixed one.
  ///
  /// A fixed chroma value can also be specified via [errorChroma], if it
  /// is, then the given chroma value is used. Alternatively a
  /// [errorMinChroma] can, be specified, then chroma in [error] is
  /// used when it is higher than [errorMinChroma]. If both
  /// [errorChroma] and [errorMinChroma] are specified, the higher
  /// value is used for chroma.
  int? error,

  /// Integer ARGB value of seed color used for neutral tonal palette
  /// calculation.
  ///
  /// If not provided, the palette is based on [primary] with Cam16 chroma
  /// fixed at 16.
  ///
  /// A fixed chroma value can also be specified via [neutralChroma], if it
  /// is, then the given chroma value is used. Alternatively a
  /// [neutralMinChroma] can, be specified, then chroma in [neutral] is
  /// used when it is higher than [neutralMinChroma]. If both
  /// [neutralChroma] and [neutralMinChroma] are specified, the higher
  /// value is used for chroma.
  int? neutral,

  /// Integer ARGB value of seed color used for neutralVariant tonal palette
  /// calculation.
  ///
  /// If not provided, the palette is based on [primary] with Cam16 chroma
  /// fixed at 16.
  ///
  /// A fixed chroma value can also be specified via [neutralVariantChroma],
  /// if it is, then the given chroma value is used. Alternatively a
  /// [neutralVariantMinChroma] can, be specified, then chroma in
  /// [neutralVariant] is used when it is higher than
  /// [neutralVariantMinChroma]. If both [neutralVariantChroma] and
  /// [neutralVariantMinChroma] are specified, the higher value is used
  /// for chroma.
  int? neutralVariant,

  /// Cam16 chroma value to use for primary colors tonal palette generation.
  ///
  /// If null, the chroma value from the used [primary] seed key color is
  /// used, if it is larger than [primaryMinChroma].
  ///
  /// Flutter SDK [ColorScheme.fromSeed] uses chroma from seed, with
  /// [primaryMinChroma] set to 48, so the chroma from the key color is used
  /// when above 48, but never lower than 48. This keeps primary color in
  /// resulting tonal palette reasonably vivid and usable regardless of
  /// used seed color.
  ///
  /// To use chroma value from [primary] seed color, keep [primaryChroma] null
  /// and [primaryMinChroma] at desired threshold for target min colorfulness.
  final double? primaryChroma,

  /// The minimum used chroma value for primary palette.
  ///
  /// If chroma in provided [primary] key color is below this value, or if a
  /// fixed [primaryChroma] is provided that is lower than [primaryMinChroma]
  /// then the [primaryMinChroma] value is used.
  ///
  /// If not defined, defaults to 48.
  ///
  /// Flutter SDK uses 48 via a hard coded value and design.
  final double? primaryMinChroma,

  /// Cam16 chroma value to use for secondary colors tonal palette
  /// generation.
  ///
  /// If null, the chroma value from the used [secondary] seed key color is
  /// used, if it is larger than [secondaryMinChroma].
  ///
  /// Flutter SDK [ColorScheme.fromSeed] uses [secondaryChroma] hard coded
  /// and locked to 16.
  ///
  /// Defaults to null, set it to 16 for Material 3 standard result.
  ///
  /// The Flutter's and M3 default value produces quite soft, muted and earthy
  /// tones as secondary tonal palette at its mid-point tones of the palette.
  /// This is a design choice, but you can modify it here.
  ///
  /// To use chroma value from [secondary] seed color, keep [secondaryChroma]
  /// null and [secondaryMinChroma] at desired threshold for target min
  /// colorfulness.
  final double? secondaryChroma,

  /// The minimum used chroma value for secondary palette.
  ///
  /// If chroma in provided [secondary] key color is below this value, or if a
  /// fixed [secondaryChroma] is provided that is lower than
  /// [secondaryMinChroma] then the [secondaryMinChroma] value is used.
  ///
  /// If not defined, defaults to 0.
  ///
  /// Flutter SDK only uses [secondaryChroma] hard coded to 16, and has no
  /// concept of minimum level for secondary tonal palettes as its chroma
  /// value is always locked to 16.
  final double? secondaryMinChroma,

  /// Cam16 chroma value to use for tertiary colors tonal palette generation.
  ///
  /// If null, the chroma value from the used [tertiary] seed key color is
  /// used, if it is larger than [tertiaryMinChroma].
  ///
  /// Flutter SDK [ColorScheme.fromSeed] uses [tertiaryChroma] hard coded
  /// and locked to 24.
  ///
  /// Defaults to null, set it to 24 for Material 3 standard result.
  ///
  /// The default produces soft and pastel tones as tertiary tonal palette
  /// at the mid-point tones of the palette, they are bit less muted than
  /// the default secondary tonal palette.
  ///
  /// To use chroma value from [tertiary] seed color, keep [tertiaryChroma]
  /// null and [tertiaryMinChroma] at desired threshold for target min
  /// colorfulness.
  final double? tertiaryChroma,

  /// The minimum used chroma value for tertiary palette.
  ///
  /// If chroma in provided [tertiary] key color is below this value, or if a
  /// fixed [tertiaryChroma] is provided that is lower than
  /// [tertiaryMinChroma] then the [tertiaryMinChroma] value is used.
  ///
  /// If not defined, defaults to 0.
  ///
  /// Flutter SDK only uses [tertiaryChroma] hard coded to 24, and has no
  /// concept of minimum level for tertiary tonal palettes, as its value is
  /// always locked to 24.
  final double? tertiaryMinChroma,

  /// The number of degrees to rotate the hue in [primary] key color to get
  /// the used Hue for the tertiary color.
  ///
  /// This is only used when [tertiary] ARGB key color is null and we have
  /// not specified an own key color for [tertiary] with its onw hue.
  ///
  /// If you set this value to 0, or very close to it, you can make seed
  /// generated color schemes where all color are "like" the primary color
  /// but with subtle tone and shade variations.
  ///
  /// If not defined, default 60.
  final double? tertiaryHueRotation,

  /// Cam16 chroma value to use for neutral colors tonal palette generation.
  ///
  /// Uses chroma from the [neutral] key color, but you can vary the
  /// amount of chroma from neutral key color that is used to generate
  /// the tonal palette
  ///
  /// Flutter SDK [ColorScheme.fromSeed] uses [neutralChroma] hard coded to 4.
  ///
  /// If not defined, defaults to 4.
  ///
  /// To force the chroma in [neutral] key color to be used, set this to null
  /// and keep [neutralMinChroma] at 0. Typically you want to use very low
  /// chroma on the neutral colors. If you set this to null, the provided
  /// ARGB value in [neutral] should have a very low chroma value itself.
  final double? neutralChroma = 4,

  /// The minimum used chroma value for neutral palette.
  ///
  /// If chroma in provided [neutral] key color is below this value, or if a
  /// fixed [neutralChroma] is provided that is lower than
  /// [neutralMinChroma] then the [neutralMinChroma] value is used.
  ///
  /// If not defined, defaults to 0.
  ///
  /// Flutter SDK only uses [neutralChroma] hard coded to 4, and has no
  /// concept of minimum level for neutral tonal palettes as its chroma
  /// value is always locked to 16.
  final double? neutralMinChroma,

  /// Cam16 chroma value to use for neutralVariant colors
  /// tonal palette generation.
  ///
  /// Uses chroma from the [neutralVariant] key color, but you can vary
  /// the amount of chroma from neutral variant key color that is used to
  /// generate the tonal palette
  ///
  /// Flutter SDK [ColorScheme.fromSeed] uses [neutralVariantChroma] hard
  /// coded to 8.
  ///
  /// Defaults to 8.
  ///
  /// To force the chroma in [neutralVariant] key color to be used, set this
  /// to null and keep [neutralVariantMinChroma] at 0. Typically you want to
  /// use very low chroma on the neutral colors. If you set this to null, the
  /// provided ARGB value in [neutralVariant] should have a very low chroma
  /// value itself.
  final double? neutralVariantChroma = 8,

  /// The minimum used chroma value for neutral variant palette.
  ///
  /// If chroma in provided [neutralVariant] key color is below this value,
  /// or if a fixed [neutralVariantChroma] is provided that is lower than
  /// [neutralVariantMinChroma] then the [neutralVariantMinChroma] value
  /// is used.
  ///
  /// If not defined, defaults to 0.
  ///
  /// Flutter SDK only uses [neutralVariantMinChroma] hard coded to 4, and
  /// has no concept of minimum level for neutral variant tonal palettes as
  /// its chroma value is always locked to 8.
  final double? neutralVariantMinChroma,

  /// Cam16 chroma value to use for error colors tonal palette generation.
  ///
  /// If null, the chroma value from the used [error] seed key color is
  /// used, if it is larger than [errorMinChroma].
  ///
  /// Defaults to null. Set it to 84 for M3 default also on custom hues.
  ///
  /// To use chroma value from [error] seed color, keep [errorChroma]
  /// null and [errorMinChroma] at desired threshold for target min
  /// colorfulness.
  final double? errorChroma,

  /// The minimum used chroma value for error palette.
  ///
  /// If chroma in provided [error] key color is below this value, or if a
  /// fixed [errorChroma] is provided that is lower than
  /// [errorMinChroma] then the [errorMinChroma] value is used.
  ///
  /// If not defined, defaults to 0.
  ///
  /// Flutter SDK only uses [errorChroma] hard coded to 84, and has no
  /// concept of minimum level for error tonal palettes, as its value is
  /// always locked to 84.
  final double? errorMinChroma,

  /// Defines what [FlexPaletteType] this [FlexCorePalette] uses.
  ///
  /// The default [FlexPaletteType.common] with 15 tones or the extended
  /// [FlexPaletteType.extended] with 24 tones.
  final FlexPaletteType paletteType = FlexPaletteType.common,
}) {
  // Primary TonalPalette calculation.
  //
  // Key color is required, we can use it.
  final Cam16 camPrimary = Cam16.fromInt(primary);
  // If a fixed chroma was given we use it instead of chroma in primary.
  final double effectivePrimaryChroma = primaryChroma ?? camPrimary.chroma;
  // We use the effectiveChroma, but only if it is over the min level.
  final FlexTonalPalette tonalPrimary = FlexTonalPalette.of(camPrimary.hue,
      math.max(primaryMinChroma ?? 48, effectivePrimaryChroma), paletteType);

  // Secondary TonalPalette calculation.
  //
  // Provided key color may be null, then we use primary as key color.
  final Cam16 camSecondary =
      secondary == null ? camPrimary : Cam16.fromInt(secondary);
  // If a fixed chroma value was given we use it instead.
  final double effectiveSecondaryChroma =
      secondaryChroma ?? camSecondary.chroma;
  // We use the effectiveChroma, but only if it is over the min level.
  final FlexTonalPalette tonalSecondary = FlexTonalPalette.of(
      camSecondary.hue,
      math.max(secondaryMinChroma ?? 0, effectiveSecondaryChroma),
      paletteType);

  // Tertiary TonalPalette calculation.
  //
  // Provided key color may be null, then we use primary as key color.
  final Cam16 camTertiary =
      tertiary == null ? camPrimary : Cam16.fromInt(tertiary);
  // If a fixed chroma value was given we use it instead.
  final double effectiveTertiaryChroma = tertiaryChroma ?? camTertiary.chroma;
  // If we had no tertiary keyColor, we won't use primary key's hue
  // directly, we add 60 degrees to it, this is the M3 way to shift hue from a
  // single key.
  final double effectiveTertiaryHue = tertiary == null
      ? camPrimary.hue + (tertiaryHueRotation ?? 60)
      : camTertiary.hue;
  // We use the effective hue and the effectiveChroma, but chroma
  // only if it is over the min level.
  final FlexTonalPalette tonalTertiary = FlexTonalPalette.of(
      effectiveTertiaryHue,
      math.max(tertiaryMinChroma ?? 0, effectiveTertiaryChroma),
      paletteType);

  // Neutral TonalPalette calculation.
  //
  // Provided key color may be null, then we use primary as key color.
  final Cam16 camNeutral =
      neutral == null ? camPrimary : Cam16.fromInt(neutral);
  // If a fixed chroma value was given we use it instead.
  final double effectiveNeutralChroma = neutralChroma ?? camNeutral.chroma;
  // We use the effectiveChroma, but only if it is over the min level.
  final FlexTonalPalette tonalNeutral = FlexTonalPalette.of(camNeutral.hue,
      math.max(neutralMinChroma ?? 0, effectiveNeutralChroma), paletteType);

  // NeutralVariant TonalPalette calculation.
  //
  // Provided key color may be null, then we use primary as key color.
  final Cam16 camNeutralVariant =
      neutralVariant == null ? camPrimary : Cam16.fromInt(neutralVariant);
  // If a fixed chroma value was given we use it instead.
  final double effectiveNeutralVariantChroma =
      neutralVariantChroma ?? camNeutralVariant.chroma;
  // We use the effectiveChroma, but only if it is over the min level.
  final FlexTonalPalette tonalNeutralVariant = FlexTonalPalette.of(
      camNeutralVariant.hue,
      math.max(neutralVariantMinChroma ?? 0, effectiveNeutralVariantChroma),
      paletteType);

  // Error TonalPalette calculation.
  //
  // Input error color maybe null, but if it is not we make a Cam16 from it.
  final Cam16? camError = error == null ? null : Cam16.fromInt(error);

  // If a fixed error chroma value was given we will use it instead as
  // effective chroma value, if not and if input error color was given, we use
  // its chroma, if one was not given we fall back to M3 default chroma 84.
  final double effectiveErrorChroma = errorChroma ?? camError?.chroma ?? 84;

  // If an error color was given, we use its hue, if none was given we fall
  // back to hue 25, the Material 3 default.
  final double effectiveErrorHue = camError?.hue ?? 25;

  // We use the effectiveChroma, but only if it is over the min level.
  final FlexTonalPalette tonalError = FlexTonalPalette.of(effectiveErrorHue,
      math.max(errorMinChroma ?? 0, effectiveErrorChroma), paletteType);

  return FlexCorePalette(
    primary: tonalPrimary,
    secondary: tonalSecondary,
    tertiary: tonalTertiary,
    neutral: tonalNeutral,
    neutralVariant: tonalNeutralVariant,
    error: tonalError,
  );
}