Jump to content
Search Community

Optimizing use of the modifiers plugin

pragdave test
Moderator Tag

Recommended Posts

I'm animating a drawing that contains various regular shapes (polygons, circles, ellipses, etc). I join pairs of these shapes with a line. The line acts as if it joins the centers, but it is cropped to a few pixels shy of the edge of each shape, and an arrowhead is added.

 

I have all the geometry worked out, so that given two shapes at arbitrary positions I can connect them with the line.

 

When I animate the shapes, I need the line to animate too. I can't simply linearly interpolate the before and after endpoints, because the cropping means the endpoints don't follow a straight line.

 

Instead, I want to use the modifiers plugin to intercept changes to the x and y attributes of the two shapes, and redraw the connection line. This is what the spring connector demo does.

 

However, if both shapes are moving, this means I redraw the line four times for each update cycle.

 

So far my best guess is to use the modifiers to build a list of the new coordinates and then have the onUpdate callback draw the line based on them. But this seems kinda hacky. 

 

Is there a better way?

 

 

Cheers

 

 

Dave

See the Pen vKdGAy by osublake (@osublake) on CodePen

Link to comment
Share on other sites

Why are you trying to optimize it? JavaScript is fast. SVG is slow.

 

1 hour ago, pragdave said:

However, if both shapes are moving, this means I redraw the line four times for each update cycle.

 

That's really not how it works. The line redraws at the end of all your updates. That said, I like using SVGPoints with polylines/polylines instead of updating a <line>. Move your mouse around.

 

See the Pen c199810fd80ff33d1cf34f67dfa275aa by osublake (@osublake) on CodePen

 

Points can be animated too.

 

See the Pen yakOjY by osublake (@osublake) on CodePen

 

1 hour ago, pragdave said:

So far my best guess is to use the modifiers to build a list of the new coordinates and then have the onUpdate callback draw the line based on them. But this seems kinda hacky. 

 

Doesn't sound hacky, but why not just updated everything inside a single onUpdate? Not sure why are you using the modifiers plugin based on your description? A demo might help to understand your problem better.

 

 

  • Like 4
Link to comment
Share on other sites

I'm animating a presentation. It'll runs for 30-40 minutes. Objects come and go: there may be 4 on display at one time, and 400 a minute later. In all I'm guessing there may be a couple of thousand SVG elements in total. So I don't keep them all lying around: I remove them when I get the chance.

 

Maybe a couple of hundred elements are connected by the lines I'm talking about. Most of the time, these elements are not on screen, and when they are, they are mostly stationary.

 

So... If I was to redraw every connecting line on every onUpdate for the entire 30 minutes, I'm guessing my browser would melt. It's already spinning fans.

 

Instead, by using the modifiers plugin, I get called only when one of my connected elements moves. If none of them moves for 10 minutes, then I'm not doing 200x4x60, or 48,000, calculations of connecting lines per second for the entire presentation. And those calculations involve a fair amount of geometry, bezier curves, and so on. So running them only when absolutely necessary seems like a good idea. SVG might be slow, and JavasScript might be fast, but when you make JavaScript do so much unnecessary work, it becomes the limiting factor. 

 

Frankly, I found your response to be dismissive and somewhat off-putting.  You took the time to create a couple of pretty examples, but they had nothing to do with my problem: performing a calculation the minimum number of times when something moves.

 

Let's kill this thread: no need for anyone to reply.

Link to comment
Share on other sites

34 minutes ago, pragdave said:

Frankly, I found your response to be dismissive and somewhat off-putting.

 

That wasn't my intent. I was genuinely trying to help you.

 

34 minutes ago, pragdave said:

You took the time to create a couple of pretty examples, but they had nothing to do with my problem:

 

Those demos show how you can speed up drawing lines using SVGPoints as it might require less updating i.e. setting attributes.

 

34 minutes ago, pragdave said:

performing a calculation the minimum number of times when something moves.

 

That was not clear to me in your original post. You just showed that spring demo. The way I set those up is with the modifiers plugin is to run infinitely. The only reason I did that was to demonstrate how the modifiers plugin works. Normally I would have just used a ticker to animate something like that.

 

 

  • Like 5
Link to comment
Share on other sites

And after reading your reply, I guess you're trying to do something similar to this? One problem with using the modifiers plugin for points is that calculations have to be done in separate x and y functions. I think it would be easier to do all the calculations in an onUpdate or ticker for any elements that have moved.

 

image.png.bc6f55ece5f72cdb232ec71eaa8e723b.png

 

 

 

  • Like 1
Link to comment
Share on other sites

14 hours ago, pragdave said:

there may be 4 on display at one time, and 400 a minute later. In all I'm guessing there may be a couple of thousand SVG elements in total

Seems like that's your performance cap no matter what related JS calculations you're doing. Most likely it'd be better to use canvas for having that many things on a screen at once. 

 

Can you please create a minimal demo or diagram of your situation? Perhaps we could make more relevant suggestions then.

 

14 hours ago, pragdave said:

Frankly, I found your response to be dismissive and somewhat off-putting.  You took the time to create a couple of pretty examples, but they had nothing to do with my problem: performing a calculation the minimum number of times when something moves.

I didn't get that vibe at all from Blake's answer. He suggested alternative ways of using lines in SVG that may be more performant, that's all. 

 

And without seeing how you're doing calculations or even how your elements are set up it's pretty hard to give pointed help on how to improve those calculations.

  • Like 3
Link to comment
Share on other sites

18 hours ago, pragdave said:

Frankly, I found your response to be dismissive and somewhat off-putting.

We really pride ourselves around here on maintaining a friendly, positive, non-snarky tone (unlike many other forums). Very sorry to hear that Blake's response came across as dismissive - I totally didn't see it that way. He's a legend around here and he even provided some demos that I thought could be very useful for your scenario but maybe I misunderstood what you were after. 

 

I see your point about modifiers potentially causing 4 redraws for each tick on each line. If I were in your shoes, I'd totally do what Blake was suggesting and use generic points almost like proxies - animate only those values (coordinates) and then in a single onUpdate (or tick listener) do all your redrawing in one fell swoop for all lines/shapes. I'm pretty confident that'd perform the best.

 

As others have said, if you really want top-notch performance my guess is that the SVG rendering lay is BY FAR the biggest bottleneck, so perhaps consider using something like PixiJS or raw canvas or something like that. In almost every case I've seen, GSAP code is only a tiny fraction of the overall load on the device. When things get jittery, it's typically like 98%+ graphics rendering and only 0.1-2% animation code execution (CPU load). 

 

Thanks for being a Shockingly Green member, @pragdave. Is there anything else we can do to help? 

  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...