Animated SVG dynamically

i wanna make ang svg similar to this gif
[https://user-images.githubusercontent.com/61006057/227771568-78497ecc-e863-46f2-b29e-e15c7c20a154.gif]

I would like to have control over the position of the circle so that it can be moved according to production
I have made an SVG and i'm able to move the circle with binding but i want the circle continue moving

Any tips how to do it?

1 Like

Post your SVG file somewhere so that we can look at it. Make sure you imbed your SVG in your project and do not save and link it.

SVG's are formatted dictionaries so you just need to find the right group of objects to bind the call to. When you insert your SVG into the designer you should see all of the data. You would then bind the x and y coordinate's to script that produces the results that you need.

Hope this nebulus answer helped, but without seeing the SVG it is a little difficult to figure out what you already have.

This is an example two circles embedded in the view.

1 Like

Ok i have the same tree of svg and i found the circle, if i edit cx the circle move, how i can move the circle every second and go to start at the end of line? The question is how i can run a script every second for add +1 in cx?

Try This Binding:

(dateExtract(now(10),"ms")+dateExtract(now(1000),"seconds")1000)%5000/5000100+240`

This will move the item 100 pixels every 5 seconds, broken up into 10 ms moves. This is not the most effecient way to do this, especially if you want to use it over and over again. For that I would create a memory tag that does this and then allow you to use the timer/over and over again.

Memory Tag may be just

dateExtract(now(10),"ms")+dateExtract(now(1000),"seconds")

Good luck.

The dramatically more efficient way to do timed animations in Perspective is to just set whatever properties to whatever value you want, and control the timing via a CSS animation in the advanced stylesheet.

6 Likes

Agree with @PGriffith

Here is a spinner animation.

Stylesheet CSS looks like:

@keyframes spin {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}

.psc-spinner {
    animation: spin 1s linear infinite;
}

Looks like:
spinner

Looks a lot better in the browser, the GIF kind of messes with the appearance of the animation.

Here is the view:

{
  "custom": {},
  "params": {},
  "props": {
    "defaultSize": {
      "height": 422,
      "width": 573
    }
  },
  "root": {
    "children": [
      {
        "meta": {
          "name": "spinner"
        },
        "position": {
          "height": 176,
          "width": 155,
          "x": 183,
          "y": 106
        },
        "props": {
          "elements": [
            {
              "elements": [
                {
                  "elements": [
                    {
                      "offset": "0%",
                      "stopColor": "value",
                      "type": "stop"
                    },
                    {
                      "offset": "25%",
                      "stopColor": "#07c",
                      "stopOpacity": "75%",
                      "type": "stop"
                    },
                    {
                      "offset": "50%",
                      "stopColor": "#07c",
                      "stopOpacity": "50%",
                      "type": "stop"
                    },
                    {
                      "offset": "75%",
                      "stopColor": "#07c",
                      "stopOpacity": "25%",
                      "type": "stop"
                    },
                    {
                      "offset": "100%",
                      "stopColor": "#07c",
                      "stopOpacity": "5%",
                      "type": "stop"
                    }
                  ],
                  "id": "fade",
                  "type": "linearGradient",
                  "x1": "1%",
                  "x2": "80%",
                  "y1": "95%",
                  "y2": "15%"
                }
              ],
              "type": "defs"
            },
            {
              "cx": 24,
              "cy": 24,
              "fill": "transparent",
              "r": 22,
              "stroke": {
                "paint": "url(#fade)",
                "width": 4
              },
              "type": "circle"
            }
          ],
          "style": {
            "classes": "spinner"
          },
          "viewBox": "0 0 48 48"
        },
        "type": "ia.shapes.svg"
      }
    ],
    "meta": {
      "name": "root"
    },
    "type": "ia.container.coord"
  }
}

Only thing of note, is that the animation doesn't work in the designer (for whatever reason, probably has to do with when the stylesheet CSS is applied?)

Anyway, works as expected in the browser.

Apparently its SVG week.

4 Likes

thank you very much, very clear in the explanation I think it is the best method!

I would like to understand how to a complex path using the CSS. Did you get that example to work and would you be willing to share the code?

I'm not sure I understand the question you're asking.

When I look at the sample diagram that was provided by original poster, some of the paths are not straight lines or circles. I was wondering how one would go about creating that path with CSS (i.e. from Solar to the House).

I see.

I would have to work something up to answer fully.

But you would probably need to use a translate3d(x,y,z) command. This would allow you to move an object along a non linear path.

I think you're looking for a stroke offset. @jlandwerlen posted an example of one here:

1 Like

Okay,

Had a little time to set something up. I think this illustrates what you're trying to do. Obviously, you can add text and other niceties to this.

All of this was done inside of the designer (no third party software).

The crux of it is using the animateMotion element on an SVG to move it along a path. Note that it must be an element.

Other notes that are of interest. The "Large Circles" are filled with the var(--containerRoot) color., this makes them appear "transparent" but still hides the animated circles when the "go into" the large circles.

The curved paths were created using a Quadratic Bezier Curve, I didn't take the time to make them exactly what was shown in the example, you may have better luck with a Cubic Bezier. Either way it is important that you use the same path for drawing as you do for the animation path (other wise it will look weird (of course you don't have to also draw the path in which case it wont matter).

Finally, order in tree of elements inside of the SVG matters. Top most elements are drawn first, and as you add elements they are drawn on top of those already drawn. So if for instance you swapped the "Large Circles" with the "Animated Circles" the animated circles would not be hidden behind the large ones.

Finished Product:

animatedShapes

View JSON

{
"custom": {},
"params": {},
"props": {
"defaultSize": {
"height": 762,
"width": 1055
}
},
"root": {
"children": [
{
"meta": {
"name": "blank"
},
"position": {
"height": 723,
"width": 1019,
"x": 16,
"y": 15
},
"props": {
"elements": [
{
"elements": [
{
"stroke": {
"paint": "#008AB0",
"width": 0.125
},
"type": "line",
"x1": 7.125,
"x2": 42.75,
"y1": 25,
"y2": 25
},
{
"stroke": {
"paint": "#D64091",
"width": 0.125
},
"type": "line",
"x1": 25,
"x2": 25,
"y1": 15.125,
"y2": 34.875
},
{
"stroke": {
"paint": "#438E00",
"width": 0.125
},
"type": "line",
"x1": 2,
"x2": 2,
"y1": 15.125,
"y2": 19.875
},
{
"stroke": {
"paint": "#DC779C",
"width": 0.125
},
"type": "line",
"x1": 48,
"x2": 48,
"y1": 15.125,
"y2": 19.875
},
{
"stroke": {
"paint": "#4B9FC8",
"width": 0.125
},
"type": "line",
"x1": 48,
"x2": 48,
"y1": 30.2,
"y2": 34.875
},
{
"d": "M27.25,14.5 Q28,24 43,23.5",
"fill": "none",
"stroke": {
"paint": "#FF9803",
"width": 0.125
},
"type": "path"
},
{
"d": "M27.25,35.5 Q28,27 43,26.5",
"fill": "none",
"stroke": {
"paint": "#3AB1B3",
"width": 0.125
},
"type": "path"
},
{
"d": "M22.75,35.5 Q22,27 6.8,26.5",
"fill": "none",
"stroke": {
"paint": "#9A0FFF",
"width": 0.125
},
"type": "path"
},
{
"d": "M22.75,14.5 Q22,24 6.8,23.5",
"fill": "none",
"stroke": {
"paint": "#9A0FFF",
"width": 0.125
},
"type": "path"
}
],
"id": "Lines",
"type": "group"
},
{
"elements": [
{
"elements": [
{
"dur": "3s",
"path": "M2,13.125 L2,21.875",
"repeatCount": "indefinite",
"type": "animateMotion"
}
],
"fill": {
"paint": "#438E00"
},
"r": 0.625,
"type": "circle"
},
{
"elements": [
{
"dur": "2s",
"path": "M48,21.875 L48,13.125",
"repeatCount": "indefinite",
"type": "animateMotion"
}
],
"fill": {
"paint": "#DC779C"
},
"r": 0.625,
"type": "circle"
},
{
"elements": [
{
"dur": "2s",
"path": "M48,29.875 L48,39.125",
"repeatCount": "indefinite",
"type": "animateMotion"
}
],
"fill": {
"paint": "#4B9FC8"
},
"r": 0.625,
"type": "circle"
},
{
"elements": [
{
"dur": "3s",
"keyPoints": "0;0.75;1",
"keyTimes": "0;0.375;1",
"path": "M22.75,14.5 Q22,24 6.8,23.5",
"repeatCount": "indefinite",
"type": "animateMotion"
}
],
"fill": {
"paint": "#9A0FFF"
},
"r": 0.625,
"type": "circle"
},
{
"elements": [
{
"dur": "3s",
"keyPoints": "0;0.75;0.995;1",
"keyTimes": "0;0.375;0.675;1",
"path": "M27.25,14.5 Q28,24 45,23.5",
"repeatCount": "indefinite",
"type": "animateMotion"
}
],
"fill": {
"paint": "#FF9803"
},
"r": 0.625,
"type": "circle"
},
{
"elements": [
{
"dur": "5s",
"path": "M5,25 L48,25",
"repeatCount": "indefinite",
"type": "animateMotion"
}
],
"fill": {
"paint": "#008AB0"
},
"r": 0.625,
"type": "circle"
},
{
"elements": [
{
"dur": "3s",
"keyPoints": "0;0.575;1",
"keyTimes": "0;0.375;1",
"path": "M27.25,35.5 Q28,27 43,26.5",
"repeatCount": "indefinite",
"type": "animateMotion"
}
],
"fill": {
"paint": "#3AB1B3"
},
"r": 0.625,
"type": "circle"
}
],
"id": "animatedCircles",
"type": "group"
},
{
"elements": [
{
"cx": 2,
"cy": 10,
"fill": {
"paint": "var(--containerRoot)"
},
"r": 5,
"stroke": {
"paint": "#438E00",
"width": 0.25
},
"type": "circle"
},
{
"cx": 2,
"cy": 25,
"fill": {
"paint": "var(--containerRoot)"
},
"r": 5,
"stroke": {
"paint": "#008AB0",
"width": 0.25
},
"type": "circle"
},
{
"cx": 25,
"cy": 10,
"fill": {
"paint": "var(--containerRoot)"
},
"r": 5,
"stroke": {
"paint": "#FF9803",
"width": 0.25
},
"type": "circle"
},
{
"cx": 48,
"cy": 10,
"fill": {
"paint": "var(--containerRoot)"
},
"r": 5,
"stroke": {
"paint": "#DC779C",
"width": 0.25
},
"type": "circle"
},
{
"cx": 25,
"cy": 40,
"fill": {
"paint": "var(--containerRoot)"
},
"r": 5,
"stroke": {
"paint": "#D64091",
"width": 0.25
},
"type": "circle"
},
{
"cx": 48,
"cy": 40,
"fill": {
"paint": "var(--containerRoot)"
},
"r": 5,
"stroke": {
"paint": "#4B9FC8",
"width": 0.25
},
"type": "circle"
},
{
"cx": 48,
"cy": 25,
"fill": {
"paint": "var(--containerRoot)"
},
"r": 5,
"stroke": {
"paint": "#438E00",
"width": 0.5
},
"type": "circle"
}
],
"id": "LargeCircles",
"type": "group"
}
],
"viewBox": "0 0 50 50"
},
"type": "ia.shapes.svg"
}
],
"meta": {
"name": "root"
},
"type": "ia.container.coord"
}
}

Helpful links:

10 Likes

Based on all the above, we dived in and started building an animated production line for a client. Pretty cool. See Gif attached. Thanks to everyone for the info above.

Animated SVG

2 Likes