Enhanced Gradients
Enhance your Flutter gradients with perceptually smoother color transitions by interpolating colors in the HCT (Hue, Chroma, Tone) color space provided by Material Design.
Installation
Add the package to your pubspec.yaml:
dependencies :
enhanced_gradients : ^2.0.0
Import
import 'package:enhanced_gradients/enhanced_gradients.dart' ;
Understanding HCT Color System
The HCT color system is part of Material Design 3 and provides a more perceptually uniform way to interpolate between colors compared to traditional RGB or HSL interpolation.
HCT stands for:
H ue: The color’s position on the color wheel (0-360 degrees)
C hroma: The color’s colorfulness or saturation
T one: The color’s lightness (perceptually uniform)
When you interpolate between colors in HCT space, the transitions appear smoother and more natural to the human eye, especially when transitioning between different hues.
Usage
There are two ways to create enhanced gradients:
1. Extension Method
Use the .enhanced() extension on existing gradient objects:
Linear Gradient
Radial Gradient
Sweep Gradient
LinearGradient (
colors : const [
Color ( 0xFF6200EE ),
Color ( 0xFF03DAC6 ),
],
). enhanced ()
2. Enhanced Gradient Classes
Use the dedicated Enhanced*Gradient classes:
EnhancedLinearGradient
EnhancedRadialGradient
EnhancedSweepGradient
EnhancedLinearGradient (
begin : Alignment .topLeft,
end : Alignment .bottomRight,
colors : const [
Color ( 0xFF000000 ),
Color ( 0xFFFFFFFF ),
],
)
Examples
Basic Example
Here’s a simple comparison between a regular gradient and an enhanced gradient:
class GradientComparison extends StatelessWidget {
@override
Widget build ( BuildContext context) {
final colors = [
Color ( 0xFF6200EE ),
Color ( 0xFF03DAC6 ),
];
return Row (
children : [
// Regular gradient
Expanded (
child : Container (
height : 200 ,
decoration : BoxDecoration (
gradient : LinearGradient (
colors : colors,
begin : Alignment .topCenter,
end : Alignment .bottomCenter,
),
),
),
),
// Enhanced gradient
Expanded (
child : Container (
height : 200 ,
decoration : BoxDecoration (
gradient : LinearGradient (
colors : colors,
begin : Alignment .topCenter,
end : Alignment .bottomCenter,
). enhanced (),
),
),
),
],
);
}
}
Complete Example from Source
The following example demonstrates a gradient comparison tool:
class GradientShowcase extends StatefulWidget {
@override
State < GradientShowcase > createState () => _GradientShowcaseState ();
}
class _GradientShowcaseState extends State < GradientShowcase > {
List < Color > _colors = [
Color ( 0xFF6200EE ),
Color ( 0xFF03DAC6 ),
];
@override
Widget build ( BuildContext context) {
final linearGradient = LinearGradient (
colors : _colors,
begin : Alignment .topCenter,
end : Alignment .bottomCenter,
);
final radialGradient = RadialGradient (colors : _colors);
final sweepGradient = SweepGradient (colors : _colors);
return Scaffold (
body : ListView (
children : [
Text (
'Regular gradient vs Enhanced gradient' ,
textAlign : TextAlign .center,
),
// Linear comparison
_GradientComparison (
gradientA : linearGradient,
gradientB : linearGradient. enhanced (),
),
// Radial comparison
_GradientComparison (
gradientA : radialGradient,
gradientB : radialGradient. enhanced (),
),
// Sweep comparison
_GradientComparison (
gradientA : sweepGradient,
gradientB : sweepGradient. enhanced (),
),
],
),
);
}
}
Advanced Configuration
Approximation Subdivisions
You can control the smoothness of the gradient by adjusting the approximation subdivisions:
Per Gradient
Global Configuration
EnhancedLinearGradient (
colors : colors,
approximationSubdivisions : 8 , // Higher = smoother (default: 6)
)
// Or with extension:
LinearGradient (colors : colors). enhanced (
approximationSubdivisions : 8 ,
)
// Set globally for all enhanced gradients
void main () {
EnhancedGradientsGlobalConfig .approximationSubdivisions = 8 ;
runApp ( MyApp ());
}
Higher subdivision values create smoother gradients but may impact performance. The default value of 6 provides a good balance.
HctColorTween for Animations
Use HctColorTween instead of ColorTween for smoother color transitions in animations:
class AnimatedColorBox extends StatefulWidget {
@override
State < AnimatedColorBox > createState () => _AnimatedColorBoxState ();
}
class _AnimatedColorBoxState extends State < AnimatedColorBox >
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation < Color ?> _colorAnimation;
@override
void initState () {
super . initState ();
_controller = AnimationController (
duration : Duration (seconds : 2 ),
vsync : this ,
).. repeat (reverse : true );
// Use HctColorTween for smoother transitions
_colorAnimation = HctColorTween (
begin : Color ( 0xFF6200EE ),
end : Color ( 0xFF03DAC6 ),
). animate (_controller);
}
@override
Widget build ( BuildContext context) {
return AnimatedBuilder (
animation : _colorAnimation,
builder : (context, child) {
return Container (
width : 200 ,
height : 200 ,
color : _colorAnimation.value,
);
},
);
}
@override
void dispose () {
_controller. dispose ();
super . dispose ();
}
}
Visual Comparison
The package includes visual examples showing the difference between regular and enhanced gradients. Here’s what you can expect:
Regular Gradient Issues:
May show muddy or grayish transitions between complementary colors
Uneven perceived brightness changes
Less vibrant intermediate colors
Enhanced Gradient Benefits:
Cleaner, more vibrant transitions
Perceptually uniform brightness changes
More natural-looking color progressions
When to Use Enhanced Gradients
Complementary colors
When transitioning between opposite colors on the color wheel (e.g., blue to orange)
Multiple color stops
When using gradients with three or more colors
Brand colors
When working with specific brand colors that need to look perfect
Material Design 3
When building apps following Material Design 3 guidelines
API Reference
Extension Methods
extension EnhancedLinearGradientExtension on LinearGradient {
LinearGradient enhanced ({ int ? approximationSubdivisions});
}
extension EnhancedRadialGradientExtension on RadialGradient {
RadialGradient enhanced ({ int ? approximationSubdivisions});
}
extension EnhancedSweepGradientExtension on SweepGradient {
SweepGradient enhanced ({ int ? approximationSubdivisions});
}
Helper Functions
// Linearly interpolate colors in HCT color space
Color ? lerpHct ( Color ? colorA, Color ? colorB, double t);
Enhanced gradients perform color interpolation during construction
The result is cached, so there’s no runtime performance impact
Higher approximation subdivisions slightly increase construction time
Memory usage is comparable to regular gradients
Source Code
View the source code on GitHub .