easy_radial_gradient 1.0.3 copy "easy_radial_gradient: ^1.0.3" to clipboard
easy_radial_gradient: ^1.0.3 copied to clipboard

Design-tool-style radial gradients for Flutter. Define each stop as position + color + opacity (like Figma), with optional Gaussian and frosted-glass backdrop blur.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'easy_radial_gradient',
      debugShowCheckedModeBanner: false,
      theme: ThemeData.dark(
        useMaterial3: true,
      ).copyWith(scaffoldBackgroundColor: const Color(0xFF0E0B1A)),
      home: const PlaygroundPage(),
    );
  }
}

/// A color preset: a label and its list of [RadialStop]s.
class _Preset {
  const _Preset(this.label, this.stops);
  final String label;
  final List<RadialStop> stops;
}

const _presets = <_Preset>[
  _Preset('Sunset', [
    RadialStop.start(color: Color(0xFFFFF1C2)),
    RadialStop.at(0.35, color: Color(0xFFFFC857)),
    RadialStop.at(0.7, color: Color(0xFFFF4D8D)),
    RadialStop.end(color: Color(0xFFFF4D8D), opacity: 0.0),
  ]),
  _Preset('Ocean', [
    RadialStop.start(color: Color(0xFF8AF0FF)),
    RadialStop.at(0.5, color: Color(0xFF4DD0FF)),
    RadialStop.at(0.8, color: Color(0xFF7C4DFF)),
    RadialStop.end(color: Color(0xFF7C4DFF), opacity: 0.0),
  ]),
  _Preset('Frost (glass)', [
    RadialStop.start(color: Color(0xFFFFFFFF), opacity: 0.34),
    RadialStop.at(0.65, color: Color(0xFFFFFFFF), opacity: 0.12),
    RadialStop.end(color: Color(0xFFFFFFFF), opacity: 0.04),
  ]),
];

class PlaygroundPage extends StatefulWidget {
  const PlaygroundPage({super.key});

  @override
  State<PlaygroundPage> createState() => _PlaygroundPageState();
}

class _PlaygroundPageState extends State<PlaygroundPage> {
  double _blur = 0;
  double _backdropBlur = 14;
  double _radius = 0.5;
  double _corner = 36;
  bool _isCircle = false;
  int _presetIndex = 2; // Frost — shows backdrop blur nicely.

  @override
  Widget build(BuildContext context) {
    final preset = _presets[_presetIndex];

    final box = RadialGradientBox(
      width: 240,
      height: _isCircle ? 240 : 200,
      radius: _radius,
      blur: _blur,
      backdropBlur: _backdropBlur,
      shape: _isCircle ? BoxShape.circle : BoxShape.rectangle,
      borderRadius: _isCircle ? null : BorderRadius.circular(_corner),
      colorStops: preset.stops,
    );

    return Scaffold(
      appBar: AppBar(
        title: const Text('easy_radial_gradient'),
        backgroundColor: Colors.transparent,
      ),
      body: SafeArea(
        child: Column(
          children: [
            // Live preview, with colorful blobs behind so backdrop blur shows.
            Expanded(
              child: Stack(
                alignment: Alignment.center,
                children: [
                  const Positioned(
                    left: 36,
                    top: 24,
                    child: _Blob(0xFFFF2D7E, 200),
                  ),
                  const Positioned(
                    right: 28,
                    bottom: 18,
                    child: _Blob(0xFF22C3FF, 220),
                  ),
                  const Positioned(
                    right: 70,
                    top: 30,
                    child: _Blob(0xFFFFB020, 150),
                  ),
                  box,
                ],
              ),
            ),

            // Controls.
            Container(
              padding: const EdgeInsets.fromLTRB(20, 12, 20, 20),
              decoration: const BoxDecoration(
                color: Color(0xFF161427),
                borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
              ),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Wrap(
                    spacing: 8,
                    children: [
                      for (var i = 0; i < _presets.length; i++)
                        ChoiceChip(
                          label: Text(_presets[i].label),
                          selected: _presetIndex == i,
                          onSelected: (_) => setState(() => _presetIndex = i),
                        ),
                    ],
                  ),
                  const SizedBox(height: 8),
                  Row(
                    children: [
                      const Text('Shape'),
                      const SizedBox(width: 12),
                      SegmentedButton<bool>(
                        segments: const [
                          ButtonSegment(value: true, label: Text('Circle')),
                          ButtonSegment(value: false, label: Text('Rounded')),
                        ],
                        selected: {_isCircle},
                        onSelectionChanged: (s) =>
                            setState(() => _isCircle = s.first),
                      ),
                    ],
                  ),
                  _slider('blur', _blur, 0, 40, (v) => _blur = v),
                  _slider(
                    'backdropBlur',
                    _backdropBlur,
                    0,
                    40,
                    (v) => _backdropBlur = v,
                  ),
                  _slider('radius', _radius, 0.1, 1.0, (v) => _radius = v),
                  if (!_isCircle)
                    _slider('corner', _corner, 0, 100, (v) => _corner = v),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _slider(
    String label,
    double value,
    double min,
    double max,
    ValueChanged<double> onChanged,
  ) {
    return Row(
      children: [
        SizedBox(
          width: 104,
          child: Text(label, style: const TextStyle(fontSize: 13)),
        ),
        Expanded(
          child: Slider(
            value: value,
            min: min,
            max: max,
            onChanged: (v) => setState(() => onChanged(v)),
          ),
        ),
        SizedBox(
          width: 44,
          child: Text(
            value.toStringAsFixed(max <= 1 ? 2 : 0),
            textAlign: TextAlign.end,
            style: const TextStyle(
              fontFeatures: [FontFeature.tabularFigures()],
            ),
          ),
        ),
      ],
    );
  }
}

class _Blob extends StatelessWidget {
  const _Blob(this.color, this.size);

  final int color;
  final double size;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: size,
      height: size,
      decoration: BoxDecoration(
        shape: BoxShape.circle,
        gradient: EasyRadialGradient(
          colorStops: [
            RadialStop.start(color: Color(color)),
            RadialStop.at(0.6, color: Color(color)),
            RadialStop.end(color: Color(color), opacity: 0.0),
          ],
        ),
      ),
    );
  }
}
0
likes
0
points
514
downloads

Publisher

unverified uploader

Weekly Downloads

Design-tool-style radial gradients for Flutter. Define each stop as position + color + opacity (like Figma), with optional Gaussian and frosted-glass backdrop blur.

Repository (GitHub)
View/report issues

Topics

#gradient #radial-gradient #blur #ui #design

License

unknown (license)

Dependencies

flutter

More

Packages that depend on easy_radial_gradient