Glossy, candy-style text for Flutter. Each glyph gets an outline stroke that hugs its edge and a vertical gradient fill with a light highlight band near the top and a fainter reflected-light band near the bottom — the way hard candy or glossy plastic catches light. Optionally, an animated light sweep shimmers across the glyphs.
A flat colored Text reads much lighter than a designer's "candy" mock.
This package recreates the treatment with plain Flutter primitives — no
shaders to bundle, no images, works everywhere Flutter renders text.
Quick start
dependencies:
glossy_text: ^0.1.0
import 'package:glossy_text/glossy_text.dart';
GlossyText(
'128',
style: TextStyle(fontSize: 64, fontWeight: FontWeight.w800),
)
That's it — the default effect is the hot-pink candy treatment. Pass
shimmer: true for the animated light sweep.
Presets
GlossyText('Candy', effect: GlossyTextEffect.gold)
pink, gold, silver, grape, ocean, lime, tangerine, mint.
The metallic presets hold up nicely on dark backgrounds:
One color in, candy out
GlossyTextEffect.candy() derives the whole treatment — outline, highlight
band, body, reflected band — from a single color, by lifting its lightness in
HSL space. Hand it your brand color and you're done:
GlossyText(
'Sweet!',
effect: GlossyTextEffect.candy(Color(0xFF8E44E0)),
shimmer: true,
)
Full control
Every layer is configurable:
GlossyText(
'Custom',
style: TextStyle(fontSize: 56, fontWeight: FontWeight.w800),
effect: GlossyTextEffect(
strokeColor: Color(0xFF0E7490),
strokeWidth: 3,
shadows: [Shadow(color: Color(0x550E7490), blurRadius: 12, offset: Offset(0, 4))],
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [/* your ramp */],
stops: GlossyTextEffect.candyStops, // or your own
),
),
shimmer: true,
shimmerColor: Color(0x8CFFFFFF),
shimmerDuration: Duration(milliseconds: 2400),
)
How it works
GlossyText stacks up to four Text layers sharing one TextStyle, so they
stay aligned glyph-for-glyph:
- Shadow pass (optional) — transparent fill, shadows only.
- Stroke pass —
foregroundpaint in stroke mode, centered on the glyph edge, so half the stroke shows outside the fill. - Fill pass — the same text under a
ShaderMask(BlendMode.srcIn) that replaces the glyph pixels with the gradient. - Sheen pass (optional) — a diagonal light band swept across the glyphs
by an
AnimationController, masked to the glyphs the same way.
Accessibility: screen readers see the text exactly once (the duplicate
layers are excluded from semantics), and semanticsLabel lets you override
it — e.g. GlossyText('128', semanticsLabel: '128 day streak').
Tips
- Chunky rounded fonts (Baloo, Nunito, Fredoka, Averta) sell the candy look best. The screenshots use Baloo 2.
strokeWidthis in logical pixels and tuned for ~50 px text; scale it with your font size (copyWith(strokeWidth: ...)).- The gradient spans the full line box, not the glyph bounds. With unusual
line heights, tweak the stops (
candyStopsis a good starting point).
Example app
The example is a small showcase: the original streak counter this effect was extracted from, the preset gallery, and a live "candy lab" with hue/stroke sliders and a shimmer toggle.
cd example
flutter run
Origin
Extracted from a production e-commerce app, where a designer's Figma mock of
a streak counter had this glossy treatment and a flat pink Text just
didn't look right.
License
Libraries
- glossy_text
- Glossy "candy" text for Flutter: outlined, gradient-filled glyphs with highlight bands and an optional animated shimmer sweep.