Skip to content

Commit

Permalink
Merge pull request #20 from KristofferStrube/feature/mobile-pan-and-z…
Browse files Browse the repository at this point in the history
…oom-support

Implemented pinch-to-zoom support.
  • Loading branch information
KristofferStrube committed Oct 22, 2023
2 parents 6f15998 + 2c75fd7 commit 1e7707a
Show file tree
Hide file tree
Showing 9 changed files with 183 additions and 104 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
::deep .anchor-inner-thin {
stroke-width: 2;
r: 10
}

::deep .anchor-inner-thick {
stroke-width: 4;
r: 10
}

::deep .anchor-outer-thin {
stroke-width: 2;
r: 12
}

::deep .anchor-outer-thick {
stroke-width: 4;
r: 14
}
21 changes: 6 additions & 15 deletions src/KristofferStrube.Blazor.SVGEditor/Gradients/Stop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,14 @@

namespace KristofferStrube.Blazor.SVGEditor;

public class Stop : ISVGElement
public class Stop(IElement element, LinearGradient parent, SVGEditor svg) : ISVGElement
{
public Stop(IElement element, LinearGradient parent, SVGEditor svg)
{
Element = element;
Parent = parent;
SVG = svg;
AnimationElements = new();
Key = Guid.NewGuid();
}

public Guid Key { get; set; }
public Guid Key { get; set; } = Guid.NewGuid();

public string? Id { get; set; }
public IElement Element { get; init; }
public LinearGradient Parent { get; init; }
public SVGEditor SVG { get; init; }
public IElement Element { get; init; } = element;
public LinearGradient Parent { get; init; } = parent;
public SVGEditor SVG { get; init; } = svg;

public Type Presenter => throw new NotImplementedException();

Expand Down Expand Up @@ -51,7 +42,7 @@ public double StopOpacity
set { if (value != 1) { Element.SetAttribute("stop-opacity", value.AsString()); } Changed?.Invoke(this); }
}

public List<BaseAnimate> AnimationElements { get; set; }
public List<BaseAnimate> AnimationElements { get; set; } = [];

