Tip: how to create SVGs and changing the fill color dynamically

Here it is.

JSON code

[
{
“type”: “ia.shapes.svg”,
“version”: 0,
“props”: {
“viewBox”: “0 0 140 120”,
“elements”: [
{
“elements”: [
{
“d”: “m8.6705 44.8h121.91”,
“fill”: {
“paint”: “#C0C0C0
},
“name”: “path”,
“stroke”: {
“paint”: {
“gradientTransform”: “matrix(0 0 0 0 -15897 -329.96)”,
“stops”: [
{
“offset”: “0”,
“stopColor”: “#55555a
}
],
“type”: “linear”
}
},
“type”: “path”
},
{
“fill”: {
“paint”: {
“gradientTransform”: “matrix(0 0 0 0 -15897 -415.11)”,
“stops”: [
{
“offset”: 0
}
],
“type”: “linear”
}
},
“height”: “59.583”,
“name”: “rect”,
“transform”: “scale(-1)”,
“type”: “rect”,
“width”: “121.91”,
“x”: “-131.13”,
“y”: “-104.79”
},
{
“d”: “m4 110h132v-100h-5v95h-122v-95h-5z”,
“fill”: {
“paint”: {
“gradientTransform”: “matrix(2.3872 0 0 4.7384 4109.4 3902.3)”,
“stops”: [
{
“offset”: “0”,
“stopColor”: “#d9d1c8
}
],
“type”: “linear”
},
“rule”: “evenodd”
},
“name”: “path”,
“stroke”: {
“dasharray”: “1, 1”,
“linecap”: “square”,
“paint”: {
“gradientTransform”: “matrix(0 0 0 0 -15897 -415.11)”,
“stops”: [
{
“offset”: “0”,
“stopColor”: “#9c9e9f
}
],
“type”: “linear”
}
},
“type”: “path”
},
{
“d”: “m9.0329 14.767h121.26v-4.6842h-121.26z”,
“fill”: {
“paint”: {
“gradientTransform”: “matrix(2.3872 0 0 4.7384 4109.4 3902.3)”,
“stops”: [
{
“offset”: “0”,
“stopColor”: “#d9d1c8
}
],
“type”: “linear”
},
“rule”: “evenodd”
},
“name”: “path”,
“stroke”: {
“dasharray”: “1.16609, 1.16609”,
“linecap”: “square”,
“paint”: {
“gradientTransform”: “matrix(0 0 0 0 -15897 -415.11)”,
“stops”: [
{
“offset”: “0”,
“stopColor”: “#9c9e9f
}
],
“type”: “linear”
}
},
“type”: “path”
}
],
“name”: “group”,
“type”: “group”
}
],
“Fill”: “blue”
},
“meta”: {
“name”: “OPT Sump 2”
},
“position”: {
“height”: 1,
“width”: 1
},
“custom”: {
“customPropColor”: “stronger gray”
},
“propConfig”: {
“props.elements[0].elements[1].fill.paint.stops[0].stopColor”: {
“binding”: {
“config”: {
“path”: “this.custom.customPropColor”
},
“transforms”: [
{
“fallback”: “#000000”,
“inputType”: “scalar”,
“mappings”: [
{
“input”: “stronger gray”,
“output”: “#A0A0A0
}
],
“outputType”: “color”,
“type”: “map”
}
],
“type”: “property”
}
}
}
}
]

Edit 2:

