15

I am playing with Scrollmagic and want to use the effect here: http://scrollmagic.io/examples/advanced/svg_drawing.html

I created a squiggle svg to test it out and need to insert the length of the path in to stroke-dasharray: 2000px; stroke-dashoffset: 2000px;

How can I find the length of the path?

 
function pathPrepare ($el) {
  var lineLength = $el[0].getTotalLength();
  $el.css("stroke-dasharray", lineLength);
  $el.css("stroke-dashoffset", lineLength);
 }

 var $word = $("path#word");
 var $dot = $("path#dot");

 // prepare SVG
 pathPrepare($word);

 // init controller
 var controller = new ScrollMagic.Controller();

 // build tween
 var tween = new TimelineMax()
  .add(TweenMax.to($word, 0.9, {strokeDashoffset: 0, ease:Linear.easeNone})) // draw word for 0.9
  .add(TweenMax.to("path", 1, {stroke: "#33629c", ease:Linear.easeNone}), 0);   // change color during the whole thing

 // build scene
 var scene = new ScrollMagic.Scene({triggerElement: "#trigger1", duration: 200, tweenChanges: true})
     .setTween(tween)
     .addIndicators() // add indicators (requires plugin)
     .addTo(controller);

</script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/ScrollMagic.js"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/plugins/debug.addIndicators.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.2/plugins/animation.gsap.js"></script>

<div style="height: 400px;"></div>
<div class="spacer s2"></div>


<div id="trigger1" class="spacer s0"></div>

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
  viewBox="0 0 841.9 595.3" xml:space="preserve" width="1000px">
<style type="text/css">
 .st0{fill:none;stroke:#000000;stroke-width:12;stroke-miterlimit:10;}
</style>
<path id="word" style="stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 2000px; stroke-dashoffset: 2000px;" fill="none" class="st0" d="M29.7,6.4c-42,87.9,34.6,16.4,96.4,12.1s346,145.7,192.8,110.4S40.8,9.8,66.8,128s179.2,218.1,281.7,122.4
 s10.2-115.2,215-94c465.8,48.3,233.5,90.1,90.2,85.4c-247-8.1,299.2,110.9-259.5,138C46.5,396.6-33.3,439.2,145.8,491
 s171.8-83.6,431.3-18.1s96.4,107.8-79.1,122.4"/>
</svg>

<div style="height: 400px;"></div>
<div class="spacer s2"></div>
R Reveley
  • 1,547
  • 3
  • 14
  • 33

1 Answers1

33

You can use getTotalLength():

The SVGGeometryElement.getTotalLength() method returns the user agent's computed value for the total length of the path in user units.

Here is a demo with your SVG:

var myPath = document.getElementById("word");
var length = myPath.getTotalLength();
console.log(length);
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
  viewBox="0 0 841.9 595.3" xml:space="preserve" width="1000px">
<style type="text/css">
 .st0{fill:none;stroke:#000000;stroke-width:12;stroke-miterlimit:10;}
</style>
<path id="word" style="stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 2000px; stroke-dashoffset: 2000px;" fill="none" class="st0" d="M29.7,6.4c-42,87.9,34.6,16.4,96.4,12.1s346,145.7,192.8,110.4S40.8,9.8,66.8,128s179.2,218.1,281.7,122.4
 s10.2-115.2,215-94c465.8,48.3,233.5,90.1,90.2,85.4c-247-8.1,299.2,110.9-259.5,138C46.5,396.6-33.3,439.2,145.8,491
 s171.8-83.6,431.3-18.1s96.4,107.8-79.1,122.4"/>
</svg>
Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171
  • 4
    Nope, it is not. – Gerardo Furtado Jun 04 '17 at 05:18
  • 4
    It seems [deprecated](https://developer.mozilla.org/en-US/docs/Web/API/SVGPathElement/getTotalLength) on a *path element*. the method has been moved to `SVGGeometryElement`. what exactly is this `SVGGeometryElement` and how does it differ from the term *path element*? – vsync Oct 18 '17 at 23:01
  • 1
    @vsync I suggest you post this as a question, with the `svg` tag, so the SVG specialists can answer you. – Gerardo Furtado Oct 18 '17 at 23:08
  • @vsync I'm not sure what the specific difference is, but be aware that an SVG `path` element is an instance of both. [See this jsfiddle](https://jsfiddle.net/z7Lcq8of/) . I think part of the reasoning is that `getTotalLength` would naturally apply to many other types of SVG elements, including circles, rectangles and so on. – TKoL Nov 02 '17 at 09:42
  • This solution doesn't seem to work as presented. I did find this and I hope it helps others: https://codepen.io/gabriellewee/pen/EZPYmw/ – RonE Jun 05 '20 at 16:35
  • `SVGGeometryElement` is a generalisation of all geometry-producing elements - both `path` and shapes like `circle`, `rect`, `polyline`, etc. This allows you to `getTotalLength()` on any element without conditionals in user code; rather, this is handled by native code. – Engineer Aug 12 '20 at 08:11