Skip to content

Commit 0dc307e

Browse files
ZonoraiCarel vd Merwemckaragoz
authored
New Component: MudSignaturePad (#277)
* Added an initial implementation for a signature pad * Add Localized String & Outer Class to paper * Makeup --------- Co-authored-by: Carel vd Merwe <[email protected]> Co-authored-by: mckaragoz <[email protected]>
1 parent 425a70e commit 0dc307e

File tree

15 files changed

+611
-5
lines changed

15 files changed

+611
-5
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace MudExtensions;
2+
3+
public enum LineCapTypes
4+
{
5+
Round,
6+
Butt,
7+
Square,
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace MudExtensions;
2+
3+
public enum LineJoinTypes
4+
{
5+
Round,
6+
Bevel,
7+
Miter
8+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
@using Microsoft.JSInterop
2+
@using MudBlazor.Charts
3+
@using MudBlazor.Utilities
4+
@using System.Text
5+
@namespace MudExtensions
6+
@inject IJSRuntime JsRuntime
7+
@inherits ComponentBase
8+
9+
<MudPaper Elevation="@Elevation" Class="@OuterClass">
10+
<div class="@ToolbarClassname" style="@ToolbarStyle">
11+
<MudIconButton Variant="@Variant" Icon="@DrawEraseChipIcon" Color="@Color" OnClick="async () => await IsEditToggled()" Size="@(Dense ? Size.Small : Size.Medium)" />
12+
@if (ShowClear)
13+
{
14+
<MudIconButton OnClick="ClearPad" Variant="@Variant" Color="@Color" Icon="@Icons.Material.Filled.Clear" Size="@(Dense ? Size.Small : Size.Medium)" />
15+
}
16+
@if (ShowDownload)
17+
{
18+
<MudIconButton OnClick="Download" Variant="@Variant" Color="@Color" Icon="@Icons.Material.Filled.Download" Size="@(Dense ? Size.Small : Size.Medium)" />
19+
}
20+
@ToolbarContent
21+
</div>
22+
<div class="@CanvasContainerClassname" style="@CanvasContainerStyle">
23+
<canvas @ref="_reference" id="@_id"></canvas>
24+
</div>
25+
<div class="@ToolbarClassname" style="@ToolbarStyle">
26+
@if (ShowLineWidth)
27+
{
28+
<MudNumericField T="decimal" Value="Options.LineWidth" ValueChanged="LineWidthUpdated" Label="@LocalizedStrings.LineWidth"
29+
Variant="@Variant" Margin="@(Dense ? Margin.Dense : Margin.Normal)" Min="1" Step="1" />
30+
}
31+
@if (ShowStrokeStyle)
32+
{
33+
<MudColorPicker Value="Options.StrokeStyle" ValueChanged="StrokeStyleUpdated" Label="@LocalizedStrings.StrokeColor"
34+
Variant="@Variant" Margin="@(Dense ? Margin.Dense : Margin.Normal)" />
35+
}
36+
@if (ShowLineJoinStyle)
37+
{
38+
<MudSelect T="LineJoinTypes" Value="Options.LineJoinStyle" ValueChanged="LineJoinTypeUpdated" ToStringFunc="x => x.ToString()"
39+
Label="@LocalizedStrings.LineJoinStyle" Variant="@Variant" Margin="@(Dense ? Margin.Dense : Margin.Normal)" Dense="@Dense">
40+
@foreach (var value in Enum.GetValues<LineJoinTypes>())
41+
{
42+
<MudSelectItem T="LineJoinTypes" Value="value"></MudSelectItem>
43+
}
44+
</MudSelect>
45+
}
46+
@if (ShowLineCapStyle)
47+
{
48+
<MudSelect T="LineCapTypes" Value="Options.LineCapStyle" ValueChanged="LineCapTypeUpdated" ToStringFunc="x => x.ToString()"
49+
Label="@LocalizedStrings.LineCapStyle" Variant="@Variant" Margin="@(Dense ? Margin.Dense : Margin.Normal)" Dense="@Dense">
50+
@foreach (var value in Enum.GetValues<LineCapTypes>())
51+
{
52+
<MudSelectItem T="LineCapTypes" Value="value"></MudSelectItem>
53+
}
54+
</MudSelect>
55+
}
56+
</div>
57+
</MudPaper>
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
using System.Text;
2+
using Microsoft.AspNetCore.Components;
3+
using Microsoft.JSInterop;
4+
using MudBlazor;
5+
using MudBlazor.Utilities;
6+
using MudExtensions.Utilities;
7+
8+
namespace MudExtensions;
9+
10+
public partial class MudSignaturePad : IAsyncDisposable
11+
{
12+
public MudSignaturePad()
13+
{
14+
_dotnetObjectRef = DotNetObjectReference.Create<MudSignaturePad>(this);
15+
}
16+
17+
protected string CanvasContainerClassname => new CssBuilder()
18+
//.AddClass($"border-solid border-2 mud-border-{Color.ToDescriptionString()}")
19+
.AddClass(CanvasContainerClass)
20+
.Build();
21+
22+
protected string ToolbarClassname => new CssBuilder()
23+
.AddClass("pa-2 d-flex flex-wrap gap-2")
24+
.AddClass(ToolbarClass)
25+
.Build();
26+
27+
private DotNetObjectReference<MudSignaturePad> _dotnetObjectRef;
28+
ElementReference _reference;
29+
bool _isErasing = true;
30+
int _lineWidth = 3;
31+
private byte[] _value = Array.Empty<byte>();
32+
readonly string _id = Guid.NewGuid().ToString();
33+
string DrawEraseChipText => _isErasing ? LocalizedStrings.Eraser : LocalizedStrings.Pen;
34+
string DrawEraseChipIcon => _isErasing ? Icons.Material.Filled.Edit : Icons.Material.Filled.EditOff;
35+
36+
private object JsOptionsStruct => new
37+
{
38+
lineWidth = Options.LineWidth,
39+
lineCap = Options.LineCapStyle.ToString().ToLower(),
40+
lineJoin = Options.LineJoinStyle.ToString().ToLower(),
41+
strokeStyle = Options.StrokeStyle.Value
42+
};
43+
44+
[Parameter]
45+
public byte[] Value
46+
{
47+
get => _value;
48+
set
49+
{
50+
if (value == _value) return;
51+
52+
_value = value;
53+
}
54+
}
55+
56+
[Parameter] public EventCallback<byte[]> ValueChanged { get; set; }
57+
[Parameter] public SignaturePadLocalizedStrings LocalizedStrings { get; set; } = new();
58+
[Parameter] public SignaturePadOptions Options { get; set; } = new SignaturePadOptions();
59+
60+
[Parameter] public string ToolbarClass { get; set; }
61+
[Parameter] public string ToolbarStyle { get; set; }
62+
[Parameter] public string OuterClass { get; set; }
63+
[Parameter] public int Elevation { get; set; } = 4;
64+
[Parameter] public string CanvasContainerClass { get; set; }
65+
[Parameter] public string CanvasContainerStyle { get; set; } = "height: 100%;width: 100%; box-shadow: rgb(204, 219, 232) 3px 3px 6px 0px inset, rgba(255, 255, 255, 0.5) -3px -3px 6px 1px inset;";
66+
[Parameter] public bool ShowClear { get; set; } = true;
67+
[Parameter] public bool ShowLineWidth { get; set; } = true;
68+
[Parameter] public bool ShowStrokeStyle { get; set; } = true;
69+
[Parameter] public bool ShowDownload { get; set; } = true;
70+
[Parameter] public bool ShowLineJoinStyle { get; set; } = true;
71+
[Parameter] public bool ShowLineCapStyle { get; set; } = true;
72+
[Parameter] public bool Dense { get; set; }
73+
[Parameter] public Variant Variant { get; set; }
74+
[Parameter] public Color Color { get; set; }
75+
[Parameter] public RenderFragment ToolbarContent { get; set; }
76+
77+
protected override async Task OnAfterRenderAsync(bool firstRender)
78+
{
79+
if (firstRender)
80+
{
81+
await JsRuntime.InvokeVoidAsync("mudSignaturePad.addPad", _dotnetObjectRef, _reference, JsOptionsStruct);
82+
if (Value.Length > 0)
83+
{
84+
await PushImageUpdateToJsRuntime();
85+
}
86+
}
87+
88+
await base.OnAfterRenderAsync(firstRender);
89+
}
90+
91+
private async Task IsEditToggled()
92+
{
93+
await JsRuntime.InvokeVoidAsync("mudSignaturePad.togglePadEraser", _reference);
94+
_isErasing = !_isErasing;
95+
}
96+
97+
async Task ClearPad()
98+
{
99+
await JsRuntime.InvokeVoidAsync("mudSignaturePad.clearPad", _reference);
100+
}
101+
102+
async Task PushImageUpdateToJsRuntime()
103+
{
104+
await JsRuntime.InvokeVoidAsync("mudSignaturePad.updatePadImage", _reference, Convert.ToBase64String(Value));
105+
}
106+
107+
async Task UpdateOptions()
108+
{
109+
await JsRuntime.InvokeVoidAsync("mudSignaturePad.updatePadOptions", _reference, JsOptionsStruct);
110+
}
111+
112+
async Task Download()
113+
{
114+
await JsRuntime.InvokeVoidAsync("mudSignaturePad.downloadPadImage", _reference);
115+
}
116+
117+
private async Task LineWidthUpdated(decimal obj)
118+
{
119+
Options.LineWidth = obj;
120+
await UpdateOptions();
121+
}
122+
123+
private async Task StrokeStyleUpdated(MudColor obj)
124+
{
125+
Options.StrokeStyle = obj;
126+
await UpdateOptions();
127+
}
128+
129+
private async Task LineJoinTypeUpdated(LineJoinTypes obj)
130+
{
131+
Options.LineJoinStyle = obj;
132+
await UpdateOptions();
133+
}
134+
135+
private async Task LineCapTypeUpdated(LineCapTypes obj)
136+
{
137+
Options.LineCapStyle = obj;
138+
await UpdateOptions();
139+
}
140+
141+
public async ValueTask DisposeAsync()
142+
{
143+
try
144+
{
145+
await JsRuntime.InvokeVoidAsync("mudSignaturePad.disposePad", _reference);
146+
}
147+
catch
148+
{
149+
//ignore
150+
}
151+
}
152+
153+
[JSInvokable]
154+
public async Task SignatureDataChangedAsync()
155+
{
156+
var base64Data = await JsRuntime.InvokeAsync<string>("mudSignaturePad.getBase64", _reference);
157+
try
158+
{
159+
Value = Convert.FromBase64String(base64Data.Replace("data:image/png;base64,", ""));
160+
}
161+
catch (Exception)
162+
{
163+
Value = Array.Empty<byte>();
164+
}
165+
166+
await ValueChanged.InvokeAsync(Value);
167+
}
168+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using MudBlazor.Utilities;
2+
3+
namespace MudExtensions;
4+
5+
public class SignaturePadOptions
6+
{
7+
public LineCapTypes LineCapStyle { get; set; } = LineCapTypes.Round;
8+
public LineJoinTypes LineJoinStyle { get; set; } = LineJoinTypes.Round;
9+
public MudColor StrokeStyle { get; set; } = new MudColor("#000000");
10+
public decimal LineWidth { get; set; } = 4;
11+
}

0 commit comments

Comments
 (0)