Jump to content
Search Community

SVG stroke-dashoffset and pathLength

grimpirate test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

This demo pen illustrates how to animate the stroke-dashoffset attribute of an SVG in both CSS and via a javascript requestAnimationFrame() call (Microsoft Edge doesn't appear to support the pathLength attribute, but that's not particularly relevant). I attempted to animate with Greensock in the following manner:
 

TweenMax.to('path', 6, {strokeDashoffset:0});

 

The only effect this seems to have is causing the curve to blink. I'm unsure if this is a result of using the pathLength attribute to normalize the curve length to 1. I realize this can be solved by DrawSVG plugin, but I'm curious as to why this fails. Thanks.

See the Pen zmOXVQ by anon (@anon) on CodePen

Link to comment
Share on other sites

Seems fine using GSAP.

See the Pen qJWzvM by PointC (@PointC) on CodePen

As you mentioned, getTotalLength() won't work in IE/Edge so I'd highly recommend the drawSVG plugin for this type of work. It's not only easier, but it works around several browser bugs and inconsistencies. 

 

https://greensock.com/drawSVG

https://greensock.com/club

 

Happy tweening.

:)

 

  • Like 3
Link to comment
Share on other sites

@PointC Sorry if I wasn't clear on this point, but the SVG spec defines a pathLength attribute for SVGs. In terms of finding your position along a curve as a percentage, setting its length to 1 makes things very simple. I realize I could achieve the same percentage by utilizing javascript and dividing by getTotalLength(). Isn't there some way that Greensock can SOLELY alter the value as I demonstrated with the javascript code? I'm unsure as to what Greensock is doing behind the scenes, but if both the CSS and javascript approach work, why is Greensock failing? This is my actual question, not really seeking a workaround.

Link to comment
Share on other sites

hmmm... I see what you're asking now.

 

I'm aware of the pathLength attribute, but I've never had a need to use it so I'm not sure I have the answer to that. It certainly seems like setting the pathLength is the problem. If you remove that, everything works fine. You can animate the pathLength attribute with the attr plugin, but dashOffset animation doesn't seem to like it much if that attribute exists.

 

Let's see if we can summon @GreenSock into this thread for some deeper answers about everything under the hood.

Link to comment
Share on other sites

Came up with a procedure that functions in the expected manner, not sure how performant it is though:
 

var path = document.querySelector('path');

TweenMax.set(path, {strokeDasharray: 1});
TweenMax.set(path, {strokeDashoffset: 1});
TweenMax.set(path, {attr:{pathLength: 1}});

TweenMax.to(path, 3, {onUpdate: function(tween) {
	path.style.strokeDashoffset=1-tween.progress();
}, onUpdateParams:["{self}"]});

 

I'm capitalizing on the fact that tween.progress() works on a number from 0 to 1.

Link to comment
Share on other sites

2 hours ago, grimpirate said:

I'm capitalizing on the fact that tween.progress() works on a number from 0 to 1.

 

 

That doesn't take ease into account.

 

TweenMax.to(path, 3, {
  onUpdate: function() {
    path.style.strokeDashoffset = 1 - this.ratio;
  }
});

 

 

But that's not a good way to keep track of a value.

 

var obj = {
  value: 1
};

TweenMax.to(obj, 3, {
  value: 0,
  onUpdate: function() {
    path.style.strokeDashoffset = obj.value;
  }
});

 

 

But why do that when you can tween an attribute?

 

TweenMax.to(path, 3, {
  attr: {
    "stroke-dashoffset": 0
  }
});

 

 

The problem you were having is that you were tweening a CSS property. Check out the autoRound section in the CSSPlugin.

https://greensock.com/docs/Plugins/CSSPlugin

 

This works as expected.

 

TweenMax.to(path, 3, {
  strokeDashoffset: 0,
  autoRound: false
});

 

 

 

  • Like 4
Link to comment
Share on other sites

@OSUblake Thank you very much for the cogent explanation and different methodologies. Still learning all the nuances of Greensock, knowing that one definitely helps. As an aside, I did originally test by modifying the attribute (and tested with your code) but it did not produce the expected result.

See the Pen jeONbp by anon (@anon) on CodePen

.

Link to comment
Share on other sites

You're setting the strokeDashoffset as a CSS inline style, which has precedence over attributes. So you would need to set the attribute if you want to animate the attribute.

 

TweenMax.set(path, {
  attr: {
    "stroke-dashoffset": 1
  }
});

 

 

My personal preference is to use CSS over presentation attributes so I don't run into problems like that.

 

 

 

 

  • Like 4
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...