Zoom the image

Enable to zoom the image.

Q&A

How to crop a new area after zooming in or zooming out?

Just double-click your mouse to enter crop mode.

Zoomable

You can use Zoomable boolean field in the Options property to enable/disable to zoom the image.

You can use ZoomOnTouch boolean field in the Options property to enable/disable to zoom the image by dragging touch.

Boolean field ZoomOnWheel used to enable/disable zoom the image by mouse wheeling.

@using Cropper.Blazor.Models

<MudGrid>
    <MudItem xs="12" sm="9" md="9" lg="9">
        <MudPaper Class="pa-2">
            <div class="img-container">
                <CropperComponent Class="big-img" @ref="cropperComponent"
                                  Src="images/Rivne2.jpg" Options="cropperOptions" />
            </div>
        </MudPaper>
    </MudItem>
    <MudItem xs="12" sm="3" md="3" lg="3">
        <MudPaper Class="pa-2">
            <MudSwitch T="bool?" Class="mb-2" @bind-Value="@Zoomable" Label="Zoomable" Color="Color.Primary" />
            <MudSwitch T="bool?" Class="mb-2" @bind-Value="@ZoomOnTouch" Label="Zoom On Touch" Color="Color.Primary" />
            <MudSwitch T="bool?" Class="mb-2" @bind-Value="@ZoomOnWheel" Label="Zoom On Wheel" Color="Color.Primary" />
        </MudPaper>
    </MudItem>
</MudGrid>
@code {
    private CropperComponent? cropperComponent = null!;

    // Setting up initial dimensions of crop area
    private Options cropperOptions = new Options
    {
        AspectRatio = 1m,
        ViewMode = ViewMode.Vm3
    };

    private void ReloadCropper()
    {
        cropperComponent?.Destroy();
        cropperComponent?.InitCropper();
    }

    private bool? Zoomable
    {
        get => cropperOptions.Zoomable ?? true;
        set
        {
            cropperOptions.Zoomable = value;
            ReloadCropper();
        }
    }

    private bool? ZoomOnTouch
    {
        get => cropperOptions.ZoomOnTouch ?? true;
        set
        {
            cropperOptions.ZoomOnTouch = value;
            ReloadCropper();
        }
    }

    private bool? ZoomOnWheel
    {
        get => cropperOptions.ZoomOnWheel ?? true;
        set
        {
            cropperOptions.ZoomOnWheel = value;
            ReloadCropper();
        }
    }
}

<style>
    .big-img {
        max-height: 400px;
        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        max-width: 100%;
    }
</style>
Wheel Zoom Ratio

Use decimal field WheelZoomRatio in the Options cropper component property to define zoom ratio when zooming the image by mouse wheeling.

By default, WheelZoomRatio is 0,1.

@using Cropper.Blazor.Models;
@using Cropper.Blazor.Events;
@using Cropper.Blazor.Events.ZoomEvent;

<MudGrid>
    <MudItem xs="12" sm="8" md="8" lg="8">
        <MudPaper Class="pa-2">
            <div class="img-container">
                <CropperComponent Class="big-img" @ref="cropperComponent" Src="images/Odesa.jpg"
                                  Options="cropperOptions" OnZoomEvent="OnZoomEvent" />
            </div>
        </MudPaper>
    </MudItem>
    <MudItem xs="12" sm="4" md="4" lg="4">
        <MudPaper Class="pa-2">
            <MudNumericField Class="mb-2" @bind-Value="WheelZoomRatio" Label="Wheel Zoom Ratio"
                             Format="N4" Variant="Variant.Text" Step=".05M" Min="0" />
            <MudNumericField Class="mb-2" @bind-Value="OldRatio" Label="Old Ratio" Format="N4"
                             Variant="Variant.Text" HideSpinButtons="true" ReadOnly="true" />
            <MudNumericField Class="mb-2" @bind-Value="CurrentRatio" Label="Current Ratio" Format="N4"
                             Variant="Variant.Text" HideSpinButtons="true" ReadOnly="true" />
        </MudPaper>
    </MudItem>
</MudGrid>
@code {
    private CropperComponent? cropperComponent = null!;

    // Setting up initial dimensions of crop area
    private Options cropperOptions = new Options
    {
        AspectRatio = 1m,
        WheelZoomRatio = 0.1m,
        ViewMode = ViewMode.Vm3
    };

    private decimal? OldRatio { get; set; }

    private decimal? CurrentRatio { get; set; }

    private decimal? WheelZoomRatio
    {
        get => cropperOptions.WheelZoomRatio;
        set
        {
            cropperOptions.WheelZoomRatio = value;
            cropperComponent?.Destroy();
            cropperComponent?.InitCropper();
        }
    }

    public async void OnZoomEvent(JSEventData<ZoomEvent> zoomJSEvent)
    {
        await InvokeAsync(() =>
        {
            if (zoomJSEvent.Detail is not null)
            {
                OldRatio = zoomJSEvent.Detail.OldRatio;
                CurrentRatio = zoomJSEvent.Detail.Ratio;
                StateHasChanged();
            }
        });
    }
}

<style>
    .big-img {
        max-height: 400px;
        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        max-width: 100%;
    }
</style>
Relative Zoom

For zoom the canvas (image wrapper) with a relative ratio use Zoom(ratio) method, where ratio parameter is decimal number.

Zoom in: requires a positive number (ratio > 0)

Zoom out: requires a negative number (ratio < 0)

@using Cropper.Blazor.Models;
@using Cropper.Blazor.Events;
@using Cropper.Blazor.Events.ZoomEvent;
@using Cropper.Blazor.Events.CropReadyEvent;

<MudGrid>
    <MudItem xs="12" sm="8" md="8" lg="8">
        <MudPaper Class="pa-2">
            <div class="img-container">
                <CropperComponent Class="big-img" @ref="cropperComponent" Src="images/Rivne.jpg"
                                  Options="cropperOptions" OnZoomEvent="OnZoomEvent" OnReadyEvent="OnCropReadyEvent" />
            </div>
        </MudPaper>
    </MudItem>
    <MudItem xs="12" sm="4" md="4" lg="4">
        <MudPaper Class="pa-2">
            <MudNumericField Class="mb-2" @bind-Value="ZoomRatio" Label="Zoom Ratio"
                             Format="N4" Variant="Variant.Text" Step=".1M" />

            <MudNumericField Class="mb-2" @bind-Value="OldRatio" Label="Old Ratio" Format="N4"
                             Variant="Variant.Text" HideSpinButtons="true" ReadOnly="true" />
            <MudNumericField Class="mb-2" @bind-Value="CurrentRatio" Label="Current Ratio" Format="N4"
                             Variant="Variant.Text" HideSpinButtons="true" ReadOnly="true" />
        </MudPaper>
    </MudItem>
</MudGrid>
@code {
    private CropperComponent? cropperComponent = null!;

    // Setting up initial dimensions of crop area
    private Options cropperOptions = new Options
    {
        AspectRatio = 1m,
        ViewMode = ViewMode.Vm3
    };

    decimal _zoomRatio;

    public async void OnCropReadyEvent(JSEventData<CropReadyEvent> jSEventData)
    {
        await InvokeAsync(async () =>
        {
            ImageData imageData = await cropperComponent!.GetImageDataAsync();
            decimal initZoomRatio = imageData.Width / imageData.NaturalWidth;

            _zoomRatio = initZoomRatio;
            StateHasChanged();
        });
    }

    private decimal ZoomRatio
    {
        get => _zoomRatio;
        set
        {
            _zoomRatio = value;
            cropperComponent?.Zoom(value);
        }
    }

    private decimal? OldRatio { get; set; }

    private decimal? CurrentRatio { get; set; }

    public async void OnZoomEvent(JSEventData<ZoomEvent> zoomJSEvent)
    {
        await InvokeAsync(() =>
        {
            if (zoomJSEvent.Detail is not null)
            {
                OldRatio = zoomJSEvent.Detail.OldRatio;
                CurrentRatio = zoomJSEvent.Detail.Ratio;
                StateHasChanged();
            }
        });
    }
}

<style>
    .big-img {
        max-height: 400px;
        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        max-width: 100%;
    }
</style>
Absolute Zoom

For zoom the canvas (image wrapper) with a relative ratio use ZoomTo(ratio, pivotX, pivotY) method, where ratio parameter is positive (ratio > 0) decimal number. pivotX and pivotY parameters is the decimal coordinates of the center point for zooming, base on the top left corner of the cropper container.

In the example, іmage zoomed to 50% from the center of the container.

@using Cropper.Blazor.Models;
@using Cropper.Blazor.Events;
@using Cropper.Blazor.Events.ZoomEvent;
@using Cropper.Blazor.Events.CropReadyEvent;

