Skip to content

Commit 8741d5e

Browse files
authored
feat(ImageCropper): add OnCropChangedAsync parameter (#460)
* doc: 更新注释 * feat: 增加 Invoke 能力 * feat: 增加 OnCropEndAsync 回调方法 * feat: 增加 ImageCropperData 结构体 * chore: bump version 9.0.3 * refactor: 更新回调名称
1 parent b7f49fb commit 8741d5e

6 files changed

Lines changed: 155 additions & 53 deletions

File tree

src/components/BootstrapBlazor.ImageCropper/BootstrapBlazor.ImageCropper.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>9.0.2</Version>
4+
<Version>9.0.3</Version>
55
</PropertyGroup>
66

77
<PropertyGroup>

src/components/BootstrapBlazor.ImageCropper/ImageCropper.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@namespace BootstrapBlazor.Components
22
@inherits BootstrapModuleComponentBase
3-
@attribute [JSModuleAutoLoader("./_content/BootstrapBlazor.ImageCropper/ImageCropper.razor.js")]
3+
@attribute [JSModuleAutoLoader("./_content/BootstrapBlazor.ImageCropper/ImageCropper.razor.js", JSObjectReference = true)]
44

55
<div @attributes="@AdditionalAttributes" class="@ClassString" id="@Id">
66
<img src="@Url" class="bb-cropper-image" />

src/components/BootstrapBlazor.ImageCropper/ImageCropper.razor.cs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Website: https://www.blazor.zone or https://argozhang.github.io/
44

55
using Microsoft.AspNetCore.Components;
6+
using Microsoft.JSInterop;
67

78
namespace BootstrapBlazor.Components;
89

@@ -29,6 +30,12 @@ public partial class ImageCropper
2930
[Parameter]
3031
public Func<ImageCropperResult, Task>? OnCropAsync { get; set; }
3132

33+
/// <summary>
34+
/// 获得/设置 剪裁框调整大小位置回调方法
35+
/// </summary>
36+
[Parameter]
37+
public Func<ImageCropperData, Task>? OnCropChangedAsync { get; set; }
38+
3239
/// <summary>
3340
/// 获取/设置 裁剪选项
3441
/// </summary>
@@ -81,10 +88,14 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
8188
/// <inheritdoc/>
8289
/// </summary>
8390
/// <returns></returns>
84-
protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Options ?? new());
91+
protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, new
92+
{
93+
Options = Options ?? new(),
94+
TriggerOnCropEndAsync = OnCropChangedAsync != null ? nameof(TriggerOnCropChangedAsync) : null,
95+
});
8596

8697
/// <summary>
87-
/// 剪裁方法 自动触发 <see cref="OnCropAsync"/> 回调方法
98+
/// 剪裁方法 触发 <see cref="OnCropAsync"/> 回调方法
8899
/// </summary>
89100
public async Task<string?> Crop()
90101
{
@@ -153,4 +164,17 @@ public Task Disable()
153164
/// <param name="angle">旋转角度</param>
154165
/// <returns></returns>
155166
public async Task Rotate(int angle) => await InvokeVoidAsync("rotate", Id, angle);
167+
168+
/// <summary>
169+
///
170+
/// </summary>
171+
/// <returns></returns>
172+
[JSInvokable]
173+
public async Task TriggerOnCropChangedAsync(ImageCropperData data)
174+
{
175+
if (OnCropChangedAsync != null)
176+
{
177+
await OnCropChangedAsync(data);
178+
}
179+
}
156180
}

src/components/BootstrapBlazor.ImageCropper/ImageCropper.razor.js

Lines changed: 81 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import Data from '../BootstrapBlazor/modules/data.js'
33
import { addLink } from '../BootstrapBlazor/modules/utility.js'
44

