Programmatically Lighten or Darken a hex color in dart
Color accurate solution with no plugin
The accepted answer changes the tint of colors when darkening (the tint is more saturated). Also its lightening function produces pure white with an amount of 0.3 for some colors although white should only be reached with an amount of 1.
The two following methods produce shades of the base color that seem 'darker' or 'lighter' without changing the tint.
import 'package:flutter/material.dart';
/// Darken a color by [percent] amount (100 = black)
// ........................................................
Color darken(Color c, [int percent = 10]) {
assert(1 <= percent && percent <= 100);
var f = 1 - percent / 100;
return Color.fromARGB(
c.alpha,
(c.red * f).round(),
(c.green * f).round(),
(c.blue * f).round()
);
}
/// Lighten a color by [percent] amount (100 = white)
// ........................................................
Color lighten(Color c, [int percent = 10]) {
assert(1 <= percent && percent <= 100);
var p = percent / 100;
return Color.fromARGB(
c.alpha,
c.red + ((255 - c.red) * p).round(),
c.green + ((255 - c.green) * p).round(),
c.blue + ((255 - c.blue) * p).round()
);
}
Example: darken a color by 15%.
final Color darkerGreen = darken(Color(0xFF159424), 15);
If starting from a Hex String value as OP asked, use J.M. Taylor' solution:
Color hexToColor(String code) {
return Color(int.parse(code.substring(0, 6), radix: 16) + 0xFF000000);
}
final Color darkerGreen = darken(hexToColor('#159424'));
Note: it's for Flutter projects as it uses the material's Color
class.
For people who want to darken or lighten Color
instead of hex string
// ranges from 0.0 to 1.0
Color darken(Color color, [double amount = .1]) {
assert(amount >= 0 && amount <= 1);
final hsl = HSLColor.fromColor(color);
final hslDark = hsl.withLightness((hsl.lightness - amount).clamp(0.0, 1.0));
return hslDark.toColor();
}
Color lighten(Color color, [double amount = .1]) {
assert(amount >= 0 && amount <= 1);
final hsl = HSLColor.fromColor(color);
final hslLight = hsl.withLightness((hsl.lightness + amount).clamp(0.0, 1.0));
return hslLight.toColor();
}
// usage
final lightRed = lighten(Colors.red);
final darkBlue = darken(Colors.blue, .3);
Live Demo
My solution based on https://stackoverflow.com/a/58604669/7479173
extension ColorBrightness on Color {
Color darken([double amount = .1]) {
assert(amount >= 0 && amount <= 1);
final hsl = HSLColor.fromColor(this);
final hslDark = hsl.withLightness((hsl.lightness - amount).clamp(0.0, 1.0));
return hslDark.toColor();
}
Color lighten([double amount = .1]) {
assert(amount >= 0 && amount <= 1);
final hsl = HSLColor.fromColor(this);
final hslLight =
hsl.withLightness((hsl.lightness + amount).clamp(0.0, 1.0));
return hslLight.toColor();
}
}
with this one can simply:
Colors.red.darken()
Colors.red.lighten()
Colors.red.lighten(0.1)
this works on any colors as long as you import the extension.
You can use tinycolor package:
TinyColor.fromString("#159424").darken(10).color
Edit:
You can convert Color
back to hex string like this:
String toHex(Color color) {
return "#${color.red.toRadixString(16).padLeft(2, "0")}"
"${color.green.toRadixString(16).padLeft(2, "0")}"
"${color.blue.toRadixString(16).padLeft(2, "0")}";
}
or if you want opacity/alpha:
String toHex(Color color) {
return "#${color.alpha.toRadixString(16).padLeft(2, "0")}"
"${color.red.toRadixString(16).padLeft(2, "0")}"
"${color.green.toRadixString(16).padLeft(2, "0")}"
"${color.blue.toRadixString(16).padLeft(2, "0")}";
}