ColorPalette.random constructor

ColorPalette.random(
  1. int numberOfColors, {
  2. ColorSpace colorSpace = ColorSpace.rgb,
  3. num minHue = 0,
  4. num maxHue = 360,
  5. num minSaturation = 0,
  6. num maxSaturation = 100,
  7. num minBrightness = 0,
  8. num maxBrightness = 100,
  9. bool perceivedBrightness = true,
  10. bool distributeHues = true,
  11. num? distributionVariability,
  12. bool clockwise = true,
  13. bool growable = true,
  14. bool unique = false,
})

Generates a ColorPalette with numberOfColors at random, constrained within the specified hue, saturation, and brightness ranges.

colorSpace defines the color space colors will be generated and returned in. colorSpace defaults to ColorSpace.rgb and must not be null.

minHue and maxHue are used to set the range of hues that will be selected from. If minHue < maxHue, the range will run in a clockwise direction between the two, however if minHue > maxHue, the range will run in a counter-clockwise direction. Both minHue and maxHue must be >= 0 && <= 360 and must not be null.

minSaturation and maxSaturation are used to set the range of the generated colors' saturation values. minSaturation must be <= maxSaturation and maxSaturation must be >= minSaturation. Both minSaturation and maxSaturation must be >= 0 && <= 100.

minBrightness and maxBrightness are used to set the range of the generated colors' brightness values. minBrightness must be <= maxBrightness and maxBrightness must be >= minBrightness. Both minBrightness and maxBrightness must be >= 0 && <= 100.

If perceivedBrightness is true, colors will be generated in the HSP color space. If false, colors will be generated in the HSB color space.

If distributeHues is true, the generated colors will be spread evenly across the range of hues allowed for. distributeHues must not be null.

distributionVariability will add a degree of randomness to the selected hues, if distributeHues is true. If null, distributionVariability defaults to (minHue - maxHue).abs() / numberOfColors / 4. To allow for no variability at all, distributionVariability must be set to 0.

If clockwise is false, colors will be generated in a clockwise order around the color wheel. If true, colors will be generated in a counter-clockwise order. clockwise will have no effect if distributeHues is false. clockwise must not be null.

If growable is false, a fixed-length the palette will be constructed with a fixed-length list. If true, a growable list will be used instead.

If unique is false, the palette will be constructed with a List. If true, a uniqueList will be used instead.

Implementation

factory ColorPalette.random(
  int numberOfColors, {
  ColorSpace colorSpace = ColorSpace.rgb,
  num minHue = 0,
  num maxHue = 360,
  num minSaturation = 0,
  num maxSaturation = 100,
  num minBrightness = 0,
  num maxBrightness = 100,
  bool perceivedBrightness = true,
  bool distributeHues = true,
  num? distributionVariability,
  bool clockwise = true,
  bool growable = true,
  bool unique = false,
}) {
  assert(numberOfColors > 0);
  assert(minHue >= 0 && minHue <= 360);
  assert(maxHue >= 0 && maxHue <= 360);
  assert(minSaturation >= 0 && minSaturation <= maxSaturation);
  assert(maxSaturation >= minSaturation && maxSaturation <= 100);
  assert(minBrightness >= 0 && minBrightness <= maxBrightness);
  assert(maxBrightness >= minBrightness && maxBrightness <= 100);

  if (!distributeHues &&
      (minHue == 0 && maxHue == 360) &&
      (minSaturation == 0 && maxSaturation == 100) &&
      (minBrightness == 0 && maxBrightness == 100)) {
    final generator = (_) {
      ColorModel color;

      switch (colorSpace) {
        case ColorSpace.cmyk:
          color = CmykColor.random();
          break;
        case ColorSpace.hsi:
          color = HsiColor.random();
          break;
        case ColorSpace.hsl:
          color = HslColor.random();
          break;
        case ColorSpace.hsp:
          color = HspColor.random();
          break;
        case ColorSpace.hsb:
          color = HsbColor.random();
          break;
        case ColorSpace.lab:
          color = LabColor.random();
          break;
        case ColorSpace.oklab:
          color = OklabColor.random();
          break;
        case ColorSpace.rgb:
          color = RgbColor.random();
          break;
        case ColorSpace.xyz:
          color = XyzColor.random();
          break;
      }

      return color;
    };

    return ColorPalette(unique
        ? UniqueList<ColorModel>.generate(numberOfColors, generator,
            growable: growable, strict: true)
        : List<ColorModel>.generate(numberOfColors, generator,
            growable: growable));
  }

  var distance = (minHue - maxHue) / numberOfColors;
  if (!clockwise) distance *= -1;

  distributionVariability ??= distance.abs() / 4;
  final variabilityRadius = distributionVariability / 2;

  final seed = _generateRandomColor(
    colorSpace,
    minHue,
    maxHue,
    minSaturation,
    maxSaturation,
    minBrightness,
    maxBrightness,
    perceivedBrightness,
  );

  final palette = <ColorModel>[seed];

  var hue = palette.first.hue;

  for (var i = 1; i < numberOfColors; i++) {
    hue += distance;
    minHue = (hue - variabilityRadius) % 360;
    maxHue = (hue + variabilityRadius) % 360;

    final color = _generateRandomColor(
      colorSpace,
      minHue,
      maxHue,
      minSaturation,
      maxSaturation,
      minBrightness,
      maxBrightness,
      perceivedBrightness,
    );

    palette.add(color);
  }

  return ColorPalette(unique
      ? UniqueList<ColorModel>.from(palette, growable: growable)
      : List<ColorModel>.from(palette, growable: growable));
}