Formatted JSON string
[
  {
    "type": "ia.container.coord",
    "version": 0,
    "props": {
      "mode": "percent",
      "aspectRatio": "1:1"
    },
    "meta": {
      "name": "root"
    },
    "position": {},
    "custom": {},
    "children": [
      {
        "type": "ia.shapes.svg",
        "version": 0,
        "props": {
          "viewBox": "0 0 140 120",
          "elements": [
            {
              "elements": [
                {
                  "d": "m8.6705 44.8h121.91",
                  "fill": {
                    "paint": "#C0C0C0"
                  },
                  "name": "path",
                  "stroke": {
                    "paint": {
                      "gradientTransform": "matrix(0 0 0 0 -15897 -329.96)",
                      "stops": [
                        {
                          "offset": "0",
                          "stopColor": "#55555a"
                        }
                      ],
                      "type": "linear"
                    }
                  },
                  "type": "path"
                },
                {
                  "fill": {
                    "paint": {
                      "gradientTransform": "matrix(0 0 0 0 -15897 -415.11)",
                      "stops": [
                        {
                          "offset": 0
                        }
                      ],
                      "type": "linear"
                    }
                  },
                  "height": "59.583",
                  "name": "rect",
                  "transform": "scale(-1)",
                  "type": "rect",
                  "width": "121.91",
                  "x": "-131.13",
                  "y": "-104.79"
                },
                {
                  "d": "m4 110h132v-100h-5v95h-122v-95h-5z",
                  "fill": {
                    "paint": {
                      "gradientTransform": "matrix(2.3872 0 0 4.7384 4109.4 3902.3)",
                      "stops": [
                        {
                          "offset": "0",
                          "stopColor": "#d9d1c8"
                        }
                      ],
                      "type": "linear"
                    },
                    "rule": "evenodd"
                  },
                  "name": "path",
                  "stroke": {
                    "dasharray": "1, 1",
                    "linecap": "square",
                    "paint": {
                      "gradientTransform": "matrix(0 0 0 0 -15897 -415.11)",
                      "stops": [
                        {
                          "offset": "0",
                          "stopColor": "#9c9e9f"
                        }
                      ],
                      "type": "linear"
                    }
                  },
                  "type": "path"
                },
                {
                  "d": "m9.0329 14.767h121.26v-4.6842h-121.26z",
                  "fill": {
                    "paint": {
                      "gradientTransform": "matrix(2.3872 0 0 4.7384 4109.4 3902.3)",
                      "stops": [
                        {
                          "offset": "0",
                          "stopColor": "#d9d1c8"
                        }
                      ],
                      "type": "linear"
                    },
                    "rule": "evenodd"
                  },
                  "name": "path",
                  "stroke": {
                    "dasharray": "1.16609, 1.16609",
                    "linecap": "square",
                    "paint": {
                      "gradientTransform": "matrix(0 0 0 0 -15897 -415.11)",
                      "stops": [
                        {
                          "offset": "0",
                          "stopColor": "#9c9e9f"
                        }
                      ],
                      "type": "linear"
                    }
                  },
                  "type": "path"
                }
              ],
              "name": "group",
              "type": "group"
            }
          ],
          "Fill": "blue"
        },
        "meta": {
          "name": "OPT Sump 2"
        },
        "position": {
          "height": 1,
          "width": 1
        },
        "custom": {
          "customPropColor": "stronger gray"
        },
        "propConfig": {
          "props.elements[0].elements[1].fill.paint.stops[0].stopColor": {
            "binding": {
              "config": {
                "path": "this.custom.customPropColor"
              },
              "transforms": [
                {
                  "fallback": "#000000",
                  "inputType": "scalar",
                  "mappings": [
                    {
                      "input": "stronger gray",
                      "output": "#A0A0A0"
                    }
                  ],
                  "outputType": "color",
                  "type": "map"
                }
              ],
              "type": "property"
            }
          }
        }
      },
      {
        "type": "ia.display.label",
        "version": 0,
        "props": {
          "style": {
            "backgroundColor": "#A0A0A0"
          }
        },
        "meta": {
          "name": "Label"
        },
        "position": {
          "x": 0.0641,
          "y": 0.3849,
          "height": 0.44,
          "width": 0.8714
        },
        "custom": {}
      }
    ]
  }
]

would you format the json by pressing </> before pasting it here

It seems your matrix transform isnt quite correct.
infact i dont really know what you are trying to do with the gradients at all
one stop doesnt really provide anything usefull with them if you dont even have an offset.

every gradient in your svg with a matrix with 's in the first 3 posiitons wont really do anything… idk why it does in the designer, it shouldnt xd

change them to 1 or whatever and it should atleast some something, but i dont see the point of gradients here, you should just do a plain fill

That image is part of a larger image this company has been working on. Since it has been challenging to use SVG in perspective, I took one Inkscape drawing, separated every object, and saved them as an optimized SVG. Then I imported each one in a folder called "drawings" :laughing: in Perspective.

