Line data Source code
1 : import 'dart:ui';
2 :
3 : export 'dart:ui' show Color;
4 :
5 : extension ColorExtension on Color {
6 : /// Darken the shade of the color by the [amount].
7 : ///
8 : /// [amount] is a double between 0 and 1.
9 : ///
10 : /// Based on: https://stackoverflow.com/a/60191441.
11 0 : Color darken(double amount) {
12 0 : assert(amount >= 0 && amount <= 1);
13 :
14 0 : final f = 1 - amount;
15 0 : return Color.fromARGB(
16 0 : alpha,
17 0 : (red * f).round(),
18 0 : (green * f).round(),
19 0 : (blue * f).round(),
20 : );
21 : }
22 :
23 : /// Brighten the shade of the color by the [amount].
24 : ///
25 : /// [amount] is a double between 0 and 1.
26 : ///
27 : /// Based on: https://stackoverflow.com/a/60191441.
28 0 : Color brighten(double amount) {
29 0 : assert(amount >= 0 && amount <= 1);
30 :
31 0 : return Color.fromARGB(
32 0 : alpha,
33 0 : red + ((255 - red) * amount).round(),
34 0 : green + ((255 - green) * amount).round(),
35 0 : blue + ((255 - blue) * amount).round(),
36 : );
37 : }
38 :
39 : /// Parses an RGB color from a valid hex string (e.g. #1C1C1C).
40 : ///
41 : /// The `#` is optional.
42 : /// The short-hand syntax is support, e.g.: #CCC.
43 : /// Lower-case letters are supported.
44 : ///
45 : /// Examples of valid inputs:
46 : /// ccc, CCC, #ccc, #CCC, #c1c1c1, #C1C1C1, c1c1c1, C1C1C1
47 : ///
48 : /// If the string is not valid, an error is thrown.
49 : ///
50 : /// Note: if you are hardcoding colors, use Dart's built-in hexadecimal
51 : /// literals instead.
52 1 : static Color fromRGBHexString(String hexString) {
53 4 : if (hexString.length == 3 || hexString.length == 4) {
54 1 : return _parseRegex(1, 3, hexString);
55 4 : } else if (hexString.length == 6 || hexString.length == 7) {
56 1 : return _parseRegex(2, 3, hexString);
57 : } else {
58 0 : throw 'Invalid format for RGB hex string: $hexString';
59 : }
60 : }
61 :
62 : /// Parses an ARGB color from a valid hex string (e.g. #1C1C1C).
63 : ///
64 : /// The `#` is optional.
65 : /// The short-hand syntax is support, e.g.: #CCCC.
66 : /// Lower-case letters are supported.
67 : ///
68 : /// Examples of valid inputs:
69 : /// fccc, FCCC, #fccc, #FCCC, #ffc1c1c1, #FFC1C1C1, ffc1c1c1, FFC1C1C1
70 : ///
71 : /// If the string is not valid, an error is thrown.
72 : ///
73 : /// Note: if you are hardcoding colors, use Dart's built-in hexadecimal
74 : /// literals instead.
75 1 : static Color fromARGBHexString(String hexString) {
76 4 : if (hexString.length == 4 || hexString.length == 5) {
77 1 : return _parseRegex(1, 4, hexString);
78 4 : } else if (hexString.length == 8 || hexString.length == 9) {
79 1 : return _parseRegex(2, 4, hexString);
80 : } else {
81 0 : throw 'Invalid format for ARGB hex string: $hexString';
82 : }
83 : }
84 :
85 1 : static Color _parseRegex(int size, int blocks, String target) {
86 4 : final groups = [for (var i = 1; i <= blocks; i++) i];
87 4 : final regexBlocks = groups.map((_) => '([0-9a-fA-F]{$size})').join();
88 2 : final regex = RegExp('^\\#?$regexBlocks\$');
89 1 : final matcher = regex.firstMatch(target)!;
90 : final extracted = matcher
91 1 : .groups(groups)
92 2 : .map((e) => e!)
93 4 : .map((e) => size == 1 ? '$e$e' : e)
94 3 : .map((e) => int.parse(e, radix: 16))
95 1 : .toList();
96 4 : final components = [if (blocks == 3) 255, ...extracted];
97 1 : return Color.fromARGB(
98 1 : components[0],
99 1 : components[1],
100 1 : components[2],
101 1 : components[3],
102 : );
103 : }
104 : }
|