glossy_text 0.1.0 copy "glossy_text: ^0.1.0" to clipboard
glossy_text: ^0.1.0 copied to clipboard

Glossy candy-style text for Flutter: outlined, gradient-filled glyphs with highlight bands, color-derived presets, and an animated shimmer sweep.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:glossy_text/glossy_text.dart';

void main() => runApp(const GlossyTextDemoApp());

/// Rounded, chunky display style that suits the candy treatment.
TextStyle baloo(double size, {double weight = 800, double? letterSpacing}) {
  return TextStyle(
    fontFamily: 'Baloo 2',
    fontSize: size,
    height: 1,
    letterSpacing: letterSpacing,
    fontVariations: [FontVariation('wght', weight)],
  );
}

class GlossyTextDemoApp extends StatelessWidget {
  const GlossyTextDemoApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'glossy_text demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFFE6307D)),
        scaffoldBackgroundColor: const Color(0xFFFFF6F9),
        useMaterial3: true,
      ),
      home: const ShowcasePage(),
    );
  }
}

class ShowcasePage extends StatelessWidget {
  const ShowcasePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        padding: const EdgeInsets.symmetric(vertical: 48),
        children: const [
          _Hero(),
          SizedBox(height: 40),
          _SectionTitle('The original: streak counter'),
          StreakDemo(),
          SizedBox(height: 40),
          _SectionTitle('Presets'),
          PresetGallery(),
          SizedBox(height: 40),
          _SectionTitle('Make your own with GlossyTextEffect.candy()'),
          CandyLab(),
          SizedBox(height: 48),
        ],
      ),
    );
  }
}

class _Hero extends StatelessWidget {
  const _Hero();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        GlossyText(
          'Glossy',
          style: baloo(76, letterSpacing: 2),
          effect: GlossyTextEffect.pink.copyWith(strokeWidth: 3.5),
          shimmer: true,
        ),
        const SizedBox(height: 8),
        Text(
          'candy-style text for Flutter',
          style: baloo(18, weight: 600).copyWith(
            color: const Color(0xFFB36A88),
          ),
        ),
      ],
    );
  }
}

class _SectionTitle extends StatelessWidget {
  const _SectionTitle(this.title);

  final String title;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(24, 0, 24, 16),
      child: Text(
        title,
        textAlign: TextAlign.center,
        style: baloo(15, weight: 700).copyWith(
          color: const Color(0xFF9A8390),
          letterSpacing: 0.4,
        ),
      ),
    );
  }
}

/// The treatment this package was extracted from: a big glossy streak
/// number above a small label.
class StreakDemo extends StatelessWidget {
  const StreakDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 56, vertical: 28),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(28),
          boxShadow: const [
            BoxShadow(
              color: Color(0x14E6307D),
              blurRadius: 24,
              offset: Offset(0, 8),
            ),
          ],
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            GlossyText(
              '128',
              style: baloo(56, letterSpacing: 2),
              semanticsLabel: '128 day streak',
            ),
            const SizedBox(height: 10),
            const Text(
              'day streak',
              style: TextStyle(fontSize: 14, color: Color(0xFFE6307D)),
            ),
          ],
        ),
      ),
    );
  }
}

class PresetGallery extends StatelessWidget {
  const PresetGallery({super.key});

  static final presets = <(String, GlossyTextEffect)>[
    ('pink', GlossyTextEffect.pink),
    ('gold', GlossyTextEffect.gold),
    ('silver', GlossyTextEffect.silver),
    ('grape', GlossyTextEffect.grape),
    ('ocean', GlossyTextEffect.ocean),
    ('lime', GlossyTextEffect.lime),
    ('tangerine', GlossyTextEffect.tangerine),
    ('mint', GlossyTextEffect.mint),
  ];

  @override
  Widget build(BuildContext context) {
    return Wrap(
      alignment: WrapAlignment.center,
      spacing: 16,
      runSpacing: 16,
      children: [
        for (final (name, effect) in presets)
          Container(
            width: 168,
            padding: const EdgeInsets.symmetric(vertical: 20),
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(20),
            ),
            child: Column(
              children: [
                GlossyText('Candy', style: baloo(34), effect: effect),
                const SizedBox(height: 8),
                Text(
                  '.$name',
                  style: const TextStyle(
                    fontSize: 12,
                    color: Color(0xFF9A8390),
                  ),
                ),
              ],
            ),
          ),
      ],
    );
  }
}

/// Live editor: derive a full glossy effect from a single color, tweak the
/// stroke, toggle the shimmer.
class CandyLab extends StatefulWidget {
  const CandyLab({super.key});

  @override
  State<CandyLab> createState() => _CandyLabState();
}

class _CandyLabState extends State<CandyLab> {
  double _hue = 265;
  double _strokeWidth = 3;
  bool _shimmer = true;

  Color get _base => HSLColor.fromAHSL(1, _hue, 0.78, 0.55).toColor();

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 360,
        padding: const EdgeInsets.all(24),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(28),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            SizedBox(
              height: 96,
              child: Center(
                child: GlossyText(
                  'Sweet!',
                  style: baloo(56),
                  effect: GlossyTextEffect.candy(
                    _base,
                    strokeWidth: _strokeWidth,
                  ),
                  shimmer: _shimmer,
                ),
              ),
            ),
            const SizedBox(height: 8),
            _LabeledSlider(
              label: 'hue',
              value: _hue,
              max: 360,
              activeColor: _base,
              onChanged: (v) => setState(() => _hue = v),
            ),
            _LabeledSlider(
              label: 'stroke',
              value: _strokeWidth,
              max: 8,
              activeColor: _base,
              onChanged: (v) => setState(() => _strokeWidth = v),
            ),
            SwitchListTile(
              title: const Text('shimmer'),
              dense: true,
              contentPadding: EdgeInsets.zero,
              activeTrackColor: _base,
              value: _shimmer,
              onChanged: (v) => setState(() => _shimmer = v),
            ),
          ],
        ),
      ),
    );
  }
}

class _LabeledSlider extends StatelessWidget {
  const _LabeledSlider({
    required this.label,
    required this.value,
    required this.max,
    required this.activeColor,
    required this.onChanged,
  });

  final String label;
  final double value;
  final double max;
  final Color activeColor;
  final ValueChanged<double> onChanged;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        SizedBox(
          width: 56,
          child: Text(label, style: const TextStyle(fontSize: 13)),
        ),
        Expanded(
          child: Slider(
            value: value,
            max: max,
            activeColor: activeColor,
            onChanged: onChanged,
          ),
        ),
      ],
    );
  }
}
1
likes
160
points
30
downloads
screenshot

Documentation

API reference

Publisher

verified publishersolospark.mn

Weekly Downloads

Glossy candy-style text for Flutter: outlined, gradient-filled glyphs with highlight bands, color-derived presets, and an animated shimmer sweep.

Repository (GitHub)
View/report issues

Topics

#text #typography #gradient #shimmer #widget

License

MIT (license)

Dependencies

flutter

More

Packages that depend on glossy_text