5-
export async function init(id, options) {
5+
export async function init(id, invoke, options) {
66
await addLink("./_content/BootstrapBlazor.ImageCropper/cropper.bundle.css");
77

88
const el = document.getElementById(id);
@@ -11,9 +11,20 @@ export async function init(id, options) {
1111
}
1212

1313
const image = el.querySelector(".bb-cropper-image");
14-
const cropper = new Cropper(image, getOptions(options));
14+
const { options: op, triggerOnCropEndAsync } = options;
15+
if (triggerOnCropEndAsync) {
16+
let cropData = null;
17+
op.cropend = () => {
18+
invoke.invokeMethodAsync(triggerOnCropEndAsync, cropData);
19+
cropData = null;
20+
}
21+
op.crop = e => {
22+
cropData = e.detail;
23+
}
24+
}
25+
const cropper = new Cropper(image, getOptions(op));
1526

16-
Data.set(id, cropper);
27+
Data.set(id, { el, invoke, options, cropper });
1728
}
1829

1930
const getOptions = op => {
@@ -27,86 +38,110 @@ const getOptions = op => {
2738
}
2839

2940
export function dispose(id) {
30-
const cropper = Data.get(id);
41+
const ic = Data.get(id);
3142
Data.remove(id);
3243

33-
if (cropper != null) {
34-
cropper.destroy();
44+
if (ic != null) {
45+
const { cropper } = ic;
46+
if (cropper) {
47+
cropper.destroy();
48+
}
3549
}
3650
}
3751

3852
export function crop(id) {
3953
let ret = null;
40-
const cropper = Data.get(id);
41-
if (cropper != null) {
42-
const { isRound } = cropper.options;
43-
cropper.crop();
44-
let resultData = cropper.getCroppedCanvas();
45-
if (isRound) {
46-
resultData = getRoundCanvas(resultData);
54+
const ic = Data.get(id);
55+
if (ic != null) {
56+
const { cropper, options } = ic;
57+
if (cropper !== null) {
58+
cropper.crop();
59+
let resultData = cropper.getCroppedCanvas();
60+
61+
const { isRound } = options.options;
62+
if (isRound) {
63+
resultData = getRoundCanvas(resultData);
64+
}
65+
ret = resultData.toDataURL();
66+
resultData = null;
4767
}
48-
ret = resultData.toDataURL();
49-
resultData = null;
5068
}
5169
return ret;
5270
}
5371

5472
export function replace(id, url) {
55-
const cropper = Data.get(id);
56-
if (cropper != null) {
57-
cropper.replace(url);
73+
const ic = Data.get(id);
74+
if (ic != null) {
75+
const { cropper } = ic;
76+
if (cropper) {
77+
cropper.replace(url);
78+
}
5879
}
5980
}
6081

6182
export function reset(id) {
62-
const cropper = Data.get(id);
63-
if (cropper != null) {
64-
cropper.reset();
83+
const ic = Data.get(id);
84+
if (ic != null) {
85+
const { cropper } = ic;
86+
if (cropper) {
87+
cropper.reset();
88+
}
6589
}
6690
}
6791

6892
export function setDragMode(id, mode) {
69-
const cropper = Data.get(id);
70-
if (cropper != null) {
71-
cropper.setDragMode(mode);
93+
const ic = Data.get(id);
94+
if (ic != null) {
95+
const { cropper } = ic;
96+
if (cropper) {
97+
cropper.setDragMode(mode);
98+
}
7299
}
73100
}
74101

75102
export function rotate(id, angle) {
76-
const cropper = Data.get(id);
77-
if (cropper != null) {
78-
cropper.rotate(angle);
103+
const ic = Data.get(id);
104+
if (ic != null) {
105+
const { cropper } = ic;
106+
if (cropper) {
107+
cropper.rotate(angle);
108+
}
79109
}
80110
}
81111

82112
export function clear(id) {
83-
const cropper = Data.get(id);
84-
if (cropper != null) {
85-
cropper.clear();
113+
const ic = Data.get(id);
114+
if (ic != null) {
115+
const { cropper } = ic;
116+
if (cropper) {
117+
cropper.clear();
118+
}
86119
}
87120
}
88121

89122
export async function enable(id) {
90-
const cropper = Data.get(id);
91-
if (cropper != null) {
92-
cropper.enable();
93-
}
94-
95-
const el = document.getElementById(id);
96-
if (el) {
97-
el.classList.remove("disabled");
123+
const ic = Data.get(id);
124+
if (ic != null) {
125+
const { el, cropper } = ic;
126+
if (cropper) {
127+
cropper.enable();
128+
}
129+
if (el) {
130+
el.classList.remove("disabled");
131+
}
98132
}
99133
}
100134

101135
export async function disable(id) {
102-
const cropper = Data.get(id);
103-
if (cropper != null) {
104-
cropper.disable();
105-
}
106-
107-
const el = document.getElementById(id);
108-
if (el) {
109-
el.classList.add("disabled");
136+
const ic = Data.get(id);
137+
if (ic != null) {
138+
const { el, cropper } = ic;
139+
if (cropper) {
140+
cropper.disable();
141+
}
142+
if (el) {
143+
el.classList.add("disabled");
144+
}
110145
}
111146
}
112147

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
// Website: https://www.blazor.zone or https://argozhang.github.io/
4+
5+
namespace BootstrapBlazor.Components;
6+
7+
/// <summary>
8+
/// 裁切数据实体类
9+
/// </summary>
10+
public struct ImageCropperData
11+
{
12+
/// <summary>
13+
/// 获得/设置 裁剪框高度值
14+
/// </summary>
15+
public float Height { get; set; }
16+
17+
/// <summary>
18+
/// 获得/设置 裁剪框宽度值
19+
/// </summary>
20+
public float Width { get; set; }
21+
22+
/// <summary>
23+
/// 获得/设置 裁剪框 X 值
24+
/// </summary>
25+
public float X { get; set; }
26+
27+
/// <summary>
28+
/// 获得/设置 裁剪框 Y 值
29+
/// </summary>
30+
public float Y { get; set; }
31+
32+
/// <summary>
33+
/// 获得/设置 裁剪框旋转角度值
34+
/// </summary>
35+
public float Rotate { get; set; }
36+
37+
/// <summary>
38+
/// 获得/设置 裁剪框 X 轴缩放值
39+
/// </summary>
40+
public float ScaleX { get; set; }
41+
42+
/// <summary>
43+
/// 获得/设置 裁剪框 Y 轴缩放值
44+
/// </summary>
45+
public float ScaleY { get; set; }
46+
}

src/components/BootstrapBlazor.ImageCropper/ImageCropperResult.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ namespace BootstrapBlazor.Components;
99
/// <summary>
1010
/// 裁切结果实体类
1111
/// </summary>
12-
/// <remarks>
13-
/// 构造函数
14-
/// </remarks>
1512
/// <param name="data"></param>
1613
public class ImageCropperResult(string data)
1714
{

0 commit comments

Comments
 (0)