public Action<ISVGElement>? Changed
{
Expand Down
36 changes: 19 additions & 17 deletions src/KristofferStrube.Blazor.SVGEditor/PathDataSequences/PathData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ namespace KristofferStrube.Blazor.SVGEditor.PathDataSequences;

public static partial class PathData
{
private static readonly string[] instructions = ["M", "m", "Z", "z", "L", "l", "H", "h", "V", "v", "C", "c", "S", "s", "Q", "q", "T", "t", "A", "a"];

public static List<IPathInstruction> Parse(string input)
{
string strippedInput = input.Replace(",", " ").Replace("-", " -");
List<string> instructions = new() { "M", "m", "Z", "z", "L", "l", "H", "h", "V", "v", "C", "c", "S", "s", "Q", "q", "T", "t", "A", "a" };
string standardizedInput = instructions.Aggregate(strippedInput, (accu, curr) => accu.Replace(curr, $",{curr} ")).TrimStart(' ');
string removesDoubleSpaces = RemoveSpaces().Replace(standardizedInput, " ");
IEnumerable<string> splitInstructionSequences = removesDoubleSpaces.Split(",").Select(seq => NormalizeArgumentSequenceWithSpaceZeroDot(seq));
string commaAndSignStandardizedInput = input.Replace(",", " ").Replace("-", " -");
string spaceStandardizedInput = instructions.Aggregate(commaAndSignStandardizedInput, (accu, curr) => accu.Replace(curr, $",{curr} ")).TrimStart(' ');
string doubleSpacesRemovedInput = RemoveSpaces().Replace(spaceStandardizedInput, " ");

IEnumerable<string> splitInstructionSequences = doubleSpacesRemovedInput.Split(",").Select(NormalizeArgumentSequenceWithSpaceZeroDot);
List<IPathInstruction> list = Enumerable.Range(1, splitInstructionSequences.Count() - 1).Aggregate(
new List<IPathInstruction>(),
(list, curr) =>
Expand All @@ -21,10 +23,10 @@ public static List<IPathInstruction> Parse(string input)
string instruction = seq[..1];
if (curr == 1 && instruction is not ("M" or "m"))
{
throw new ArgumentException($"The first sequence is not a move (\"m\" or \"M\") in {strippedInput}");
throw new ArgumentException($"The first sequence is not a move (\"m\" or \"M\") in {commaAndSignStandardizedInput}");
}
List<double> parameters = new();
List<double> parameters = [];
if (seq != "Z" && seq != "z")
{
parameters = seq[2..].Split(" ").Select(p => p.ParseAsDouble()).ToList();
Expand All @@ -34,7 +36,7 @@ public static List<IPathInstruction> Parse(string input)
case "L" or "l":
if (parameters.Count % 2 != 0 && parameters.Count >= 2)
{
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {strippedInput}");
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {commaAndSignStandardizedInput}");
}
Enumerable.Range(0, parameters.Count / 2).ToList().ForEach(i =>
Expand All @@ -46,7 +48,7 @@ public static List<IPathInstruction> Parse(string input)
case "M" or "m":
if (parameters.Count % 2 != 0 && parameters.Count >= 2)
{
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {strippedInput}");
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {commaAndSignStandardizedInput}");
}
Enumerable.Range(0, parameters.Count / 2).ToList().ForEach(i =>
Expand All @@ -58,7 +60,7 @@ public static List<IPathInstruction> Parse(string input)
case "H" or "h":
if (parameters.Count == 0)
{
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {strippedInput}");
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {commaAndSignStandardizedInput}");
}
Enumerable.Range(0, parameters.Count).ToList().ForEach(i =>
Expand All @@ -70,7 +72,7 @@ public static List<IPathInstruction> Parse(string input)
case "V" or "v":
if (parameters.Count == 0)
{
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {strippedInput}");
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {commaAndSignStandardizedInput}");
}
Enumerable.Range(0, parameters.Count).ToList().ForEach(i =>
Expand All @@ -82,7 +84,7 @@ public static List<IPathInstruction> Parse(string input)
case "Z" or "z":
if (parameters.Count != 0)
{
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {strippedInput}");
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {commaAndSignStandardizedInput}");
}
list.Add(new ClosePathInstruction(instruction == "z", previous!));
Expand All @@ -91,7 +93,7 @@ public static List<IPathInstruction> Parse(string input)
case "C" or "c":
if (parameters.Count % 6 != 0 && parameters.Count >= 6)
{
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {strippedInput}");
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {commaAndSignStandardizedInput}");
}
Enumerable.Range(0, parameters.Count / 6).ToList().ForEach(i =>
Expand All @@ -103,7 +105,7 @@ public static List<IPathInstruction> Parse(string input)
case "S" or "s":
if (parameters.Count % 4 != 0 && parameters.Count >= 4)
{
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {strippedInput}");
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {commaAndSignStandardizedInput}");
}
Enumerable.Range(0, parameters.Count / 4).ToList().ForEach(i =>
Expand All @@ -115,7 +117,7 @@ public static List<IPathInstruction> Parse(string input)
case "Q" or "q":
if (parameters.Count % 4 != 0 && parameters.Count >= 4)
{
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {strippedInput}");
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {commaAndSignStandardizedInput}");
}
Enumerable.Range(0, parameters.Count / 4).ToList().ForEach(i =>
Expand All @@ -127,7 +129,7 @@ public static List<IPathInstruction> Parse(string input)
case "T" or "t":
if (parameters.Count % 2 != 0 && parameters.Count >= 2)
{
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {strippedInput}");
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {commaAndSignStandardizedInput}");
}
Enumerable.Range(0, parameters.Count / 2).ToList().ForEach(i =>
Expand All @@ -139,7 +141,7 @@ public static List<IPathInstruction> Parse(string input)
case "A" or "a":
if (parameters.Count % 7 != 0 && parameters.Count >= 7)
{
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {strippedInput}");
throw new ArgumentException($"Wrong number of parameters for '{instruction}' at number {curr} sequence in {commaAndSignStandardizedInput}");
}
Enumerable.Range(0, parameters.Count / 7).ToList().ForEach(i =>
Expand Down
24 changes: 14 additions & 10 deletions src/KristofferStrube.Blazor.SVGEditor/SVGEditor.razor
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
<CascadingValue Value=this IsFixed=true>
<ContextMenuTrigger MenuId="SVGMenu" style="height:100%;" MouseButtonTrigger="ShouldShowContextMenu(null) ? MouseButtonTrigger.Right : (MouseButtonTrigger)4">
<svg @ref=SVGElementReference
@onpointermove="Move"
@onpointerdown="Down"
@onpointerup="Up"
@onpointerout="Out"
@onwheel="Wheel"
@onpointerdown:stopPropagation="true"
@oncontextmenu="()=>{}"
@oncontextmenu:preventDefault="true"
<svg @ref=svgElementReference
@onpointermove="Move"
@onpointerdown="Down"
@ontouchstart="TouchStart"
@ontouchmove="TouchMove"
@ontouchend="TouchEnd"
@ontouchleave="TouchEnd"
@onpointerup="Up"
@onpointerout="Out"
@onwheel="Wheel"
@onpointerdown:stopPropagation="true"
@oncontextmenu="()=>{}"
@oncontextmenu:preventDefault="true"
class="svg-editor"
style="cursor:@(TranslatePanner.HasValue ? "move" : "initial");"
style="cursor:@(translatePanner.HasValue ? "move" : "initial");"
width="100%"
height="100%">
<rect width="100%" height="100%" fill="transparent" @onpointerdown=@UnSelect></rect>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,28 @@ public partial class SVGEditor
{
public void OpenColorPicker(string attributeName, string previousColor, Action<string> colorSetter)
{
ColorPickerShapes = MarkedShapes;
colorPickerShapes = MarkedShapes;
PreviousColor = previousColor;
ColorPickerAttributeName = attributeName;
ColorPickerSetter = colorSetter;
colorPickerAttributeName = attributeName;
colorPickerSetter = colorSetter;
StateHasChanged();
}

private void ColorPickerClosed(string value)
{
if (ColorPickerAttributeName is "Fill")
if (colorPickerAttributeName is "Fill")
{
ColorPickerShapes?.ForEach(s => s.Fill = value);
colorPickerShapes?.ForEach(s => s.Fill = value);
}
else if (ColorPickerAttributeName is "Stroke")
else if (colorPickerAttributeName is "Stroke")
{
ColorPickerShapes?.ForEach(s => s.Stroke = value);
colorPickerShapes?.ForEach(s => s.Stroke = value);
}
else
{
ColorPickerSetter?.Invoke(value);
colorPickerSetter?.Invoke(value);
}
ColorPickerShapes = null;
colorPickerShapes = null;
}

public void MoveToBack()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public partial class SVGEditor : IAsyncDisposable

protected override async Task OnAfterRenderAsync(bool firstRender)
{
BBox = await GetBoundingBox(SVGElementReference);
BBox = await GetBoundingBox(svgElementReference);
}

public async Task FocusAsync(ElementReference elementReference)
Expand Down
Loading

0 comments on commit 1e7707a

Please sign in to comment.