<MudGrid>
    <MudItem xs="12" sm="8" md="8" lg="8">
        <MudPaper Class="pa-2">
            <div class="img-container">
                <CropperComponent Class="big-img" @ref="cropperComponent" Src="images/dolphin.jpg"
                                  Options="cropperOptions" OnZoomEvent="OnZoomEvent" OnReadyEvent="OnCropReadyEvent" />
            </div>
        </MudPaper>
    </MudItem>
    <MudItem xs="12" sm="4" md="4" lg="4">
        <MudPaper Class="pa-2">
            <MudNumericField Class="mb-2" @bind-Value="ZoomRatio" Label="Zoom Ratio"
                             Format="N4" Variant="Variant.Text" Step=".1M" Min="0" />
            <MudNumericField Class="mb-2" @bind-Value="PivotX" Label="PivotX"
                             Format="N4" Variant="Variant.Text" Step=".1M" />
            <MudNumericField Class="mb-2" @bind-Value="PivotY" Label="PivotY"
                             Format="N4" Variant="Variant.Text" Step=".1M" />

            <MudNumericField Class="mb-2" @bind-Value="OldRatio" Label="Old Ratio" Format="N4"
                             Variant="Variant.Text" HideSpinButtons="true" ReadOnly="true" />
            <MudNumericField Class="mb-2" @bind-Value="CurrentRatio" Label="Current Ratio" Format="N4"
                             Variant="Variant.Text" HideSpinButtons="true" ReadOnly="true" />
        </MudPaper>
    </MudItem>
</MudGrid>
@code {
    private CropperComponent? cropperComponent = null!;

    // Setting up initial dimensions of crop area
    private Options cropperOptions = new Options
    {
        AspectRatio = 1m,
        ViewMode = ViewMode.Vm0
    };

    decimal _zoomRatio;
    decimal _pivotX;
    decimal _pivotY;

    public async void OnCropReadyEvent(JSEventData<CropReadyEvent> jSEventData)
    {
        await InvokeAsync(async () =>
        {
            ImageData imageData = await cropperComponent!.GetImageDataAsync();
            decimal initZoomRatio = imageData.Width / imageData.NaturalWidth;
            OldRatio = initZoomRatio;

            ContainerData containerData = await cropperComponent!.GetContainerDataAsync();
            // Zoom to 50% from the center of the container.
            PivotX = containerData.Width / 2;
            PivotY = containerData.Height / 2;
            ZoomRatio = 0.5m;
            StateHasChanged();
        });
    }

    private decimal ZoomRatio
    {
        get => _zoomRatio;
        set
        {
            _zoomRatio = value;
            cropperComponent?.ZoomTo(value, PivotX, PivotY);
        }
    }

    private decimal PivotX
    {
        get => _pivotX;
        set
        {
            _pivotX = value;
            cropperComponent?.ZoomTo(ZoomRatio, value, PivotY);
        }
    }


    private decimal PivotY
    {
        get => _pivotY;
        set
        {
            _pivotY = value;
            cropperComponent?.ZoomTo(ZoomRatio, PivotX, value);
        }
    }

    private decimal? OldRatio { get; set; }

    private decimal? CurrentRatio { get; set; }

    public async void OnZoomEvent(JSEventData<ZoomEvent> zoomJSEvent)
    {
        await InvokeAsync(() =>
        {
            if (zoomJSEvent.Detail is not null)
            {
                OldRatio = zoomJSEvent.Detail.OldRatio;
                CurrentRatio = zoomJSEvent.Detail.Ratio;
                StateHasChanged();
            }
        });
    }
}

<style>
    .big-img {
        max-height: 400px;
        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        max-width: 100%;
    }
</style>
Min & Max Zoom Ratio

You can override the OnZoomEvent to establish minimum and/or maximum ratio limits for zooming the canvas by preventing the default logic.
To override the OnZoomEvent event, you need to use JavaScript, in which you assign a new function to the window.cropper.onZoom event. An example of an event override is shown below.

Make sure that the current Zoom Ratio value is less than the minimum value, otherwise this setting may not work correctly.

@using Cropper.Blazor.Models;
@using Cropper.Blazor.Events;
@using Cropper.Blazor.Events.ZoomEvent;
@using Cropper.Blazor.Events.CropReadyEvent;

