image_blur_web 0.0.1 copy "image_blur_web: ^0.0.1" to clipboard
image_blur_web: ^0.0.1 copied to clipboard

A Flutter widget for progressive image loading with blur-to-sharp transition effect. Supports placeholder, thumbnail preview, and smooth animated transitions optimized for web.

example/lib/main.dart

// ignore_for_file: library_private_types_in_public_api

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ImageBlurWeb Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        brightness: Brightness.dark,
      ),
      home: ImageGalleryPage(),
    );
  }
}

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

  @override
  _ImageGalleryPageState createState() => _ImageGalleryPageState();
}

class _ImageGalleryPageState extends State<ImageGalleryPage> {
  final List<ImageItem> images = [
    ImageItem(
      thumbnailUrl: 'https://picsum.photos/id/1/200/200',
      imageUrl: 'https://picsum.photos/id/1/800/800',
      title: 'Nature 1',
    ),
    ImageItem(
      thumbnailUrl: 'https://picsum.photos/id/2/200/200',
      imageUrl: 'https://picsum.photos/id/2/800/800',
      title: 'Nature 2',
    ),
    ImageItem(
      thumbnailUrl: 'https://picsum.photos/id/3/200/200',
      imageUrl: 'https://picsum.photos/id/3/800/800',
      title: 'Nature 3',
    ),
    // Add more images...
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Gallery'),
        elevation: 0,
      ),
      body: GridView.builder(
        padding: EdgeInsets.all(16),
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: MediaQuery.of(context).size.width > 600 ? 3 : 2,
          crossAxisSpacing: 16,
          mainAxisSpacing: 16,
          childAspectRatio: 1,
        ),
        itemCount: images.length,
        itemBuilder: (context, index) {
          return ImageGridItem(imageItem: images[index]);
        },
      ),
    );
  }
}

class ImageGridItem extends StatelessWidget {
  final ImageItem imageItem;

  const ImageGridItem({
    super.key,
    required this.imageItem,
  });

  @override
  Widget build(BuildContext context) {
    return ImageBlurWeb(
      placeholder: AssetImage('assets/placeholder.jpg'),
      thumbnail: NetworkImage(imageItem.thumbnailUrl),
      image: NetworkImage(imageItem.imageUrl),
      width: double.infinity,
      height: double.infinity,
      fit: BoxFit.cover,
      blur: 20,
      fadeDuration: Duration(milliseconds: 500),
      borderRadius: BorderRadius.circular(12),
      boxShadow: [
        BoxShadow(
          color: Colors.black.withValues(alpha: 0.2),
          blurRadius: 8,
          offset: Offset(0, 4),
        ),
      ],
      backgroundColor: Colors.grey[900],
      enableHover: true,
      onTap: () => showFullScreenImage(context),
      errorWidget: (context, error) => Container(
        color: Colors.grey[800],
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(Icons.error_outline, color: Colors.red, size: 40),
            SizedBox(height: 8),
            Text(
              'Error loading image',
              style: TextStyle(color: Colors.white),
            ),
          ],
        ),
      ),
      loadingBuilder: (context, child, loadingProgress) {
        if (loadingProgress == null) return child;
        return Stack(
          children: [
            child,
            Positioned.fill(
              child: Container(
                color: Colors.black26,
                child: Center(
                  child: CircularProgressIndicator(
                    valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
                  ),
                ),
              ),
            ),
          ],
        );
      },
    );
  }

  void showFullScreenImage(BuildContext context) {
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => FullScreenImageView(imageItem: imageItem),
      ),
    );
  }
}

class FullScreenImageView extends StatelessWidget {
  final ImageItem imageItem;

  const FullScreenImageView({
    super.key,
    required this.imageItem,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0,
        title: Text(imageItem.title),
      ),
      body: Center(
        child: InteractiveViewer(
          minScale: 0.5,
          maxScale: 4.0,
          child: Hero(
            tag: imageItem.imageUrl,
            child: ImageBlurWeb(
              placeholder: NetworkImage(imageItem.thumbnailUrl),
              thumbnail: NetworkImage(imageItem.thumbnailUrl),
              image: NetworkImage(imageItem.imageUrl),
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height,
              fit: BoxFit.contain,
              blur: 20,
              enableHover: false,
              loadingBuilder: (context, child, loadingProgress) {
                if (loadingProgress == null) return child;
                return Stack(
                  children: [
                    child,
                    Center(
                      child: CircularProgressIndicator(
                        valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
                      ),
                    ),
                  ],
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

class ImageItem {
  final String thumbnailUrl;
  final String imageUrl;
  final String title;

  ImageItem({
    required this.thumbnailUrl,
    required this.imageUrl,
    required this.title,
  });
}
1
likes
160
points
121
downloads

Publisher

verified publisherswanflutterdev.com

Weekly Downloads

A Flutter widget for progressive image loading with blur-to-sharp transition effect. Supports placeholder, thumbnail preview, and smooth animated transitions optimized for web.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on image_blur_web