Skip to content

Commit

Permalink
fix issue with set up Src in cropper component when call replace imag…
Browse files Browse the repository at this point in the history
…e function; add replace examples
  • Loading branch information
MaxymGorn committed Nov 14, 2023
1 parent 55348ed commit 9fcb6e0
Show file tree
Hide file tree
Showing 15 changed files with 383 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/Cropper.Blazor/Client/Pages/CropperDemo.razor
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@
<MudIconButton Icon="@Icons.Material.Filled.Sync" OnClick="Reset" Title="Reset" />
</MudTooltip>
<MudTooltip Text="Import image with Blob URLs">
<InputFile id="imageInput" OnChange="InputFileChangeAsync" accept="image/*" hidden multiple />
<InputFile id="imageInput" OnChange="InputFileChangeAsync" accept="image/*" hidden />
<MudIconButton HtmlTag="label" Icon="@Icons.Material.Filled.PhotoCamera" for="imageInput" Title="Upload image file" />
</MudTooltip>
<MudTooltip Text="Replace image with Blob URLs">
<InputFile id="imageReplaceInput" OnChange="ReplaceImageAsync" accept="image/*" hidden multiple />
<InputFile id="imageReplaceInput" OnChange="ReplaceImageAsync" accept="image/*" hidden />
<MudIconButton HtmlTag="label" Icon="@Icons.Material.Filled.FindReplace" for="imageReplaceInput" Title="Replace image file" />
</MudTooltip>
<MudTooltip Text="cropper.destroy()">
Expand Down
11 changes: 8 additions & 3 deletions src/Cropper.Blazor/Client/Pages/CropperDemo.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ public async Task ReplaceImageAsync(InputFileChangeEventArgs inputFileChangeEven
if (imageFile != null)
{
string oldSrc = Src;
string src = await CropperComponent!.GetImageUsingStreamingAsync(imageFile, imageFile.Size);
string newSrc = await CropperComponent!.GetImageUsingStreamingAsync(imageFile, imageFile.Size);

if (IsErrorLoadImage)
{
Expand All @@ -420,8 +420,13 @@ public async Task ReplaceImageAsync(InputFileChangeEventArgs inputFileChangeEven
IsAvailableInitCropper = false;
}

CropperComponent?.ReplaceAsync(src);
CropperComponent?.RevokeObjectUrlAsync(oldSrc);
await Task.WhenAll(
CropperComponent?.ReplaceAsync(newSrc, false).AsTask(),
CropperComponent?.RevokeObjectUrlAsync(oldSrc).AsTask())
.ContinueWith(x =>
{
Src = newSrc;
});
}
}

Expand Down
41 changes: 41 additions & 0 deletions src/Cropper.Blazor/Client/Pages/Replace/CropperReplacePage.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@page "/examples/replacing"
@using Cropper.Blazor.Client.Models;
@using Cropper.Blazor.Client.Pages.Replace.Examples

<DocsPage>
<DocsPageHeader Title="Replace image" SubTitle="Replace the image's src and rebuild the cropper." />
<DocsPageContent>

<DocsPageSection>
<SectionHeader Title="Simple Usage">
<Description>
With the <CodeInline Class="docs-code-warning">ReplaceAsync</CodeInline> method
you can replace the image's src and rebuild the cropper.
<br><br>
<CodeInline Class="docs-code-warning">GetCroppedCanvasDataURLAsync</CodeInline> method have following arguments:
<MudList>
<MudListItem Icon="@Icons.Material.Filled.Circle" IconSize="Size.Small" IconColor="Color.Primary">
<CodeInline>url (required)</CodeInline> - used to set a new URL;
</MudListItem>
<MudListItem Icon="@Icons.Material.Filled.Circle" IconSize="Size.Small" IconColor="Color.Secondary">
<CodeInline>hasSameSize (not required, default - true)</CodeInline> - If the new image has the same size as the old one, then it will not rebuild the cropper and only update the URLs of all related images. This can be used for applying filters;
</MudListItem>
<MudListItem Icon="@Icons.Material.Filled.Circle" IconSize="Size.Small" IconColor="Color.Secondary">
<CodeInline><MudLink UserAttributes="@(new Dictionary<string, object>(){ {"rel", "noopener"} })" Target="_blank" Href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource">CancellationToken</MudLink> (not required)</CodeInline> - used to propagate notifications that the operation should be canceled.
</MudListItem>
</MudList>
<br>
</Description>
</SectionHeader>
<SectionContent @ref="ActiveReplaceActive" ChildContent="ReplaceActiveRenderFragment" Codes="@(
new CodeFile[]
{
new CodeFile("Basic replace image with the same size", "BasicReplaceImageWithSameSizeExample"),
new CodeFile("Basic replace image with the new size", "BasicReplaceImageWithNewSizeExample"),
new CodeFile("Using input file replace image with the same size", "BasicInputReplaceImageWithSameSizeExample"),
new CodeFile("Using input file replace image with the new size", "BasicInputReplaceImageWithNewSizeExample")
})" />
</DocsPageSection>

