glossy_text

pub package license: MIT

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.

animated shimmer

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

presets

GlossyText('Candy', effect: GlossyTextEffect.gold)

pink, gold, silver, grape, ocean, lime, tangerine, mint.

The metallic presets hold up nicely on dark backgrounds:

gold and silver on dark

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,
)

candy factory

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:

  1. Shadow pass (optional) — transparent fill, shadows only.
  2. Stroke passforeground paint in stroke mode, centered on the glyph edge, so half the stroke shows outside the fill.
  3. Fill pass — the same text under a ShaderMask (BlendMode.srcIn) that replaces the glyph pixels with the gradient.
  4. 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.
  • strokeWidth is 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 (candyStops is 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

MIT

Libraries

glossy_text
Glossy "candy" text for Flutter: outlined, gradient-filled glyphs with highlight bands and an optional animated shimmer sweep.