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

A Flutter package that makes any widget zoomable with pinch and pan gestures, just like zooming images in a gallery. Perfect for image viewers, charts, and interactive content.

example/lib/main.dart

// main.dart example for ZoomViewer package
import 'package:flutter/material.dart';
import 'package:zoom_viewer/zoom_viewer.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Zoomable Widget Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        useMaterial3: true,
      ),
      home: const ZoomableDemoPage(),
    );
  }
}

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

  @override
  State<ZoomableDemoPage> createState() => _ZoomableDemoPageState();
}

class _ZoomableDemoPageState extends State<ZoomableDemoPage> {
  double _currentScale = 1.0;
  int _selectedTab = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Zoomable Widget Demo'),
        centerTitle: true,
        elevation: 2,
      ),
      body: Column(
        children: [
          // Scale indicator
          Container(
            padding: const EdgeInsets.all(16),
            color: Colors.blue.shade50,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Icon(Icons.zoom_in, color: Colors.blue),
                const SizedBox(width: 8),
                Text(
                  'Zoom: ${_currentScale.toStringAsFixed(2)}x',
                  style: const TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                    color: Colors.blue,
                  ),
                ),
              ],
            ),
          ),

          // Tab selector
          Padding(
            padding: const EdgeInsets.all(16),
            child: SegmentedButton<int>(
              segments: const [
                ButtonSegment(
                    value: 0,
                    label: Text('Container'),
                    icon: Icon(Icons.crop_square)),
                ButtonSegment(
                    value: 1,
                    label: Text('Gradient'),
                    icon: Icon(Icons.gradient)),
                ButtonSegment(
                    value: 2,
                    label: Text('Complex'),
                    icon: Icon(Icons.widgets)),
              ],
              selected: {_selectedTab},
              onSelectionChanged: (Set<int> selection) {
                setState(() {
                  _selectedTab = selection.first;
                  _currentScale = 1.0;
                });
              },
            ),
          ),

          // Demo content
          Expanded(
            child: Center(
              child: _buildDemoContent(),
            ),
          ),

          // Instructions
          Container(
            padding: const EdgeInsets.all(16),
            color: Colors.grey.shade100,
            child: const Column(
              children: [
                Text(
                  '📌 Instructions:',
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
                ),
                SizedBox(height: 8),
                Text('• Pinch to zoom in/out'),
                Text('• Pan to move around when zoomed'),
                Text('• Double tap to toggle zoom'),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildDemoContent() {
    switch (_selectedTab) {
      case 0:
        return _buildSimpleContainer();
      case 1:
        return _buildGradientBox();
      case 2:
        return _buildComplexWidget();
      default:
        return _buildSimpleContainer();
    }
  }

  Widget _buildSimpleContainer() {
    return ZoomViewer(
      minScale: 0.5,
      maxScale: 4.0,
      backgroundColor: Colors.grey.shade200,
      onScaleChanged: (scale) {
        setState(() {
          _currentScale = scale;
        });
      },
      child: Container(
        width: 250,
        height: 250,
        decoration: BoxDecoration(
          color: Colors.blue,
          borderRadius: BorderRadius.circular(20),
          boxShadow: [
            BoxShadow(
              color: Colors.black.withOpacity(0.2),
              blurRadius: 10,
              offset: const Offset(0, 5),
            ),
          ],
        ),
        child: const Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Icon(Icons.touch_app, size: 50, color: Colors.white),
              SizedBox(height: 16),
              Text(
                'Pinch to Zoom!',
                textAlign: TextAlign.center,
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 24,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildGradientBox() {
    return ZoomViewer(
      minScale: 0.3,
      maxScale: 5.0,
      backgroundColor: Colors.black,
      onScaleChanged: (scale) {
        setState(() {
          _currentScale = scale;
        });
      },
      child: Container(
        width: 300,
        height: 300,
        decoration: BoxDecoration(
          gradient: const LinearGradient(
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
            colors: [
              Colors.purple,
              Colors.pink,
              Colors.orange,
              Colors.yellow,
            ],
          ),
          borderRadius: BorderRadius.circular(30),
        ),
        child: Center(
          child: Container(
            padding: const EdgeInsets.all(20),
            decoration: BoxDecoration(
              color: Colors.white.withOpacity(0.9),
              borderRadius: BorderRadius.circular(15),
            ),
            child: const Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(Icons.color_lens, size: 40, color: Colors.purple),
                SizedBox(height: 8),
                Text(
                  'Gradient Box',
                  style: TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                SizedBox(height: 4),
                Text(
                  'Zoom up to 5x!',
                  style: TextStyle(
                    fontSize: 14,
                    color: Colors.grey,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildComplexWidget() {
    return ZoomViewer(
      minScale: 0.5,
      maxScale: 3.0,
      backgroundColor: Colors.grey.shade300,
      onScaleChanged: (scale) {
        setState(() {
          _currentScale = scale;
        });
      },
      child: Container(
        width: 280,
        height: 400,
        padding: const EdgeInsets.all(20),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(20),
          boxShadow: [
            BoxShadow(
              color: Colors.black.withOpacity(0.3),
              blurRadius: 15,
              offset: const Offset(0, 8),
            ),
          ],
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Header
            Row(
              children: [
                Container(
                  width: 60,
                  height: 60,
                  decoration: BoxDecoration(
                    color: Colors.blue.shade100,
                    borderRadius: BorderRadius.circular(30),
                  ),
                  child: const Icon(Icons.person, size: 30, color: Colors.blue),
                ),
                const SizedBox(width: 12),
                const Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        'User Profile',
                        style: TextStyle(
                          fontSize: 18,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      Text(
                        'Zoom to see details',
                        style: TextStyle(
                          fontSize: 12,
                          color: Colors.grey,
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),

            const SizedBox(height: 20),
            const Divider(),
            const SizedBox(height: 20),

            // Content
            _buildInfoRow(Icons.email, 'Email', 'user@example.com'),
            const SizedBox(height: 16),
            _buildInfoRow(Icons.phone, 'Phone', '+998 90 123 45 67'),
            const SizedBox(height: 16),
            _buildInfoRow(
                Icons.location_on, 'Location', 'Tashkent, Uzbekistan'),

            const Spacer(),

            // Button
            SizedBox(
              width: double.infinity,
              child: ElevatedButton(
                onPressed: () {},
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  padding: const EdgeInsets.symmetric(vertical: 16),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(12),
                  ),
                ),
                child: const Text('View Full Profile'),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildInfoRow(IconData icon, String label, String value) {
    return Row(
      children: [
        Container(
          padding: const EdgeInsets.all(8),
          decoration: BoxDecoration(
            color: Colors.blue.shade50,
            borderRadius: BorderRadius.circular(8),
          ),
          child: Icon(icon, size: 20, color: Colors.blue),
        ),
        const SizedBox(width: 12),
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                label,
                style: const TextStyle(
                  fontSize: 12,
                  color: Colors.grey,
                ),
              ),
              Text(
                value,
                style: const TextStyle(
                  fontSize: 14,
                  fontWeight: FontWeight.w500,
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }
}
3
likes
150
points
167
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter package that makes any widget zoomable with pinch and pan gestures, just like zooming images in a gallery. Perfect for image viewers, charts, and interactive content.

Repository (GitHub)
View/report issues

Topics

#zoom #widget #pinch #gesture #image-viewer

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on zoom_viewer