Coder Social home page Coder Social logo

kristofferstrube / blazor.svgeditor Goto Github PK

View Code? Open in Web Editor NEW
273.0 273.0 45.0 41.97 MB

A basic SVG editor written in Blazor.

Home Page: https://kristofferstrube.github.io/Blazor.SVGEditor/

License: MIT License

C# 73.19% HTML 25.88% CSS 0.83% JavaScript 0.09%
blazor blazor-webassembly drag-and-drop editor path renderer svg webassembly wysiwyg

blazor.svgeditor's Introduction

Kristoffer Strube

I'm currently working on using Blazor Web Apps to work with the browser easily and safely.

Right now, I'm focusing on wrapping the Web Audio API and its surrounding API's in my Blazor.WebAudio and Blazor.MediaCaptureStreams projects.

My Blog: https://kristoffer-strube.dk

I also do consultancy primarily focused on Blazor. If you are interested in my services, just contact me on Twitter or LinkedIn. Jobs related to my open-source projects get a considerable rebate.

Contact

Twitter 🐤: @KStrubeG

LinkedIn 👔: KristofferStrube

Mastodon 🐘: @KristofferStrube

BlueSky 🦋: @kstrubeg.bsky.social

blazor.svgeditor's People

Contributors

kristofferstrube avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blazor.svgeditor's Issues

Feature: Rotation

It would be nice if we could rotate shapes. We can do this using CSS transforms but we should make sure to scope this feature as it can get rather complex if we have multiple series of rotation combined with scaling and translation.

There are multiple possibilities for scaling. The best one would be to have some natural mapping like a third anchor that can be used explicitly for rotation. Other simpler ideas could be to have discrete options for rotation like "Rotate 90 degrees" or to have some input in the context menu to control the rotation numerically.

Seperating decimal numbers that have no spaces but are seperated by dots.

Sometimes we get input like this for some instructions in path data:

a.457.318.914.317.61.78

Which should be made into:

a 0.457 0.318 0.914 0.317 0.61 0.78

The idea would be to find all places where there is a . char with either an alphabetic char before or numbers that continue until another . without any spaces.

I tried doing something like this.

string pattern = @"\.(\d+)\.";
string replacement = "$0 0.";
string input = "a.457.318.914.317.61.78";
string result = Regex.Replace(input, pattern, replacement);

but that result is:

a.457. 0.318.914. 0.317.61. 0.78

So I need to match on [a-zA-Z] optionally and I need somehow to match dots twice and fix some extra .´s.

One could also take a look at the implementation details for Path data: https://www.w3.org/TR/SVG/paths.html#PathDataBNF
where they have written a full parse three in BNF that could potentially capture all of this without any edge cases like this.

But for this second approach, we need to redo the full parsing which will potentially make it tougher to read.

Feature: Background graphics

It seems sensible that it should be possible to add some background graphics/shapes to either serve as context for what is being edited or to give an idea of the zoom level/placement of the viewport.

This can be implemented in many ways, so I will start off by describing some simple cases and then later try to come up with an implementation that can support these cases.

  • Grid: It would be nice to have a grid layout on the whole-number coordinates so that the user can relate the size of their shapes to this and align different parts of shapes to each other more easily. A problem with this is that it can be rather heavy to render many shapes in the background that will move a lot when the viewport moves.
  • Static Shape: If the goal for using the editor is to sketch over something, then having a set of shapes that can't be selected, which are placed in the background, would be nice.

For both cases, the background shapes/grid would need to be transformed according to where the viewport is, so we can't simply place some static SVG/HTML in the background.

Before specifying any solution further, I would love to get feedback from the library users to see what concrete cases you have.

Feature: Fit viewport to Shapes

It would be awesome to be able to call some function on the SVGEditor taking a list of shapes that would zoom and translate the viewport of the editor so that the given shapes are centered in the middle of the editor with some padding from the edge of the bounding area.

This could be especially useful in the Blazor.GraphEditor library where nodes' positions are updated continuously.

Bugfix : Deleting multiple selection with Delete button does not work and create console error

Bugfix : in ShapeEditor::KeyUp

                if (eventArgs.Key == "Delete")
                {
                    SVGElement.SVG.Remove(SVGElement.SVG.SelectedElements);
                    SVGElement.SVG.SelectedElements.Clear();
                }

