Pan & Zoom plugin screenshot
Dark mode ready
Multilingual support
Supports v5.x

Pan & Zoom

An interactive image zoom and pan component for Filament. This package provides a beautiful, responsive image viewer with smooth zoom and pan functionality, perfect for viewing receipts, documents, or any images that require detailed inspection.

Tags: Forms Form Field Tables
Supported versions:
4.x 3.x
Solution Forest avatar Author: Solution Forest

Documentation

filament-panzoom

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

An interactive image zoom and pan component for Filament PHP. This package provides a beautiful, responsive image viewer with smooth zoom and pan functionality, perfect for viewing receipts, documents, or any images that require detailed inspection.

Features:

  • 🔍 Mouse wheel zooming
  • 🖱️ Click and drag panning
  • 🖱️ Double-click zoom to position (configurable level)
  • 📱 Touch support for mobile devices
  • ⚡ Smooth transitions and animations
  • 🎯 Zoom in/out buttons
  • 🔄 Reset view functionality
  • 📊 Real-time zoom percentage display
  • 🎨 Modern, clean UI design

#Requirements

  • PHP 8.3+
  • Laravel 10.0+
  • Filament 3.3+ or 4.0+

#Installation

You can install the package via composer:

composer require solution-forest/filament-panzoom

#Register the Plugin

Add the plugin to your Filament Panel Provider (e.g., app/Providers/Filament/AdminPanelProvider.php):

use SolutionForest\FilamentPanzoom\FilamentPanzoomPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->default()
        ->id('admin')
        ->path('admin')
        // ... other configuration
        ->plugins([
            FilamentPanzoomPlugin::make(),
            // ... other plugins
        ]);
}

#Optional: Publish Assets

Optionally, you can publish the views for customization:

php artisan vendor:publish --tag="filament-panzoom-views"

You can also publish the config file:

php artisan vendor:publish --tag="filament-panzoom-config"

#Usage

#Filament Version Compatibility

This package supports both Filament 3.0+ and Filament 4.0+ with automatic compatibility detection.

#Filament 3.0+ (Legacy)

// Forms, Actions & Tables
use SolutionForest\FilamentPanzoom\Components\PanZoom;

public static function form(Form $form): Form
{
    return $form->schema([
        PanZoom::make('image_preview')
            ->imageUrl(fn ($record) => $record?->image_url)
            ->label('Image Preview')
            ->columnSpanFull(),
    ]);
}

// Infolists
use SolutionForest\FilamentPanzoom\Infolists\Components\PanZoomEntry;

public function infolist(Infolist $infolist): Infolist
{
    return $infolist->schema([
        PanZoomEntry::make('image_preview')
            ->imageUrl(fn ($record) => $record?->image_url)
            ->label('Image Preview'),
    ]);
}

#Filament 4.0+ (Current)

// Forms - Uses Schemas
use SolutionForest\FilamentPanzoom\Components\PanZoom;

public static function configure(Schema $schema): Schema
{
    return $schema->components([
        PanZoom::make('image_preview')
            ->imageUrl(fn ($record) => $record?->image_url),
        // Note: label() and columnSpanFull() methods not available in 4.0+
    ]);
}

// Infolists - Uses Schemas
use SolutionForest\FilamentPanzoom\Infolists\Components\PanZoomEntry;

public static function configure(Schema $schema): Schema
{
    return $schema->components([
        PanZoomEntry::make('image_preview')
            ->imageUrl(fn ($record) => $record?->image_url),
    ]);
}

#Configurable Double-Click Zoom

You can customize the double-click zoom level for each component. Double-clicking again will return the image to the original fit-to-container view:

// Filament 3.0+ Forms
PanZoom::make('image_preview')
    ->imageUrl(fn ($record) => $record?->image_url)
    ->doubleClickZoomLevel(2.5)  // Zoom to 2.5x instead of default 3x
    ->label('Image Preview');

// Filament 4.0+ Forms
PanZoom::make('image_preview')
    ->imageUrl(fn ($record) => $record?->image_url)
    ->doubleClickZoomLevel(4.0)  // Zoom to 4x for more detail
    ->columnSpanFull();

