pulse_glow_button ✨

An eye-catching, high-conversion call-to-action button for Flutter featuring animated radiant ambient glow, concentric sonar ripple waves, tactile press physics, and seamless loading state transitions.

Designed to captivate user attention on hero actions, checkout pages, gamified rewards, and live media streaming states.

pub package License: MIT


✨ Features

  • 🌟 Radiant Ambient Glow: Organic breathing light aura radiating softly around the button with customizable blur radiuses and bloom colors.
  • πŸ“‘ Concentric Sonar Ripples: Pulsating wave rings expanding outwards with progressive opacity fade.
  • πŸ“³ Tactile Press Physics: Smooth spring compression scaling on finger press coupled with HapticFeedback.lightImpact().
  • ⏳ Integrated Loading Spinner: Instant switch between normal CTA content and a progress indicator with state preservation (isLoading: true).
  • 🎨 Gradient & Custom Shapes: Works with solid backgrounds, multi-stop linear gradients, rounded corners, or circular floating action buttons.
  • ⚑ Zero External Dependencies: Built 100% on Flutter's core animation primitives for 60/120fps performance without extra bloat.

πŸ“¦ Installation

Add pulse_glow_button to your pubspec.yaml:

dependencies:
  pulse_glow_button: ^1.0.1

Or install it via terminal:

flutter pub add pulse_glow_button

Import the package in your Dart code:

import 'package:pulse_glow_button/pulse_glow_button.dart';

πŸš€ Usage Examples

1. High-Conversion "Claim Reward" Hero CTA

PulseGlowButton(
  text: 'Claim Daily Reward',
  icon: const Icon(Icons.stars_rounded, color: Colors.amber, size: 24),
  style: PulseGlowStyle(
    glowColor: const Color(0xFF8B5CF6),
    backgroundColor: const Color(0xFF7C3AED),
    maxGlowRadius: 28.0,
    minGlowRadius: 10.0,
    rippleCount: 2,
    borderRadius: BorderRadius.circular(20),
    padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 16),
  ),
  onTap: () {
    print('Claiming reward!');
  },
)

2. Live Broadcast / Emergency Beacon with Gradient

PulseGlowButton(
  text: 'GO LIVE NOW',
  icon: const Icon(Icons.fiber_manual_record, color: Colors.white, size: 18),
  style: PulseGlowStyle(
    glowColor: const Color(0xFFEF4444),
    rippleColor: const Color(0xFFF87171),
    gradient: const LinearGradient(
      colors: [Color(0xFFEF4444), Color(0xFFDC2626)],
      begin: Alignment.topLeft,
      end: Alignment.bottomRight,
    ),
    rippleCount: 3,
    rippleMaxScale: 1.5,
    pulseDuration: const Duration(milliseconds: 1400),
    borderRadius: BorderRadius.circular(30),
  ),
  onTap: () => startLiveStream(),
)

3. Asynchronous Checkout Button with Loading State

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

  @override
  State<CheckoutButton> createState() => _CheckoutButtonState();
}

class _CheckoutButtonState extends State<CheckoutButton> {
  bool _processing = false;

  Future<void> _handlePayment() async {
    setState(() => _processing = true);
    await Future.delayed(const Duration(seconds: 2));
    if (mounted) setState(() => _processing = false);
  }

  @override
  Widget build(BuildContext context) {
    return PulseGlowButton(
      text: 'Complete Payment (\$49.00)',
      icon: const Icon(Icons.lock_outline, color: Colors.white),
      isLoading: _processing,
      style: PulseGlowStyle(
        glowColor: const Color(0xFF10B981),
        backgroundColor: const Color(0xFF059669),
        borderRadius: BorderRadius.circular(16),
      ),
      onTap: _handlePayment,
    );
  }
}

πŸ› οΈ API Reference

PulseGlowButton

Parameter Type Default Description
text String? null Primary text label displayed inside the button.
icon Widget? null Optional leading widget/icon shown before the text label.
child Widget? null Optional custom widget replacing the default row layout.
onTap VoidCallback? null Callback triggered when the button is tapped.
isLoading bool false When true, renders the loading spinner and disables taps.
loadingWidget Widget? null Custom widget to display when isLoading is true.
style PulseGlowStyle PulseGlowStyle() Custom visual style and animation attributes.
enableGlow bool true Toggles the breathing ambient glow bloom on/off.
enableRipples bool true Toggles expanding sonar wave rings on/off.
enableHaptics bool true Fires tactile vibration when pressed.
width double? null Optional explicit button width.
height double? null Optional explicit button height.

PulseGlowStyle

Parameter Type Default Description
glowColor Color Color(0xFF6366F1) Aura light color radiating around the button container.
backgroundColor Color Color(0xFF6366F1) Solid background fill if no gradient is set.
gradient Gradient? null Gradient fill for the button surface.
maxGlowRadius double 24.0 Maximum blur radius at peak of breathing glow cycle.
minGlowRadius double 8.0 Minimum blur radius at bottom of breathing glow cycle.
rippleColor Color? null Color of sonar ripples (defaults to glowColor).
rippleCount int 2 Number of concentric expanding rings.
rippleMaxScale double 1.4 Outer expansion boundary factor for sonar ripples.
borderRadius BorderRadius BorderRadius.circular(16) Corner radius of the button and its glow mask.
padding EdgeInsetsGeometry symmetric(h: 24, v: 14) Internal button content padding.
pulseDuration Duration 1800ms Duration of one complete breathing/ripple cycle.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

Author

Created by Shahzain Baloch.

Libraries

pulse_glow_button