Preserving/propagating svg element bindings

I've imported a complicated SVG and put various bindings and transforms on its elements, but I'm worried someday the graphic will need changing and re-importing. Would there be an efficient way to preserve and paste binding assignments and props from the old SVG to the new one, a sort of mass-paste? I'm thinking you can copy the JSON and just swap out sections that have been changed in a vector drawing program... is there a better way?

Unfortunately, no. A new Component in this context would almost definitely have a different structure - otherwise there would be no point. If it's only the attributes of the svg elements which are being changed, there might be a way...

In theory, if you used an updated svg and that svg had EXACTLY the same structure, you could...

  1. Place your "new" svg into the View.
  2. Copy the View's JSON into your favorite text editor.
  3. Copy the propConfig of the "old" svg component from the View's JSON.
  4. Paste the "old" propConfig into the new correct place on the "new" svg.

It really depends what changes in the SVG. If you're adding objects into it, that's easy, just embed the new svg into the page and copy the individual elements that were added into the existing svg with bindings.
If you're changing existing elements, not so easy, as @cmallonee said. You could script it by processing the View's raw json, but you'd have to make sure you name all of your svg objects properly. It's not a simple task. It also depends what you've bound.

Instead of embedding one big complex SVG picture, it looks like it's better to just embed the SVG elements separately, copy over and modify bindings if needed, position and size them, and possibly erase or alter any other graphics from the original SVG if that's still around. There's a tradeoff: precise drawing in AI exported as one big picture (even though it's tough to work with once in Perspective--nothing can be easily moved around, and re-binding all the elements in an altered, re-imported image is even harder) versus embedding smaller SVG pieces individually and trying to position them together properly in Perspective, but they are easier to work with once positioned.

It would be great if you could embed a picture and break it apart as in Vision...

Keep in mind it's always better to keep objects together in the one drawing/component so they don't resize with pixel inaccuracies which may make them look dodgy

Typically one large SVG will load faster than a bunch of separate SVGs. But, to me the maintainability of multiple SVGs is easier than one large one.

Also remember that there is a performance hit with the number of objects that need to be loaded, so keeping your SVG’s to as few as possible will help, particularly with load times.

I'm trying to add a big SVG to a coordinate container set to %, then add in individual labels for value display. Text can't come in on an SVG of course (using export to screens in AI), because it converts each letter to a path.

But separate labels don't scale well with the SVG; I've tried wrapping them in little flex containers and using 1vw for font sizes, but that doesn't work too well either. What do you usually do in this situation? It does need to display some data, and I'd like to keep it responsive if possible.

It's been a long time since I used Illustrator, but can you export as an "optimised" SVG? I don't know what the equivalent term is in AI, but this is Inkscape terminology. This exports text out just fine as text not as shapes.

E.g.

<svg id="svg6720" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
	<text id="text8897" x="10.514604" y="14.286509" font-family="Calibri" font-size="13.333px" letter-spacing="0px" text-align="center" text-anchor="middle" word-spacing="0px" style="line-height:1.25" xml:space="preserve">
		<tspan id="tspan8895" x="10.514604" y="14.286509">Hel</tspan>
	</text>
</svg>

And in Perspective:

[
  {
    "type": "ia.shapes.svg",
    "version": 0,
    "props": {
      "viewBox": "0 0 24 24",
      "elements": [
        {
          "elements": [
            {
              "id": "tspan8895",
              "name": "tspan8895",
              "text": "Hel",
              "type": "tspan",
              "x": "10.514604",
              "y": "14.286509"
            }
          ],
          "id": "text8897",
          "name": "text8897",
          "style": {
            "lineHeight": "1.25"
          },
          "text": "Hel",
          "textAnchor": "middle",
          "type": "text",
          "x": "10.514604",
          "y": "14.286509"
        }
      ]
    },
    "meta": {
      "name": "hel_0"
    },
    "position": {
      "basis": "300px"
    },
    "custom": {}
  }
]

Actually, it looks like 2 text objects are being added in the Perspective version... that's a bug

1 Like

I'm just learning it seems that AI has an issue exporting text without messing it up in IgP. I'm faster in AI for drawing, so I'm Exporting to SVG from there (which seems almost equivalent to Optimized), re-opening in Inkscape and adding text there... Then export from Inkscape, and delete the elements containing tspan. Previously I was fooled that AI couldn't export SVG text objects at all, it does, they just seem to dislocate to a larger default font.

update to the latest vrsion has some improved svg imports where text should work

I've read some posts that recommend using scripting to drive SVG animations instead of dealing with bindings having to be manually redone every time you re-import. I've been trying to think of the best place for such scripts to live. Right now I'm thinking, maybe create a custom prop on the SVG, and bind it to an expression structure that looks at all the tags the SVG needs. Follow this with a script transform that traverses the SVG and updates elements in response to the tags; its return value is ignored. Maybe it calls on library scripts to supply style classes, colors, etc. to make it less cluttered. The basic traversal looks like (I got the idea from someone else's post):

def transform(self, value, quality, timestamp):
	elements=self.props.elements
	for index in elements:
		properties=index.elements
		for subindex, subprop in enumerate(properties):
			if subprop.id=='derp':
				if value.blue:
					subprop['fill']['paint']='blue'
				elif value.green:
					subprop['fill']['paint']='green'
	return value