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="" Label="Zoomable" Color="Color.Primary" /> <MudSwitch T="bool?" Class="mb-2" @bind-Value="" Label="Zoom On Touch" Color="Color.Primary" /> <MudSwitch T="bool?" Class="mb-2" @bind-Value="" 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(
method, where ratio
)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(
method, where ratio, pivotX, pivotY
)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.
@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>