AnimatedLines Exchange Resource

I saw a linked in post advertising the Animated SVG Arrow Lines Exchange resource found here:

Is there documentation about using the animation elements used in that SVG? I thought it was SMIL but I drag/dropped an SVG using SMIL animation and Ignition chopped out all the animation stuff.

I can kind of deduce how to create the animations based on these properties but I’d prefer to read the documentation to figure out the limits. I have some ideas.

I saw the post about this on X the other day. Looks interesting

Hello! I am the author of that resource, and I think I can help point you to some helpful resources for creating SVG animation that works with Ignition.

W3 Schools SVG Animation Documentation is a good place for some examples, and using the “try it out” function is helpful to see in real time how changing the settings changes the animation.

Mozilla SVG Animate Docs also has some details about the animate element, with an example of using values instead of from and to.

From what I have tested, animateTransform does not work (which prevents rotation), but animate elements do work (so you can do motion of one property at a time).

For how I made these specific animations in this resource, each animated line is made up of a light grey rectangle, an animated mask (moving), a rectangle that is masked with the animation, and another rectangle overlaid at 0.3 opacity that the color is set by the fill paint property.

The animated mask is made up of identical squares that are either black or white, all moving down at a 45 degree angle, shown here with the background of the SVG in green. Our target rectangle is the grey one between the green background and the moving squares.

svgAnimation45Degrees

Each square (except for that tiny white one at the end) is the exact same in dimensions and animate properties, except for the start time. by delaying each black square 0.25s after each white square, and having each white square 1s apart, it creates a nice overlap that makes an arrow shape.

Because we can’t use animateTransform elements and I wanted arrows, I had to use the overlapping black and white squares at an angle to create an arrow, but by putting a rotate transform on each square, it moved the motion to align with the grey outline.

svgAnimationAigned

That little white square is to make the last black square not cause a cutout on the first white one when it loops, so the arrows look the same each loop.

Now that the “arrows” are aligned with the grey rectangle in the background, cropping down the SVG to the size of the grey rectangle gets us much closer to the final goal.

svgAnimationAignedCropped

Now we have to set the filled rectangle to be masked by the moving squares, and the fill color will only show where the mask layer is white. the black or transparent sections will not show.

svgAnimationColor

8 Likes

Cool. Thanks for the explanation.

I have been working my way through it by systematically deleting nodes and seeing what changes then hitting undo. Your explanation is great and it looks like I can’t use the same approach with what I’m trying to do.

I’m trying to repeat bubbles across the viewbox. I drew some nice bubbles and injected them into a modified copy of one of your exchange element instances but I can’t animate them using the same approach because they are drawn using cx and cy which makes very funny things happen if I animate it. The documentation you linked shows it animating a circle so I think you pointed me in the right direction to sort it out.

I also modified the radius and location of my circles to fit inside the viewbox of the instance I’m messing with. I’m trying to build a perspective friendly version of a concept I saw at a wastewater plant to show flow in pipes.


Edit: Yeah, this is looking very possible. I can make one bubble smoothly work. I have a number of tweaks to do and it will work.

It basically works but the elements hang out in the front as it gets to their delay point. I removed the gradient for a proof of concept so I could test with 1/3 as many elements.

My conclusion is that it can be done like this but there’s probably a better approach to do what I’m trying to do but that approach works great for what you were doing. Thanks for showing me how the animation stuff works. I didn’t know that was a thing till I saw your resource.