So I can see that not whatever someone draws in SVG can be imported into Perspective. (I haven't tried in Vision)

Answring your questions

Inkscape doing.

Again, Inkscape

What about an image that shows 4 thousand errors in Perspective? I can't be done manually.

That's why I think that some tips and tricks has to be draft out for ignition 8.1. Everyone will know what and what not to do with their SVGs.

Still, there are many people that have succesfully imported svgs from inkspace…
maybe its just the gradient, ignition does something weird with it for sure xd

I think that you may be running in to this:

Also, watch out for this:

For simple things, I usually just draw them inside the designer, by embedding this blank SVG and adding the elements/paths that I need.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
  xmlns:svg="http://www.w3.org/2000/svg"
  xmlns="http://www.w3.org/2000/svg"
  width="50mm"
  height="50mm"
  viewBox="0 0 50 50"
  version="1.1">
</svg>

Those are the only tags outside of the actual elements that you need in an SVG.

For larger complicated SVG's I use Inkscape and save them as optimized. I stole the settings for that from @nminchin.

Honestly though, complex SVG's should be linked, and you should use separate SVG's only for the things which you must animate or interact with.

2 Likes

That helped me. Tomorrow I'll give it a try.

That sounds hard. I can imagine how it's done.

I'll have to give it a try to see how the linked SVG works with the rest of the objects. Like if the resizing is good for everything in the designer plus the linked SVG.

Man it would be nice if there was a way to be able to manually add these css properties into the perspective classes, rather than being restricted to the listed one only… Thanks for the tip, I needed that :slight_smile:

you can add any css you want even if ignition doesnt recognize it

You can, but you have to add your other css to your p style within your css theme

I meant add it to the perspective style classes, not the css files.

1 Like

I didn’t word my comment right. I meant in the styles, under “applied styles” like here. I’d like to add “vector-effect” but it’s not selectable from any of the options, and I can’t add it manually, unless you can tell me otherwise :slight_smile:

1 Like

I found that this was the best method too as I had more visibility and control over the styles from within Ignition designer rather than having to go to the css files. I was a little worried about all the extra class bindings I’m having to make on virtually all components, but with a bit of testing, I didn’t find any performance issues. Did you have any?

I know that increasing the number of bindings must be increasing overhead that could impact view loading times, but I have not experienced significant issues with this. That said, I try to keep SVG elements to a minimum and I only do simple property bindings on the elements that need to change their style. I think keeping the logic that determines which style class is used limited to a single custom property probably helps minimize the impact on performance.

I imagine you could test the validity of that last statement by copying your custom property’s style-class-determining binding to every SVG element’s style.classes property in a duplicate view and just see how the two load, side by side. If it’s an SVG with very few elements, you may not even see much of a difference though.

Yeah, exactly. I’ve done a few tests and I see no performance draw back. My class bindings are all dependant on the “theme” session prop. And yes, all my SVG’s have as little elements as I can get away with to reduce the bindings.

I also have a full suite of a alarming styles that get applied based on the alarm status (active/ack/unack…etc) using animations. And speaking of performance, that really tripped me up, because background-colour animation was destroying GPU usage, as it was re-rendering at each blink. With some HTML5 and CSS knowledge and research, I found that the main two properties that browsers can animate without re-rendering were Opacity and Transform. So I use opacity animation rather than bg-colour and the performance difference on the client/browser was incredible. Sorry, I got a bit side-tracked there. :slight_smile:

1 Like

Maybe I didn't word mine right either. You can add vector-effect into a Perspective Style, but you won't be able to see it in the Designer, and you need to add it via a CSS theme.

E.g. if you P. Style path is: Thing/Something/Style1
then in CSS theme you would use:

.psc-Thing\/Something\/Style1 {
   vector-effect: non-scaling-stroke;
}

I don't know if this will completely override the style or just add to it... and if it overrides it, how you would just add to it... over to @victordcq !

2 Likes

css is additive, so it would work!

if you would also put for example width in both styleclass and theme.css than the one that gets loaded in last will win, which should be the styleclass.(i think) (Unless you use !important)

over and out :smiley:

3 Likes

@nminchin do you mind showing me an example, for some reason I wasn't able to get what you described to work.

Actually, I think you can coerce extra CSS properties into a style class from the designer alone. Whether you’re supposed to be able to or not is another matter. :slight_smile: A quick test in version 8.1.9 seems to confirm that a sort of “property injection” similar to the CSS injection hack @victordcq found will also work if you place your intended property within a property that takes a string value, you would just need to prefix it with a semi-colon to close the property you are entering it into:

; vector-effect: non-scaling-stroke

No need for a semi-colon at the end unless you wish to add multiple properties at once, since the originally edited style class property will end the line in a semi-colon automatically. Observe:

Inspecting an element that has been assigned this style class from Chrome’s web dev tools:
image

10 Likes

Very cool! I didn’t even think about that, but that’s great to know :grinning: