Skip to main content

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

A Flutter package for creating beautiful, highly customizable fluid mesh gradients with custom shaders and static image export.

example/lib/main.dart

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_mesh_gradients/flutter_mesh_gradients.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Mesh Gradients Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MainScreen(),
      debugShowCheckedModeBanner: false,
    );
  }
}

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

  @override
  State<MainScreen> createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  int _currentIndex = 0;

  final List<Widget> _pages = [
    const FullScreenDemo(),
    const ComponentsDemo(),
    const PalettesDemo(),
    const StaticDemo(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _pages[_currentIndex],
      bottomNavigationBar: NavigationBar(
        selectedIndex: _currentIndex,
        onDestinationSelected: (index) {
          setState(() {
            _currentIndex = index;
          });
        },
        destinations: const [
          NavigationDestination(
            icon: Icon(Icons.fullscreen),
            label: 'Full Screen',
          ),
          NavigationDestination(
            icon: Icon(Icons.widgets),
            label: 'Components',
          ),
          NavigationDestination(
            icon: Icon(Icons.palette),
            label: 'Palettes',
          ),
          NavigationDestination(
            icon: Icon(Icons.image),
            label: 'Static',
          ),
        ],
      ),
    );
  }
}

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

  @override
  State<FullScreenDemo> createState() => _FullScreenDemoState();
}

class _FullScreenDemoState extends State<FullScreenDemo> {
  double _amplitude = 0.2;
  double _frequency = 0.5;
  double _blur = 1.0;
  double _speed = 1.0;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        // Background Mesh Gradient
        Positioned.fill(
          child: FluidMeshGradient(
            animate: true,
            time: 15,
            options: MeshGradientOptions(
              speed: _speed,
              amplitude: _amplitude,
              frequency: _frequency,
              blur: _blur,

              color1: const Color(0xFF6A0DAD), // Deep Purple
              color2: const Color(0xFFFF007F), // Neon Pink
              color3: const Color(0xFF00E5FF), // Cyan
              color4: const Color(0xFFFFD700), // Gold
            ),
          ),
        ),
        