[
  {
    "type": "ia.shapes.svg",
    "version": 0,
    "props": {
      "viewBox": "0 35 1086 80",
      "elements": [
        {
          "elements": [
            {
              "type": "linearGradient",
              "id": "linearGradient6",
              "elements": [
                {
                  "type": "stop",
                  "name": "stop",
                  "offset": "0",
                  "stopColor": "#bed2dc"
                },
                {
                  "type": "stop",
                  "name": "stop",
                  "offset": ".50329",
                  "stopColor": "#bed2dc",
                  "stopOpacity": "0"
                }
              ],
              "name": "linearGradient6"
            },
            {
              "type": "linearGradient",
              "id": "linearGradient4",
              "elements": [
                {
                  "type": "stop",
                  "name": "stop",
                  "offset": "0",
                  "stopColor": "#fff"
                },
                {
                  "type": "stop",
                  "name": "stop",
                  "offset": ".6407",
                  "stopColor": "#fff",
                  "stopOpacity": "0"
                }
              ],
              "name": "linearGradient4"
            },
            {
              "type": "linearGradient",
              "id": "linearGradient1",
              "elements": [
                {
                  "type": "stop",
                  "name": "stop",
                  "offset": "0",
                  "stopColor": "#bec8d2"
                },
                {
                  "type": "stop",
                  "name": "stop",
                  "offset": "1",
                  "stopColor": "#b4c3cd"
                }
              ],
              "name": "linearGradient1"
            },
            {
              "type": "radialGradient",
              "id": "radialGradient2",
              "name": "radialGradient2",
              "cx": "129.87",
              "cy": "131.21",
              "r": "20",
              "gradientTransform": "matrix(-.019773 1.9856 -1.1245 -.011198 168.41 -181.51)",
              "gradientUnits": "userSpaceOnUse",
              "href": "#linearGradient1"
            },
            {
              "type": "radialGradient",
              "id": "radialGradient2-0",
              "name": "radialGradient2-0",
              "cx": "130.39",
              "cy": "130.15",
              "r": "20",
              "gradientTransform": "matrix(-.015537 1.1074 -1.0065 -.014121 152.5 -66.621)",
              "gradientUnits": "userSpaceOnUse",
              "href": "#linearGradient4"
            },
            {
              "type": "radialGradient",
              "id": "radialGradient2-0-5",
              "name": "radialGradient2-0-5",
              "cx": "152.47",
              "cy": "137.81",
              "r": "20",
              "gradientTransform": "matrix(1.3853 .044426 -.023296 .72644 -188.27 -1.052)",
              "gradientUnits": "userSpaceOnUse",
              "href": "#linearGradient6"
            },
            {
              "type": "radialGradient",
              "id": "radialGradient2-09",
              "name": "radialGradient2-09",
              "cx": "129.87",
              "cy": "131.21",
              "r": "20",
              "gradientTransform": "matrix(-.019773 1.9856 -1.1245 -.011198 192.75 -238.13)",
              "gradientUnits": "userSpaceOnUse",
              "href": "#linearGradient1"
            },
            {
              "type": "radialGradient",
              "id": "radialGradient2-0-8",
              "name": "radialGradient2-0-8",
              "cx": "130.39",
              "cy": "130.15",
              "r": "20",
              "gradientTransform": "matrix(-.015537 1.1074 -1.0065 -.014121 176.84 -123.24)",
              "gradientUnits": "userSpaceOnUse",
              "href": "#linearGradient4"
            },
            {
              "type": "radialGradient",
              "id": "radialGradient2-0-5-5",
              "name": "radialGradient2-0-5-5",
              "cx": "152.47",
              "cy": "137.81",
              "r": "20",
              "gradientTransform": "matrix(1.3853 .044426 -.023296 .72644 -163.92 -57.673)",
              "gradientUnits": "userSpaceOnUse",
              "href": "#linearGradient6"
            }
          ],
          "name": "defs",
          "type": "defs"
        },
        {
          "type": "group",
          "elements": [
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "0s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "20",
              "cy": 90,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "0.3s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "44.34",
              "cy": 60,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "0.6s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "20",
              "cy": 90,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "0.9s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "44.34",
              "cy": 60,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "1.2s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "20",
              "cy": 90,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "1.5s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "44.34",
              "cy": 60,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "1.8s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "20",
              "cy": 90,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "2.1s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "44.34",
              "cy": 60,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "2.4s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "20",
              "cy": 90,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "2.7s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "44.34",
              "cy": 60,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "3s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "20",
              "cy": 90,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "3.3s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "44.34",
              "cy": 60,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "3.6s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "20",
              "cy": 90,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "3.9s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "44.34",
              "cy": 60,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "4.2s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "20",
              "cy": 90,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "4.5s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "44.34",
              "cy": 60,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "4.8s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "20",
              "cy": 90,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "5.1s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "44.34",
              "cy": 60,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "5.4s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "20",
              "cy": 90,
              "r": 10
            },
            {
              "type": "circle",
              "fill": {
                "opacity": 0.6,
                "paint": "#EEEEFF"
              },
              "elements": [
                {
                  "type": "animate",
                  "attributeName": "cx",
                  "begin": "5.7s",
                  "dur": "6s",
                  "from": 20,
                  "repeatCount": "indefinite",
                  "to": "100%"
                }
              ],
              "name": "circle",
              "cx": "44.34",
              "cy": 60,
              "r": 10
            }
          ]
        }
      ],
      "style": {
        "backgroundColor": "#808080"
      }
    },
    "meta": {
      "name": "NormalLongThin_9"
    },
    "position": {
      "x": 51.130677185058595,
      "y": 146,
      "height": 36,
      "width": 496
    },
    "custom": {
      "note": "This one goes to 100% with no gradient elements"
    }
  }
]

If anyone saw that, I hit the wrong thing and it wasn’t a code block lol

Edit:
I see I should have started them at a negative position also so they are not visible prior to use.