<MudGrid>
    <MudItem xs="12" sm="8" md="8" lg="8">
        <MudPaper Class="pa-2">
            <div class="img-container">
                <CropperComponent Class="big-img" @ref="cropperComponent" Src="images/dolphin.jpg"
                                  Options="cropperOptions" OnZoomEvent="OnZoomEvent" OnReadyEvent="OnCropReadyEvent" />
            </div>
        </MudPaper>
    </MudItem>
    <MudItem xs="12" sm="4" md="4" lg="4">
        <MudPaper Class="pa-2">
            <MudNumericField Class="mb-2" @bind-Value="MinZoomRatio" Label="Min zoom ratio"
                             Min="0" Max="MaxZoomRatio" Variant="Variant.Text" Step=".1M">
            </MudNumericField>
            <MudNumericField Class="mb-2" @bind-Value="MaxZoomRatio" Label="Max zoom ratio"
                             Min="MinZoomRatio ?? 0" Variant="Variant.Text" Step=".1M">
            </MudNumericField>

            <MudNumericField Class="mb-2" @bind-Value="OldRatio" Label="Old Ratio" Format="N4"
                             Variant="Variant.Text" HideSpinButtons="true" ReadOnly="true" />
            <MudNumericField Class="mb-2" @bind-Value="CurrentRatio" Label="Current Ratio" Format="N4"
                             Variant="Variant.Text" HideSpinButtons="true" ReadOnly="true" />
        </MudPaper>
    </MudItem>
</MudGrid>
@code {
    [Inject] private IJSRuntime? JSRuntime { get; set; }

    private CropperComponent? cropperComponent = null!;

    // Setting up initial dimensions of crop area
    private Options cropperOptions = new Options
    {
        AspectRatio = 1m,
        ViewMode = ViewMode.Vm3
    };

    private decimal? minZoomRatio = null;
    private decimal? maxZoomRatio = null;

    private decimal? MinZoomRatio
    {
        get => minZoomRatio;
        set
        {
            minZoomRatio = value;
            InvokeAsync(ApplyZoomRulesForCropperAsync);
        }
    }
    private decimal? MaxZoomRatio
    {
        get => maxZoomRatio;
        set
        {
            maxZoomRatio = value;
            InvokeAsync(ApplyZoomRulesForCropperAsync);
        }
    }

    private decimal? OldRatio { get; set; }

    private decimal? CurrentRatio { get; set; }

    public async void OnZoomEvent(JSEventData<ZoomEvent> zoomJSEvent)
    {
        await InvokeAsync(() =>
        {
            if (zoomJSEvent.Detail is not null)
            {
                OldRatio = zoomJSEvent.Detail.OldRatio;
                CurrentRatio = zoomJSEvent.Detail.Ratio;
                StateHasChanged();
            }
        });
    }

    public async void OnCropReadyEvent(JSEventData<CropReadyEvent> jSEventData)
    {
        await InvokeAsync(async () =>
        {
            ImageData imageData = await cropperComponent!.GetImageDataAsync();
            decimal initZoomRatio = imageData.Width / imageData.NaturalWidth;
            CurrentRatio = initZoomRatio;
            StateHasChanged();
        });
    }

    public async Task ApplyZoomRulesForCropperAsync()
    {
        ImageData currentImageData = await cropperComponent!.GetImageDataAsync();
        ContainerData containerData = await cropperComponent.GetContainerDataAsync();
        decimal currentZoomRatio = currentImageData.Width / currentImageData.NaturalWidth;

        if ((MinZoomRatio is not null) && (MinZoomRatio > currentZoomRatio))
        {
            cropperComponent.ZoomTo((decimal)MinZoomRatio, containerData.Width / 2, containerData.Height / 2);
        }
        else if ((MaxZoomRatio is not null) && (currentZoomRatio > MaxZoomRatio))
        {
            cropperComponent.ZoomTo((decimal)MaxZoomRatio, containerData.Width / 2, containerData.Height / 2);
        }

        await JSRuntime!.InvokeVoidAsync("window.overrideOnZoomCropperEvent", MinZoomRatio, MaxZoomRatio);
    }
}

<style>
    .big-img {
        max-height: 400px;
        /* This rule is very important, please don't ignore this */
        max-width: 100%;
    }

    .img-container {
        max-height: 400px;
        max-width: 100%;
    }
</style>
An unhandled error has occurred. Reload 🗙