        // Overlay content
        SafeArea(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Expanded(
                child: Center(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      const Text(
                        'Fluid Mesh',
                        style: TextStyle(
                          fontSize: 48,
                          fontWeight: FontWeight.bold,
                          color: Colors.white,
                          letterSpacing: -1.0,
                        ),
                      ),
                      const SizedBox(height: 16),
                      Container(
                        padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
                        decoration: BoxDecoration(
                          color: Colors.white.withValues(alpha: 0.2),
                          borderRadius: BorderRadius.circular(30),
                          border: Border.all(
                            color: Colors.white.withValues(alpha: 0.3),
                            width: 1,
                          ),
                        ),
                        child: const Text(
                          'Stunning Animations',
                          style: TextStyle(
                            fontSize: 18,
                            color: Colors.white,
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              // Controls
              Container(
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  color: Colors.black.withValues(alpha: 0.5),
                  borderRadius: const BorderRadius.vertical(top: Radius.circular(24)),
                ),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    _buildSlider('Amplitude', _amplitude, 0.0, 1.0, (v) => setState(() => _amplitude = v)),
                    _buildSlider('Frequency', _frequency, 0.0, 10.0, (v) => setState(() => _frequency = v)),
                    _buildSlider('Blur', _blur, 0.1, 5.0, (v) => setState(() => _blur = v)),
                    _buildSlider('Speed', _speed, 0.0, 5.0, (v) => setState(() => _speed = v)),
                  ],
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }

  Widget _buildSlider(String label, double value, double min, double max, ValueChanged<double> onChanged) {
    return Row(
      children: [
        SizedBox(
          width: 80,
          child: Text(
            label,
            style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
          ),
        ),
        Expanded(
          child: Slider(
            value: value,
            min: min,
            max: max,
            activeColor: Colors.white,
            inactiveColor: Colors.white.withValues(alpha: 0.3),
            onChanged: onChanged,
          ),
        ),
        SizedBox(
          width: 40,
          child: Text(
            value.toStringAsFixed(1),
            style: const TextStyle(color: Colors.white),
          ),
        ),
      ],
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Components'),
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          const Text(
            'Card Background',
            style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 12),
          SizedBox(
            height: 200,
            child: ClipRRect(
              borderRadius: BorderRadius.circular(24),
              child: Stack(
                children: [
                  const Positioned.fill(
                    child: FluidMeshGradient(
                      options: MeshGradientOptions(
                        speed: 2.0,
                        color1: Color(0xFF00C9FF),
                        color2: Color(0xFF92FE9D),
                        color3: Color(0xFF00C9FF),
                        color4: Color(0xFF92FE9D),
                      ),
                    ),
                  ),
                  Center(
                    child: Text(
                      'Beautiful Card',
                      style: TextStyle(
                        fontSize: 28,
                        fontWeight: FontWeight.w800,
                        color: Colors.white.withValues(alpha: 0.9),
                        shadows: [
                          Shadow(
                            color: Colors.black.withValues(alpha: 0.3),
                            blurRadius: 8,
                          ),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
          const SizedBox(height: 32),
          const Text(
            'Button Background',
            style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 12),
          Center(
            child: SizedBox(
              width: 250,
              height: 60,
              child: ClipRRect(
                borderRadius: BorderRadius.circular(30),
                child: Stack(
                  children: [
                    const Positioned.fill(
                      child: FluidMeshGradient(
                        options: MeshGradientOptions(
                          speed: 3.0,
                          color1: Color(0xFFFF512F),
                          color2: Color(0xFFDD2476),
                          color3: Color(0xFFFF512F),
                          color4: Color(0xFFDD2476),
                        ),
                      ),
                    ),
                    Positioned.fill(
                      child: Material(
                        color: Colors.transparent,
                        child: InkWell(
                          onTap: () {},
                          splashColor: Colors.white.withValues(alpha: 0.3),
                          highlightColor: Colors.white.withValues(alpha: 0.1),
                          child: const Center(
                            child: Text(
                              'Tap Me!',
                              style: TextStyle(
                                color: Colors.white,
                                fontSize: 18,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Palettes & Speeds'),
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          _buildPaletteCard(
            title: 'Sunset (Slow)',
            speed: 0.5,
            color1: const Color(0xFFFDC830),
            color2: const Color(0xFFF37335),
            color3: const Color(0xFFFDC830),
            color4: const Color(0xFFF37335),
          ),
          const SizedBox(height: 16),
          _buildPaletteCard(
            title: 'Ocean (Medium)',
            speed: 1.5,
            color1: const Color(0xFF2E3192),
            color2: const Color(0xFF1BFFFF),
            color3: const Color(0xFF2E3192),
            color4: const Color(0xFF1BFFFF),
          ),
          const SizedBox(height: 16),
          _buildPaletteCard(
            title: 'Neon (Fast)',
            speed: 4.0,
            color1: const Color(0xFFFF00FF),
            color2: const Color(0xFF00FFFF),
            color3: const Color(0xFFFF00FF),
            color4: const Color(0xFF00FFFF),
          ),
        ],
      ),
    );
  }

  Widget _buildPaletteCard({
    required String title,
    required double speed,
    required Color color1,
    required Color color2,
    required Color color3,
    required Color color4,
  }) {
    return SizedBox(
      height: 150,
      child: ClipRRect(
        borderRadius: BorderRadius.circular(20),
        child: Stack(
          children: [
            Positioned.fill(
              child: FluidMeshGradient(
                options: MeshGradientOptions(
                  speed: speed,
                  color1: color1,
                  color2: color2,
                  color3: color3,
                  color4: color4,
                ),
              ),
            ),
            Positioned(
              bottom: 16,
              left: 16,
              child: Container(
                padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                decoration: BoxDecoration(
                  color: Colors.black.withValues(alpha: 0.5),
                  borderRadius: BorderRadius.circular(20),
                ),
                child: Text(
                  title,
                  style: const TextStyle(
                    color: Colors.white,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

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

  @override
  State<StaticDemo> createState() => _StaticDemoState();
}

class _StaticDemoState extends State<StaticDemo> {
  Uint8List? _exportedBytes;
  bool _isExporting = false;

  Future<void> _exportImage() async {
    setState(() => _isExporting = true);
    try {
      final bytes = await MeshGradientExporter.exportImageBytes(
        size: const Size(300, 300),
        options: const MeshGradientOptions(
          color1: Color(0xFF6A0DAD),
          color2: Color(0xFFFF007F),
          color3: Color(0xFF00E5FF),
          color4: Color(0xFFFFD700),
          amplitude: 0.3,
          frequency: 1.2,
          speed: 1.0,
        ),
        time: 5.0, // A fixed moment in time
      );
      setState(() => _exportedBytes = bytes);
    } finally {
      setState(() => _isExporting = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Static & Export')),
      body: Center(
        child: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Text(
                'Static Mode (animate: false)',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 8),
              Container(
                width: 300,
                height: 200,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(20),
                  boxShadow: [
                    BoxShadow(color: Colors.black26, blurRadius: 10, offset: Offset(0, 5))
                  ],
                ),
                clipBehavior: Clip.antiAlias,
                child: const FluidMeshGradient(
                  animate: false,
                  time: 10,
                  options: MeshGradientOptions(
                    color1: Color(0xFF4CAF50),
                    color2: Color(0xFF8BC34A),
                    color3: Color(0xFFCDDC39),
                    color4: Color(0xFFFFEB3B),
                  ),
                ),
              ),
              const SizedBox(height: 32),
              const Text(
                'Export to Image',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 8),
              ElevatedButton.icon(
                onPressed: _isExporting ? null : _exportImage,
                icon: _isExporting
                    ? const SizedBox(width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2))
                    : const Icon(Icons.download),
                label: const Text('Export Gradient'),
              ),
              const SizedBox(height: 16),
              if (_exportedBytes != null) ...[
                const Text('Exported Result:'),
                const SizedBox(height: 8),
                Container(
                  decoration: BoxDecoration(
                    border: Border.all(color: Colors.grey),
                  ),
                  child: Image.memory(
                    _exportedBytes!,
                    width: 150,
                    height: 150,
                  ),
                ),
              ],
            ],
          ),
        ),
      ),
    );
  }
}
0
likes
160
points
155
downloads

Documentation

API reference

Publisher

verified publisherpinz.dev

Weekly Downloads

A Flutter package for creating beautiful, highly customizable fluid mesh gradients with custom shaders and static image export.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_mesh_gradients