In SVG.razor.cs I commented SelectedElements.Clear(); So this will not work with contextual menu ( I do not use them anymore in my fork).

 public void Remove(ISVGElement SVGElement)
        {
            ElementsAsHtml.RemoveAt(Elements.IndexOf(SVGElement));
            Elements.Remove(SVGElement);
            //SelectedElements.Clear();
            UpdateInput();
            RerenderAll();
        }

        public void Remove(List<ISVGElement> elements)
        {
            foreach (var element in elements)
            {
                this.Remove(element);
            }
        }

Factorization canbe improved to avoid unnecessary code like

            UpdateInput();
            RerenderAll();

Feature: Possible natural mapping for stroke-dasharray

The stroke-dasharray attribute has a lot of possibilities for natural mapping in some control. Right now, we simply take a free-text input that is inserted in the shape.

I imagine som kind of drag and drop of stops on a line similar to how we control the stops of a LinearGradient. But I'm open to ideas.

Could not find 'blazorContextMenu.SetMenuHandlerReference' ('blazorContextMenu' was undefined)

Hi Kristoffer,
I followed the steps for integrating the SVG Editor, but during the runtime I get the error below.
I tried also manually to register the service without success. Could you help?
Best regards,
Nedim.

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Could not find 'blazorContextMenu.SetMenuHandlerReference' ('blazorContextMenu' was undefined).
Error: Could not find 'blazorContextMenu.SetMenuHandlerReference' ('blazorContextMenu' was undefined).
at https://localhost:5002/_framework/blazor.webassembly.js:1:328
at Array.forEach ()
at a.findFunction (https://localhost:5002/_framework/blazor.webassembly.js:1:296)
at _ (https://localhost:5002/_framework/blazor.webassembly.js:1:2442)
at https://localhost:5002/_framework/blazor.webassembly.js:1:3330
at new Promise ()
at Object.beginInvokeJSFromDotNet (https://localhost:5002/_framework/blazor.webassembly.js:1:3311)
at Object.Gt [as invokeJSFromDotNet] (https://localhost:5002/_framework/blazor.webassembly.js:1:62569)
at Object.Ii (https://localhost:5002/_framework/dotnet.7.0.10.vzm6zpl6t5.js:5:71974)
at _mono_wasm_invoke_js_blazor (https://localhost:5002/_framework/dotnet.7.0.10.vzm6zpl6t5.js:14:103886)
Microsoft.JSInterop.JSException: Could not find 'blazorContextMenu.SetMenuHandlerReference' ('blazorContextMenu' was undefined).
Error: Could not find 'blazorContextMenu.SetMenuHandlerReference' ('blazorContextMenu' was undefined).

Annotations on an image

I have a need to annotate an image and I was thinking that this project would be a great start.

is it possible to add an image and then make the drawings on top of that image?

Bug: Complete Without Close Instruction gets `ArgumentOutOfRangeException`.

Stack trace:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: ArgumentOutOfRange_IndexMustBeLess Arg_ParamName_Name, index
System.ArgumentOutOfRangeException: ArgumentOutOfRange_IndexMustBeLess Arg_ParamName_Name, index
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder , RenderFragment , Exception& )

Feature: Add automatic centering and scaling function after svg file loaded

After SVGEditor.Elements is loaded, is it possible to center all elements to SVgEdit according to the display area, and automatically match the appropriate scaling(maybe a padding value there) according to the display area so that it fills the display area? I saw that SVGEdit has “SVGEditor. Scale” and “SVGEditor.Translate”, but it seems that after loading is completed, the boundarybox of all elements and the boundarybox of SVgEdit need to be calculated in order to calculate the new "Translate" and "Scale". that will be great with this automatic centering and scaling function.

form :
3

to (center and bigger/smaller to fill the display area):
4

Feature: Virtualization

Currently, we recalculate the positions of lines, markers, and the shapes themselves even when they are outside the bounds of the viewport. To minimize this problem we should use the concept called virtualization.

There are many approaches to this, but the most important part is that we should probably only query the selectable points with some margin. The next part is that we currently loop through all shapes in the SVG DOM linearly when we render them. This means that we have to go through all the first hierarchy shapes even the ones we don't render. Instead, we should speak to store the shapes in a tree structure so that we only need to traverse some constant number of paths from the root to render the visible shapes. One such tree is a KD-tree. But before going with this approach I need to make some preliminary analysis of what number of shapes this would be faster for and in which scenarios it applies if any.

Refactoring with interfaces

Kristoffer,
your work has been really impressive, in this project.

In particular, I found it incredibly useful to use the editor for Bezier curves, in a project I'm working on.

image

My only (small) concern is that I had to create a new SVG element, removing all the things I don't need. I attach the resulting set of projects, where you can see that I had to duplicate a lot of other classes, because creating an SVG2 element, there is a strong dependency on the concrete class in other elements.
I'm wondering if it could be possible to refactor things a little bit to make things cleaner... I'm available to help, if you want...

Blazor.SVGEditor.zip

SVGEditor code in a server-side app : System.InvalidOperationException: The current thread is not associated with the Dispatcher

When using the SVGEditor code in a server-side app and editing the svg as text in textarea

"System.InvalidOperationException: The current thread is not associated with the Dispatcher"
<SVG @ref=SVG1 Input=@input1 InputUpdated="(string s) => { Input1 = s; StateHasChanged(); }" />

After reading this
<SVG @ref=SVG1 Input=@input1 InputUpdated="(string s) => { Input1 = s; InvokeAsync(StateHasChanged); }" />
Solve the issue

Color Picker css not load

The BlazorColorPicker.bundle.scp.css file is not load in _context.The ColorPicker style is displayed incorrectly and can not display and hidden.

Bugix : `Elements.IndexOf(element)` value should be checked to avoid crashes

When removing elements and adding new one then removing, it can crash

in SVG.razor.cs

        protected override void OnInitialized()
        {

            ElementSubject
                .Buffer(TimeSpan.FromMilliseconds(33))
                .Where(updates => updates.Count > 0)
                .Subscribe(updates =>
                {
                    updates
                        .Distinct()
                        .ToList()
                        .ForEach(element =>
                        {
                            ElementsAsHtml[Elements.IndexOf(element)] = element.ToHtml();
                        });
                    UpdateInput();
                });
        }

Don't you think Elements.IndexOf(element) value should be checked to secure the code and avoid crashes ?
image

Access to internal instructions (and adding new elements by instructions)

Kristoffer,
really a good job, in creating this library. It's very clear and useful out of the box, but I'm wondering if it would be possible to make it even more flexible, giving access to the internal instructions.
I went quickly through the inner code, and I feel that your work on the internal representation is even more interesting than the front end side. For what I see, in this moment I can only work passing and receiving the svg representation, with the cumbersome syntax.
For scientific drawing, for example, it would be much more flexible to be able to pass and receive the list of instructions of a path.
...or maybe I'm missing something, here... :-)
Congratulations again, I would like to have your opinion, when you can, of course.
Thank you.
AB

Bug: Selection is lost when zooming with touch

When you use touch to zoom, all selected shapes are deselected. This was implemented this way as it was not clear the user had touched the back facade as a part of the zoom, which should deselect all shapes.
This has brought pain as users spend a lot of time selecting shapes, which they lose when zooming. To mitigate this, we should only deselect all shapes if a touch interaction starts with pressing the back facade and has not performed any zooming.

Feature: Panning and zooming on mobile

We want to be able to support panning and zooming on mobile devices that don't have a mouse.

We currently support panning on devices that have a mouse by listening for the middle-button being pressed. And we support zooming by listening for the scroll-wheen being rolled.

There exist many methods for supporting panning on touch devices. One such approach is to start panning if the user has multiple fingers on the screen. Some only need to have 2 or more fingers on the screen to support a generic free movement of zoom, panning, and coordinate system rotation. But there are other options, so I'm very open to ideas. We haven't implemented rotation of the coordinate system on the desktop yet so I would probably also wait to implement that until I have found an intuitive interaction method for rotating on the desktop.

Self Closing Tags Not Supported

The following SVG lines should both render in the same way. However, the set of the self-closing tags only renders the first object. Presumably it's not correctly identifying the tag is closed.
Does not work correctly:
<rect x="120" y="380" height="125" width="140" fill="green" stroke="blue" stroke-width="2"/> <circle cx="450" cy="300" r="80" stroke="green" stroke-width="1" fill="url('#purple_blue_up_right')"/>
Does work correctly:
<rect x="120" y="380" height="125" width="140" fill="green" stroke="blue" stroke-width="2"></rect> <circle cx="450" cy="300" r="80" stroke="green" stroke-width="1" fill="url('#purple_blue_up_right')"></circle>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.