// Infolists (both 3.0+ and 4.0+)
PanZoomEntry::make('image_preview')
    ->imageUrl(fn ($record) => $record?->image_url)
    ->doubleClickZoomLevel(2.0)  // Zoom to 2x
    ->imageId(fn ($record) => 'image-' . $record->id);

Available Zoom Levels:

  • Range: 0.5x to 5.0x
  • Default: 3.0x (good balance for detail viewing)
  • Common values:
    • 2.0 - Moderate zoom
    • 2.5 - Balanced zoom
    • 3.0 - Default (detailed view)
    • 4.0 - High zoom
    • 5.0 - Maximum zoom

#In Blade Views

You can use the component directly in any Blade view (works in both 3.0+ and 4.0+):

@include('filament-panzoom::filament-panzoom', [
    'imageUrl' => 'https://example.com/image.jpg',
    'imageId' => 'unique-image-id',
    'doubleClickZoomLevel' => 2.5  // Custom zoom level (double-click again to return to fit)
])

#Component Selection Guide

⚠️ Important: Choose the correct component for your context!

Context Component Import
Forms (3.0+) PanZoom use SolutionForest\FilamentPanzoom\Components\PanZoom;
Forms (4.0+) PanZoom use SolutionForest\FilamentPanzoom\Components\PanZoom;
Actions PanZoom use SolutionForest\FilamentPanzoom\Components\PanZoom;
Tables PanZoom use SolutionForest\FilamentPanzoom\Components\PanZoom;
Infolists (3.0+) PanZoomEntry use SolutionForest\FilamentPanzoom\Infolists\Components\PanZoomEntry;
Infolists (4.0+) PanZoomEntry use SolutionForest\FilamentPanzoom\Infolists\Components\PanZoomEntry;

Why two components? Filament has separate component hierarchies for Forms and Infolists. Using the wrong one will cause a TypeError.

#Key Differences: Filament 3.0+ vs 4.0+

Feature Filament 3.0+ Filament 4.0+
Forms Structure form(Form $form): Form configure(Schema $schema): Schema
Infolists Structure infolist(Infolist $infolist): Infolist configure(Schema $schema): Schema
Available Methods label(), columnSpanFull(), etc. Limited methods (Schemas-based)
Component Base Filament\Forms\Components\Component Filament\Schemas\Components\Component
Auto-detection ✅ Yes ✅ Yes

#Usage Examples

#Filament 3.0+ Examples

In Forms:

public static function form(Form $form): Form
{
    return $form->schema([
        PanZoom::make('image_preview')
            ->imageUrl(fn ($record) => $record?->image_url)
            ->label('Image Preview')
            ->columnSpanFull(),
    ]);
}

In Infolists:

use SolutionForest\FilamentPanzoom\Infolists\Components\PanZoomEntry;

public function infolist(Infolist $infolist): Infolist
{
    return $infolist->schema([
        PanZoomEntry::make('receipt_image')
            ->imageUrl(fn ($record) => asset('storage/' . $record->image_path))
            ->label('Receipt Image')
            ->imageId(fn ($record) => 'receipt-' . $record->id),
    ]);
}

In Table Actions:

public static function table(Table $table): Table
{
    return $table->actions([
        Action::make('viewImage')
            ->form([
                PanZoom::make('image_viewer')
                    ->imageUrl(fn ($record) => $record->image_url)
                    ->label('Image Viewer'),
            ])
    ]);
}

In Custom Pages:

protected function getFormSchema(): array
{
    return [
        PanZoom::make('document_viewer')
            ->imageUrl($this->imageUrl)
            ->label('Document Viewer')
            ->columnSpanFull(),
    ];
}

#Filament 4.0+ Examples

In Forms (Schemas):

public static function configure(Schema $schema): Schema
{
    return $schema->components([
        PanZoom::make('image_preview')
            ->imageUrl(fn ($record) => $record?->image_url),
        // Note: label() and columnSpanFull() methods not available in 4.0+
    ]);
}

In Infolists (Schemas):

use SolutionForest\FilamentPanzoom\Infolists\Components\PanZoomEntry;

public static function configure(Schema $schema): Schema
{
    return $schema->components([
        PanZoomEntry::make('receipt_image')
            ->imageUrl(fn ($record) => asset('storage/' . $record->image_path))
            ->imageId(fn ($record) => 'receipt-' . $record->id),
    ]);
}

In Table Actions:

public static function table(Table $table): Table
{
    return $table->actions([
        Action::make('viewImage')
            ->form([
                PanZoom::make('image_viewer')
                    ->imageUrl(fn ($record) => $record->image_url),
            ])
    ]);
}

In Custom Pages:

protected function getFormSchema(): array
{
    return [
        PanZoom::make('document_viewer')
            ->imageUrl($this->imageUrl),
        // Note: columnSpanFull() method not available in 4.0+
    ];
}

#Component Properties

The component accepts the following properties:

Property Type Required Description
imageUrl string Yes The URL of the image to display
imageId string Yes Unique identifier for the component instance
doubleClickZoomLevel float No Zoom level for double-click (0.5-5.0, default: 3.0)

#Quick Tips

💡 Pro Tip: Double-click anywhere on the image to zoom to that exact position (configurable, default 3x). Double-click again to return to fit.

#Features

#Zoom Controls

  • Mouse Wheel: Scroll to zoom in/out
  • Double-Click: Double-click to zoom to exact position (configurable level, default: 3x). Double-click again to return to fit.
  • Zoom Buttons: Click the + and - buttons in the control panel
  • Zoom Range: 0.5x to 5x magnification

#Pan Controls

  • Mouse Drag: Click and drag to pan around the image
  • Touch Support: Touch and drag on mobile devices

#Reset View

  • Reset Button: Click the reset button to return to the original view
  • Auto-fit: Images are automatically fitted to the container on load

#Visual Feedback

  • Zoom Percentage: Real-time zoom level display
  • Cursor States: Visual feedback for grabbable/grabbing states
  • Smooth Transitions: Animated zoom and pan movements

#Styling

The component uses Tailwind CSS classes and is designed to work seamlessly with Filament's design system. The component is fully responsive and includes:

  • Modern, clean interface
  • Smooth hover effects
  • Mobile-friendly touch controls
  • Consistent with Filament's design patterns

#Troubleshooting

#Common Issues

TypeError: Argument #1 ($component) must be of type Filament\Infolists\Components\Component

  • ❌ You're using PanZoom in an Infolist
  • ✅ Use PanZoomEntry for Infolists instead

TypeError: Argument #1 ($component) must be of type Filament\Forms\Components\Component

  • ❌ You're using PanZoomEntry in a Form/Action
  • ✅ Use PanZoom for Forms/Actions instead

Fatal Error: Class was composed with trait conflicts

  • ✅ Fixed in v1.2.1+ - update your package

Method not found: label() or columnSpanFull() in Filament 4.0+

  • ❌ These methods aren't available in Filament 4.0+ Schemas
  • ✅ Remove these method calls or use Filament 3.0+ syntax

Undefined type 'Filament\Schemas\Components\Component'

  • ❌ Linter error in Filament 3.0+ environment
  • ✅ This is expected - the package uses runtime detection for compatibility

#Version-Specific Issues

#Filament 3.0+

  • ✅ All methods available (label(), columnSpanFull(), etc.)
  • ✅ Traditional Forms/Infolists structure

#Filament 4.0+

  • ⚠️ Limited methods available (Schemas-based)
  • ⚠️ Different structure (configure(Schema $schema))
  • ✅ Automatic compatibility detection

#Quick Reference

Context Component Import
Forms (3.0+) PanZoom use SolutionForest\FilamentPanzoom\Components\PanZoom;
Forms (4.0+) PanZoom use SolutionForest\FilamentPanzoom\Components\PanZoom;
Actions PanZoom use SolutionForest\FilamentPanzoom\Components\PanZoom;
Tables PanZoom use SolutionForest\FilamentPanzoom\Components\PanZoom;
Infolists (3.0+) PanZoomEntry use SolutionForest\FilamentPanzoom\Infolists\Components\PanZoomEntry;
Infolists (4.0+) PanZoomEntry use SolutionForest\FilamentPanzoom\Infolists\Components\PanZoomEntry;

#Browser Support

  • Chrome 70+
  • Firefox 65+
  • Safari 12+
  • Edge 79+

#Testing

composer test

#Changelog

Please see CHANGELOG for more information on what has changed recently.

#Contributing

Please see CONTRIBUTING for details.

#Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

#Credits

#License

The MIT License (MIT). Please see License File for more information.