Modify SVG in the background - javascript

I have SVG icons of some elements. These elements are for example road signals on the level crossing. If a road signal is shining RED light, I change the appropriate SVG element's fill to red.
Now I have these elements in a menu, and I want each of them to have it's icon, but also that this icon represents its lamp state. So when the lamp state changes, the icon at the appropriate element also changes.
I did this before in Java (GWT) and I did it by loading the icon into a variable in a helper class (SvgHelper) and then anytime I wanted to display icon of particular element anywhere, I called svgHelper.getIcon(element) and it modified the svg, that it has stored in a variable, (in the background) and then returned me new cloned SVGImage that I could the put anywhere. So I only had one icon, changed its state, cloned it and returned.
Now when I want to do it in javascript, it seems, that to work with the SVG in any way, it has to be in the DOM first.
Is there a way to work with the SVG "in the background" so that it is not in the DOM? Because I would rather change multiple SVG properties and once finished then put the SVG in the DOM. Also I target the elements by ID and there can be multiple of those icons on a single page, so the IDs would collide.
I tried using svg.js and import my svg from string, but from what I understood the library actually requires some div to work in, so it adds it to the DOM.
In java I was doing it using this library and since it is in the end compiled to JS, there should be a way to do it.

Since even the GWT library adds the SVG to the DOM, I ended up doing just that. So I have some object which I have in a DOM somewhere outside of the screen, target the element by ID, change its properties. Onec the SVG is ready, I put it in its destination using vuejs's v-html directive.

Related

How to manipulate inline SVG from vuex

So, I am creating a customizing tool for cursors with Vuejs and Vuex. Currently, I am stuck in the step where I have to bind a color user is going to click on to the fill of svg cursor. I will try to cover step by step how everyhing works and what it should do.
First of all, I have different inline SVG's which are replacing the default HTML cursor. These SVG's are placed in the Vuex state.
Just so you know they are put like this so when the user clicks on a button on the first component, script hides default cursor and binds chosen one with V-HTML. Basically, I am displaying them as HTML code in the components.
This is where the issue begins. Now, this chosen cursor displays on the second component where the user should be able to change the fill color.
What I can't figure out is how can I access the property of fill in the svg's?
I have tried to bind it via :fill = "dataName" but it doesn't work like that.
I am new to Vuejs but I hope my question makes sense.
The problem is that you're inserting the inline SVG (via v-html) after the Vue compilation step, so — as you've noticed — Vue never sees that content. Without more context, it's hard to see how you could achieve what you want.
As an alternative, though, you could have all your cursors use currentColor for the fill color
<path fill="currentColor">
and then simply set the CSS color property of some containing element to the desired color

Data Binding with Angular 2 & Inline SVG

I have an SVG image, parts of which I change dynamically depending on responses from an API call. One aspect I change is the colour of different elements within the SVG, which I can handle somewhat cleanly via applying different CSS classes. However there are also text elements that I would like to change.
I have this currently working by inlining the full SVG image into my component template and picking out the parts I wish to bind to the model. However, this means that any time I want to edit the raw SVG image I need to copy/paste the SVG markup back into the template and reapply these bindings.
Ideally what I would do is keep the SVG as an external file, then inline the SVG as part of the build process so I can avoid sandboxing (something I can currently do), but I also want to dynamically apply the data bindings via a selector (e.g. id/class associated with each SVG sub-element) after the SVG is inlined. Two solutions I've come up with would be to create a directive that would do some DOM manipulation to associate the relative elements with the values I want to set, or to modify the SVG tags in the build process post-inline to add the Angular binding syntax here. Neither option seems great to me.
Is there another way to do this that I'm missing?

xml to svg dynamically

I have been searching for months now about this subject, but I can't find anything about it. What I'm looking for: I have sheetmusic on my screen, which is xml converted to svg with javascript. Now I want to make buttons with which I can manipulate the SVG that's displayed on the screen. For example: the music has lyrics underneath the notes and chords above it. Let's say I want to replace or remove them with an onclick button. All this temporarily, only on the screen.
I am currently working on a similar project. You have 2 approaches:
Directly modify SVG (hmmm not cool if you have complex objects)
Find out which SVG element is to be modified, find the corresponding id
in the XML structure, modify the XML node, "recompile" XML to SVG.
As a more performant way, you may compile only the node that changed and
then insert it in the SVG.
In order to select the element you want to apply an action on, you can set
a 'click' event listener on each selectable element.

Load saved svg shapes and access them through javascript

I am trying to draw svg shapes, add events(click, drag etc.) and properties to the shapes and save them to server from my web application. I also want to load these saved shapes from the server and access their events and properties from my web application.
My Problems are:
A. I can not load a previously saved svg shape while I am drawing new ones at the same time. I am trying to load saved svg blocks by using .html(). I have tried using append also with same results.
In this JSFiddle link I have tried to create a similar scenario. Once you click Load Annotation Button, an svg block renders. But it erases the previous element.
B. Before loading the saved annotations, if you click the existing line, you will find that the element is being selected (alert message with the id of element). But after you add saved annotations to the svg block, you cannot find the elements by clicking on them.
there must be something I am doing wrong. Can you point it out please?

Setting the Location of Groups

A newbie question. As I've explained in a prior post, I'm coming to SVG Land from Flash loaded with ActionScript expectations and misconceptions.
I've built an interactive graphic using D3 and I'm nearly finished except that I want to add a little pop-up box that displays when a user mouses over a state. Right now it appears as a static object labeled "West Virginia" on the left side of the stage:
http://www.50laboratories.com/miscellany/demographicclout2.html
The pop-up is a group with its own distinct ID. I need to be able to set its x and y location depending on the state being hovered over, but so far can't figure out how. It seems to me that I should be able to address a group in my JavaScript as I would a named movie clip in Flash, but visiting API references like this one, https://github.com/mbostock/d3/wiki/API-Reference, I see no references to methods and properties of group objects. Thanks in advance for your help.
Unlike actionscript, svg elements are dom nodes and manipulating them involves either setting their attributes or style properties. You could manipulate these by calling certain attribute/style setters of the dom nodes, but since you're using d3, you set those attributes/styles using d3's setters.
The way to position a element with d3 is to
1. select it, by the id you assigned it
2. set its transform attribute to translate([some-x], [some-y])
d3.select("#statepopup").attr("transform", "translate(50,100)");
P.S.
The transform attribute is also how you can scale and rotate the group.

Categories

Resources