Jump to content
Search Community

Animating multiple SVG paths on multiple elements at different times

Forrest 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

Hi guys,

 

I have 4 SVG symbols on my website. As the user scrolls, the SVG paths are animating in. I have this working but I feel that there is a better way of doing it. Here is my code:

 

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


    var $motion1 = $("path.motion1");
    var $motion2 = $("path.motion2");
    var $motion3 = $("path.motion3");
    var $motion4 = $("path.motion4");
    var $ui = $("path.ui");
    var $ui2 = $("path.ui2");
    var $ui3 = $("path.ui3");
    var $ui4 = $("path.ui4");
    var $design1 = $("path.design1");
    var $design2 = $("path.design2");
    var $design3 = $("path.design3");
    var $design4 = $("path.design4");
    var $strat1 = $("path.strat1");
    var $strat2 = $("path.strat2");
    var $strat3 = $("path.strat3");
    var $strat4 = $("path.strat4");
    var $strat5 = $("path.strat5");
    var $strat6 = $("path.strat6");


    // prepare SVG
    pathPrepare($motion1);
    pathPrepare($motion2);
    pathPrepare($motion3);
    pathPrepare($motion4);
    pathPrepare($ui);
    pathPrepare($ui2);
    pathPrepare($ui3);
    pathPrepare($ui4);
    pathPrepare($design1);
    pathPrepare($design2);
    pathPrepare($design3);
    pathPrepare($design4);
    pathPrepare($strat1);
    pathPrepare($strat2);
    pathPrepare($strat3);
    pathPrepare($strat4);
    pathPrepare($strat5);
    pathPrepare($strat6);


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


    // build tweens for each SVG
    var tweenMotion = new TimelineMax()
    tweenMotion
      .add(TweenMax.to($motion1, 1, {strokeDashoffset: 0, ease:Linear.easeNone}))
      .add(TweenMax.to($motion2, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
      .add(TweenMax.to($motion3, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
      .add(TweenMax.to($motion4, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
      ;


    var tweenUI = new TimelineMax()
    tweenUI
      .add(TweenMax.to($ui, 1, {strokeDashoffset: 0, ease:Linear.easeNone}))
      .add(TweenMax.to($ui2, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
      .add(TweenMax.to($ui3, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
      .add(TweenMax.to($ui4, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
      ;


    var tweenDesign = new TimelineMax()
      tweenDesign
        .add(TweenMax.to($design1, 1, {strokeDashoffset: 0, ease:Linear.easeNone}))
        .add(TweenMax.to($design2, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
        .add(TweenMax.to($design3, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
        .add(TweenMax.to($design4, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
        ;


    var tweenStrat = new TimelineMax()
       tweenStrat
        .add(TweenMax.to($strat1, 1, {strokeDashoffset: 0, ease:Linear.easeNone}))
        .add(TweenMax.to($strat2, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
        .add(TweenMax.to($strat3, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
        .add(TweenMax.to($strat4, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
        .add(TweenMax.to($strat5, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
        .add(TweenMax.to($strat6, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
        ;


      // build 4 scenes for each SVG
      var scene01 = new ScrollMagic.Scene({
        triggerElement: '#index-services',
        duration: '90%',
        triggerHook: 1,
        tweenChanges: true})
        .setTween(tweenMotion)
        .addTo(controller);

      var scene02 = new ScrollMagic.Scene({
        triggerElement: '.service_01',
        duration: '90%',
        triggerHook: 1,
        tweenChanges: true})
        .setTween(tweenUI)
        .addTo(controller);

      var scene03 = new ScrollMagic.Scene({
        triggerElement: '.service_02',
        duration: '90%',
        triggerHook: 1,
        tweenChanges: true})
        .setTween(tweenDesign)
        .addTo(controller);

      var scene04 = new ScrollMagic.Scene({
        triggerElement: '.service_03',
        duration: '90%',
        triggerHook: 1,
        tweenChanges: true})
        .setTween(tweenStrat)
        .addTo(controller);

I've added an individual class to each path I want to animate, I grab the length and then animate the strokeDashoffset to 0.

 

This works fine. I'm just curious to know whether there is a better way. I tried using a for each loop but that ended up with issues with animations restarting when they hit the next trigger.

 

I tried having an individual class for all the paths but then there were timing issues as the length would be different for all of them.

 

Is it really necessary for me to have 4 scenes for 4 SVG symbols? I think it's ok as they are completely different symbols, so in a way it makes sense. It's mainly the 4 timelines I have. I need to animate the 4 SVGs completely individually, so again, the 4 timelines kind of made sense.

 

If anyone can simplify this code I'd be very interested to see.

 

Thanks guys.

Link to comment
Share on other sites

Hi Forrest  :)

 

Welcome to the GreenSock forum.

 

I don't know why you couldn't add a class to those elements, loop through them and then using GSAP's set() method you could set the dasharray and dashoffset. More info about set():

 

https://greensock.com/docs/#/HTML5/Animation/TweenMax/set/

 

You could also save a lot of code by putting your tween targets into an array rather than using multiple tweens that start at time 0: 

// this 
var tweenMotion = new TimelineMax();

    tweenMotion
      .add(TweenMax.to($motion1, 1, {strokeDashoffset: 0, ease:Linear.easeNone}))
      .add(TweenMax.to($motion2, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
      .add(TweenMax.to($motion3, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
      .add(TweenMax.to($motion4, 1, {strokeDashoffset: 0, ease:Linear.easeNone}), 0)
      ;

// becomes this     
var tweenMotion = new TimelineMax();
tweenMotion.to([ $motion1, $motion2, $motion3, $motion4 ], 1, {strokeDashoffset: 0, ease:Linear.easeNone});

If you have other questions about your project, we'd like to see a CodePen demo so we can edit your code and get you the best answers. More info about that:

 
 
Happy tweening.
:)
  • Like 2
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...