</DocsPageContent>
</DocsPage>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Cropper.Blazor.Client.Components.Docs;
using Cropper.Blazor.Client.Pages.Replace.Examples;
using Microsoft.AspNetCore.Components;

namespace Cropper.Blazor.Client.Pages.Replace
{
public partial class CropperReplacePage
{
SectionContent ActiveReplaceActive = null!;

RenderFragment ReplaceActiveRenderFragment => builder =>
{
if (ActiveReplaceActive.ActiveCode == nameof(BasicReplaceImageWithNewSizeExample))
{
builder.OpenComponent<BasicReplaceImageWithNewSizeExample>(1);
builder.CloseComponent();
}
else if (ActiveReplaceActive.ActiveCode == nameof(BasicReplaceImageWithSameSizeExample))
{
builder.OpenComponent<BasicReplaceImageWithSameSizeExample>(1);
builder.CloseComponent();
}
else if (ActiveReplaceActive.ActiveCode == nameof(BasicInputReplaceImageWithNewSizeExample))
{
builder.OpenComponent<BasicInputReplaceImageWithNewSizeExample>(1);
builder.CloseComponent();
}
else if (ActiveReplaceActive.ActiveCode == nameof(BasicInputReplaceImageWithSameSizeExample))
{
builder.OpenComponent<BasicInputReplaceImageWithSameSizeExample>(1);
builder.CloseComponent();
}
else
{
throw new InvalidOperationException();
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<div class="img-container">
<CropperComponent Class="big-img"
Src="@src"
ErrorLoadImageSrc="@_errorLoadImageSrc"
ErrorLoadImageClass="cropper-error-load"
IsAvailableInitCropper="@IsAvailableInitCropper"
IsErrorLoadImage="@IsErrorLoadImage"
OnErrorLoadImageEvent="OnErrorLoadImageEvent"
@ref="cropperComponent"
Options="new Blazor.Models.Options()" />
</div>

<InputFile id="imageReplaceInput" OnChange="ReplaceImageAsync" accept="image/*" />

@* Make sure the size of the image fits perfectly into the container *@
<style>
.big-img {
max-height: 400px;
/* This rule is very important, please don't ignore this */
max-width: 100%;
}
.img-container {
max-height: 400px;
width: 100%;
}
/* These styles are just needed for a nice button and don't related with cropper component */
#imageReplaceInput {
display: inline-block;
padding: 10px 20px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 5px;
text-align: center;
text-decoration: none;
font-size: 16px;
cursor: pointer;
}
</style>

@code {
private readonly string _errorLoadImageSrc = "not-found-image.jpg";
private bool IsErrorLoadImage { get; set; } = false;
private bool IsAvailableInitCropper { get; set; } = true;
private string src = "images/Landscape-Color.jpg";
private CropperComponent? cropperComponent = null!;

public async Task ReplaceImageAsync(InputFileChangeEventArgs inputFileChangeEventArgs)
{
IBrowserFile imageFile = inputFileChangeEventArgs.File;

if (imageFile != null)
{
string oldSrc = src;
string newSrc = await cropperComponent!.GetImageUsingStreamingAsync(imageFile, imageFile.Size);

/* These conditions are required for error handling. */
if (IsErrorLoadImage)
{
IsAvailableInitCropper = true;
IsErrorLoadImage = false;
}
else
{
IsAvailableInitCropper = false;
}

await Task.WhenAll(
cropperComponent?.ReplaceAsync(newSrc, false).AsTask(),
cropperComponent?.RevokeObjectUrlAsync(oldSrc).AsTask())
.ContinueWith(x =>
{
src = newSrc;
});
}
}

public void OnErrorLoadImageEvent(ErrorEventArgs errorEventArgs)
{
IsErrorLoadImage = true;
Destroy();
StateHasChanged();
}

private void Destroy()
{
cropperComponent?.Destroy();
cropperComponent?.RevokeObjectUrlAsync(src);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<div class="img-container">
<CropperComponent Class="big-img"
Src="@src"
ErrorLoadImageSrc="@_errorLoadImageSrc"
ErrorLoadImageClass="cropper-error-load"
IsAvailableInitCropper="@IsAvailableInitCropper"
IsErrorLoadImage="@IsErrorLoadImage"
OnErrorLoadImageEvent="OnErrorLoadImageEvent"
@ref="cropperComponent"
Options="new Blazor.Models.Options()" />
</div>

<InputFile id="imageReplaceInput" OnChange="ReplaceImageAsync" accept="image/*" />

@* Make sure the size of the image fits perfectly into the container *@
<style>
.big-img {
max-height: 400px;
/* This rule is very important, please don't ignore this */
max-width: 100%;
}
.img-container {
max-height: 400px;
width: 100%;
}
/* These styles are just needed for a nice button and don't related with cropper component */
#imageReplaceInput {
display: inline-block;
padding: 10px 20px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 5px;
text-align: center;
text-decoration: none;
font-size: 16px;
cursor: pointer;
}
</style>

@code {
private readonly string _errorLoadImageSrc = "not-found-image.jpg";
private bool IsErrorLoadImage { get; set; } = false;
private bool IsAvailableInitCropper { get; set; } = true;
private string src = "images/Landscape-Color.jpg";
private CropperComponent? cropperComponent = null!;

public async Task ReplaceImageAsync(InputFileChangeEventArgs inputFileChangeEventArgs)
{
IBrowserFile imageFile = inputFileChangeEventArgs.File;

if (imageFile != null)
{
string oldSrc = src;
string newSrc = await cropperComponent!.GetImageUsingStreamingAsync(imageFile, imageFile.Size);

/* These conditions are required for error handling. */
if (IsErrorLoadImage)
{
IsAvailableInitCropper = true;
IsErrorLoadImage = false;
}
else
{
IsAvailableInitCropper = false;
}

await Task.WhenAll(
cropperComponent?.ReplaceAsync(newSrc, false).AsTask(),
cropperComponent?.RevokeObjectUrlAsync(oldSrc).AsTask())
.ContinueWith(x =>
{
src = newSrc;
});
}
}

public void OnErrorLoadImageEvent(ErrorEventArgs errorEventArgs)
{
IsErrorLoadImage = true;
Destroy();
StateHasChanged();
}

private void Destroy()
{
cropperComponent?.Destroy();
cropperComponent?.RevokeObjectUrlAsync(src);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<div class="img-container">
<CropperComponent Class="big-img" Src="images/Landscape-Color.jpg" @ref="cropperComponent" Options="new Blazor.Models.Options()" />
</div>

@if (!IsReplaced)
{
<div class="button" @onclick="ReplaceImageAsync">
Replace image
</div>
}

@* Make sure the size of the image fits perfectly into the container *@
<style>
.big-img {
max-height: 400px;
/* This rule is very important, please don't ignore this */
max-width: 100%;
}
.img-container {
max-height: 400px;
width: 100%;
}
/* These styles are just needed for a nice button and don't related with cropper component */
.button {
display: inline-block;
padding: 10px 20px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 5px;
text-align: center;
text-decoration: none;
font-size: 16px;
cursor: pointer;
}
</style>

@code {
private CropperComponent? cropperComponent = null!;

/* This property is only needed to display the 'Replace image' block. */
private bool IsReplaced = false;

public async Task ReplaceImageAsync()
{
IsReplaced = true;

await cropperComponent!.ReplaceAsync("images/raspberry.jpg", false);
}
}
Loading

0 comments on commit 9fcb6e0

Please sign in to comment.