I'm having a really hard time importing and calling SVG.js functions from within React.
Has anyone gotten it to work?
The primary error seems to be: SVG relies on being able to look at the nodes of various elements, but that's not how React allows elements to be accessed.
Svg.js changes nodes directly. React uses a virtual Dom. I see no way to use them together at all. There are react svg libs our there which might be a better fit for the job
Ah. That's disapointing, but that's what I thought.
Thank you
One way to use React with SVG.js is to capture a ref and pass it into the SVG constructor.
<div ref={ref => this.makeSVG(ref)}></div>
makeSVG() then receives the raw DOM element as the argument. This will run every time the render function runs.
Yes that would work. However you completely give up the control of this element to svg. So you can't benefit from the state management and virtual Dom in this case
SVG.js methods can be called from the React lifecycle methods.
Yes that's true. However to have a stable state you should make sure to clear the whole svg and rerender it. After all that's the whole thing about react (+ virtual Dom)
The problem as I see it with using React lifecycle methods - correct me if I'm wrong - but that would not allow your SVG to take advantage of the easy re-rendering when data changes. For example, if the user clicks on a path inside of my editor - it will change to the color they've already selected. That is done via a listener and an update function, using SVG.js, and writing that to my undo/redo object as well.
I wanted to use React thinking that I'd see some benefits by having React automatically update my SVG when the underlying data changes - and by using Redux or MobiX the undo/redo would be pretty automatic rather than manually done by my own code.
But I currently can't see a way to build and manipulate your SVG using SVG.js and still take advantage of any benefit that React has to offer - in fact it looks a bit like a nightmare, like using React for a powerful SVG editor would take 4 times the code, and a lot of hacks just to work.
Am I wrong here?
Correct. You would rerender the whole svg when data changes. You can Ofc go ahead and create components for every element and use that together with react but in that case you cannot use svg.js. Svg.js is more like jquery. It's a Dom manipulation library. React does not fit into these.
It's too bad in a sense, that svg.js just can't manipulate the virtual dom or something- as React has some awesome momentum behind it, and seems like a really great way to get control over the spaghetti aspects of my app - but caramba I am extremely dependent on svg.js - and rewriting even some of these functions in a way that fits into the React style seems like it would do more harm than good, both for performance, and my own sanity :)
Just got a crazy idea. But by using svgdom, we might be able to get vdom to work. As I understand svgdom, then everything is done in memory but the output can be a react/Vue/what-ever parsable SVG string of even vdom nodes if you want to be specific to the view library. I would expect the SVG string approach would be library independent and a lot quicker to develop.
Am I completely off here?
No - that's completely right. I thought about that too. However, what you would get is a vdom which you cannot update properly. Because you didn't attack any life cycle methods to it. Iam not sure how you can manipulate react elements after they were created. Can you add logic for state updates?
@Fuzzyma I'm a react noob so I'm sorry I can't be of much help with any ideas here, but what I'd be really happy to do is test if you all develop any plan of attack! I have to learn react for a client project, but I'd love to try it out with my own stuff. So @dotnetCarpenter I'm up for testing if you have some snippets you think might work!
I wonder if riot.js might not be a better framework for using svg.js...
Since riot is manipulating the DOM and doesn't have a vdom, I would suspect
you are right.
If you are just starting out with MVVM, then I suggest trying out vue.js as
it has much better coupling to other web technologies such as web
components. Making it easier to learn but again, it uses a vdom that just
doesn't work with SVG.js as is.
Unfortunately, I don't have any time to do real development at the moment.
I do try to keep myself updated with the projects I'm involved in, hence my
post.
About react, then yes. It's exacly what you do. You have a model that has a
property update and then the library calls every function that uses this
property. If you used svgdom, then an update to a model property will
trigger a call to the function that uses said property. In turn your
function will use svgdom to manipulate the SVG and the result will be a
change to the vdom. When the library does the diff logic, it will take the
diff set and apply it to the real DOM.
If we can change the vdom, via svgdom, the rest should just work. There is
different ways to manipulate the vdom. Each library has a different vdom
but all of them can parse SVG ( but not all attributes in my experience).
A thought example using Vue.js, which I'm currently working with, would be
to write a simple inline SVG in a template, which will transpile to a js
function, fed into svgdom as a string (after data is added, e.i. handlebar
style logic is applied), svgdom will do its thing by calls from a Vue
method or lifecycle event function, and the resulting string would be
returning to vue.js which would translate it to vdom and finally to real
DOM. This sounds much more complicated than it is but I do expect
performance to be pretty low.
On Mar 14, 2018 9:35 PM, "Stacey Reiman" notifications@github.com wrote:
I wonder if riot.js http://riotjs.com might not be a better framework for
using svg.js...
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/svgdotjs/svg.js/issues/740#issuecomment-373165681, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AACq87Ea4WXNQqrAIHFhJ8f7e4XaUHjIks5teX8kgaJpZM4PZmJv
.
Yeah I am rendering dozens of svgs, manipulating colors on the fly, and have an editor that creates simultaneous variations of the main design. Sounds like this would be miserable to even contemplate coding! I'm looking at some interesting frameworks though, as the react stuff has got me reading up on all sorts of new things I didn't know were out there. As they say, if you blink your JS might already begin getting outdated!
This IS kind of a big deal, though - does anyone know of any drawing libraries like SVG.js that are fully modelled in vdom space? Like, I would love to be able to work with something tree-walked into Redux but not have to rewrite all the drawing tools in the world.
Has anyone here gotten an SVG to output its children into React for, say, thinking about the actual data nodes in the SVG file?
I guess more clearly: how are people writing UI interfaces for SVGjs?
Have you looked at Svelte.js? It's similar to React in many ways, but w/out all of the bloat (but also w/out the rich ecosystem...) - and it doesn't use a vdom, - which means you could outright use SVG.js. The thing about SVG.js is that it's not very modular: in order to use a few functions, you pretty much need the whole thing - or you run into errors that something necessary isn't there. No offense intended - the library is brilliant - just not written in a time when that kind of modularity was the most important thing. Now in the era of modular JS - being able to use 1 off fns w/out needing 75KB min of additional bloat - is more what I'm seeing.
That having been said, you could use something like Riot.js or Svelte if you want a React like app but where you could use the existing SVG.js.
My previous SVG.js; stuff has all used a jQuery like "manipulate it after the fact" type of approach. But I'm rewriting my SVG editor in Svelte - which has been pretty amazing so far. The SVG "reacts" to the data underneath - so if I update the data, the SVG automatically updates. Right now I've only converted the black and white icons to this system, which is easy as they are just path based - but I do plan to use a converter to parse more complicated art to a path array, and incorporate them that way. It's a drastically different way of manipulating SVGs - and I'm not sure yet where I might run into gotchas - I'm just doing stuff like color, stroke, scale, viewbox, etc - so relatively simple things.
I do suspect that you'd have to nearly entirely rewrite SVG.js in order to accommodate for a modular, data driven "reactive" type system. And unless somebody wants to fork some cash over to @Fuzzyma and @wout, I doubt they have the time and energy!! We might be able to do a community driven conversion bit by bit, if somebody had the motivation to oversee it!
Oooh, I hadn't seen Svelte! I looked at Riot but noted the use of vdom and realized I was going to have to re-wrap everything. Thanks for the pointer. Rewriting SVG.js seems... like a good forever project? I bet it'll get done when someone finds a paid use, etc.
I tell you after a week or so using Svelte I am super impressed - Rich Harris (also the creator of rollup) is rock star JS ninja - and it is one of the most sensical, easiest things I've ever used. Give it a try!
Most helpful comment
One way to use React with SVG.js is to capture a ref and pass it into the SVG constructor.
makeSVG()then receives the raw DOM element as the argument. This will run every time the render function runs.