createPrimarySwatch static method

MaterialColor createPrimarySwatch(
  1. Color color
)

Create a primary color Material swatch from a given color value.

The original version of this swatch calculation is based on this https://medium.com/@filipvk/creating-a-custom-color-swatch-in-flutter-554bcdcb27f3 by Filip Velickovic https://filipvk.bitbucket.io/ It has been slightly modified.

The provided color value is used as the Material swatch default color 500 in the returned swatch, with lighter hues for lower indexes and darker shades for higher index values.

If you give this function a standard Material color index 500 value, eg Colors.red[500] it will not return the same swatch as Colors.red. This function is an approximation and gives an automated way of creating a material like primary swatch.

The official Material colors contain hand picked references colors. To get an official Material swatch from a color use primarySwatch that returns the real Material swatch first for a color, if it is a standard Material primary color, and then creates a Material like swatch with this function, if it was not a standard material primary color hue.

There are reversed engineered JS versions of the official Material Color algorithm made from the Material Guide web tools. If anybody has the energy to make a Dart version of it, that would be fabulous. SO discussion here: https://stackoverflow.com/questions/32942503/material-design-color-palette

Starting points here:

The official M2 guide it should match: https://material.io/design/color/the-color-system.html#tools-for-picking-colors And its color tool where the JS reverse engineered version is from: https://material.io/resources/color/#!/?view.left=0&view.right=0&primary.color=6002ee

Implementation

static MaterialColor createPrimarySwatch(Color color) {
  final Map<int, Color> swatch = <int, Color>{};
  final int a = color.alpha;
  final int r = color.red;
  final int g = color.green;
  final int b = color.blue;
  for (final int strength in _indexPrimary) {
    final double ds = 0.5 - strength / 1000;
    swatch[strength] = Color.fromARGB(
      a,
      r + ((ds < 0 ? r : (255 - r)) * ds).round(),
      g + ((ds < 0 ? g : (255 - g)) * ds).round(),
      b + ((ds < 0 ? b : (255 - b)) * ds).round(),
    );
  }
  // The above gives a starting point, this tunes it a bit better, still far
  // from the real algorithm.
  swatch[50] = swatch[50]!.lighten(18);
  swatch[100] = swatch[100]!.lighten(16);
  swatch[200] = swatch[200]!.lighten(14);
  swatch[300] = swatch[300]!.lighten(10);
  swatch[400] = swatch[400]!.lighten(6);
  swatch[700] = swatch[700]!.darken(2);
  swatch[800] = swatch[800]!.darken(3);
  swatch[900] = swatch[900]!.darken(4);
  return MaterialColor(color.value, swatch);
}