Skip to content

Instantly share code, notes, and snippets.

@jhoffi
Last active December 20, 2023 09:14
Show Gist options
  • Save jhoffi/758fd5c5c51295d675bc2144033a1abe to your computer and use it in GitHub Desktop.
Save jhoffi/758fd5c5c51295d675bc2144033a1abe to your computer and use it in GitHub Desktop.
[TrackShape]: Class for flutter slider with gradient
import 'package:flutter/material.dart';
/// Based on https://www.youtube.com/watch?v=Wl4F5V6BoJw
class GradientRectSliderTrackShape extends SliderTrackShape
with BaseSliderTrackShape {
const GradientRectSliderTrackShape({
this.gradient = const LinearGradient(
colors: [
Colors.red,
Colors.yellow,
],
),
this.darkenInactive = true,
});
final LinearGradient gradient;
final bool darkenInactive;
@override
void paint(
PaintingContext context,
Offset offset,
{
required RenderBox parentBox,
required SliderThemeData sliderTheme,
required Animation<double> enableAnimation,
required TextDirection textDirection,
required Offset thumbCenter,
bool isDiscrete = false,
bool isEnabled = false,
double additionalActiveTrackHeight = 2,
}
) {
assert(sliderTheme.disabledActiveTrackColor != null);
assert(sliderTheme.disabledInactiveTrackColor != null);
assert(sliderTheme.activeTrackColor != null);
assert(sliderTheme.inactiveTrackColor != null);
assert(sliderTheme.thumbShape != null);
assert(sliderTheme.trackHeight != null && sliderTheme.trackHeight! > 0);
final Rect trackRect = getPreferredRect(
parentBox: parentBox,
offset: offset,
sliderTheme: sliderTheme,
isEnabled: isEnabled,
isDiscrete: isDiscrete,
);
final activeGradientRect = Rect.fromLTRB(
trackRect.left,
(textDirection == TextDirection.ltr)
? trackRect.top - (additionalActiveTrackHeight / 2)
: trackRect.top,
thumbCenter.dx,
(textDirection == TextDirection.ltr)
? trackRect.bottom + (additionalActiveTrackHeight / 2)
: trackRect.bottom,
);
// Assign the track segment paints, which are leading: active and
// trailing: inactive.
final ColorTween activeTrackColorTween = ColorTween(
begin: sliderTheme.disabledActiveTrackColor,
end: sliderTheme.activeTrackColor);
final ColorTween inactiveTrackColorTween = darkenInactive
? ColorTween(
begin: sliderTheme.disabledInactiveTrackColor,
end: sliderTheme.inactiveTrackColor
)
: activeTrackColorTween;
final Paint activePaint = Paint()
..shader = gradient.createShader(activeGradientRect)
..color = activeTrackColorTween.evaluate(enableAnimation)!;
final Paint inactivePaint = Paint()
..color = inactiveTrackColorTween.evaluate(enableAnimation)!;
final Paint leftTrackPaint;
final Paint rightTrackPaint;
switch (textDirection) {
case TextDirection.ltr:
leftTrackPaint = activePaint;
rightTrackPaint = inactivePaint;
break;
case TextDirection.rtl:
leftTrackPaint = inactivePaint;
rightTrackPaint = activePaint;
break;
}
final Radius trackRadius = Radius.circular(trackRect.height / 2);
final Radius activeTrackRadius = Radius.circular(trackRect.height / 2 + 1);
context.canvas.drawRRect(
RRect.fromLTRBAndCorners(
trackRect.left,
(textDirection == TextDirection.ltr)
? trackRect.top - (additionalActiveTrackHeight / 2)
: trackRect.top,
thumbCenter.dx,
(textDirection == TextDirection.ltr)
? trackRect.bottom + (additionalActiveTrackHeight / 2)
: trackRect.bottom,
topLeft: (textDirection == TextDirection.ltr)
? activeTrackRadius
: trackRadius,
bottomLeft: (textDirection == TextDirection.ltr)
? activeTrackRadius
: trackRadius,
),
leftTrackPaint,
);
context.canvas.drawRRect(
RRect.fromLTRBAndCorners(
thumbCenter.dx,
(textDirection == TextDirection.rtl)
? trackRect.top - (additionalActiveTrackHeight / 2)
: trackRect.top,
trackRect.right,
(textDirection == TextDirection.rtl)
? trackRect.bottom + (additionalActiveTrackHeight / 2)
: trackRect.bottom,
topRight: (textDirection == TextDirection.rtl)
? activeTrackRadius
: trackRadius,
bottomRight: (textDirection == TextDirection.rtl)
? activeTrackRadius
: trackRadius,
),
rightTrackPaint,
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment