Jump to content
GreenSock

Joseph Levin

Simple MorphSVG slideshow problem

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

Hello everyone!

 

I'm new to GSAP, and maybe I'm just tired at the moment and not seeing things clearly, but I'm having a lot of difficulty with a simple slideshow using the GSAP MorphSVG plugin.

 

In my pen I have a series of <svg> elements defined which, when the .svgbox the svgs are held in is swiped left or right, morphing is supposed to occur.

 

Basically, on a "touch swipe" (or a "drag" with the mouse), I determine the "firstSVG" and the "secondSVG" that the firstSVG is to be morphed into.

 

This seemed to work perfectly when swiping "left", but when swiping "right", I ran into some issues with the morphs not occurring.

 

This line taken from my pen (under the portion of the code that handles a "right" swipe) seemsto be part of the problem:

firstSVG=$(slideArray[currSlideIndex-1][0]); //index within array should be currSlideIndex rather than currSlideIndex-1. Magically, it works.

 

 

I originally had this line to be:
 

firstSVG=$(slideArray[currSlideIndex][0]);

 

such that the currSlideIndex, firstSVG and secondSVG values were adjusted properly (but the morphs don't act as expected).

 

When I set the code to be as it is currently:
 

firstSVG=$(slideArray[currSlideIndex-1][0]);

 

The firstSVG and secondSVG values come up at times as being the same value (but the morphs work fine in either swipe direction).

 

I'm at a loss and would greatly appreciate any help anyone could provide.

 

 

PS: Clicking on "run pen" will show the pen more as it is expected to be seen. The very bottom of the purple box showing the firstSVG and secondSVG values is cut off in the embedded pen for large browser sizes. Please resize your browser a bit to see the entire content or open it up on Codepen to see what I'm asking about.

 

Thank you very much, in advance.

 

-Joe

 

 

See the Pen MmBpmz by jlevin (@jlevin) on CodePen

Link to comment
Share on other sites

With issues like these its probably best to just set up simple "next" and "previous" buttons so that you can test the basic logic.

Earlier today i saw the swipes working a little and now they aren't. Perhaps you are editing the pen or something.

 

Regardless, I think you want to get away from dynamically setting a firstSVG property and morphing it into a secondSVG. You should have some "base" shape that you morph into other shapes depending on which direction you swipe.

 

Check out this demo below. Press the buttons. I am always animating the circle into the requested shape. Never animating elephant into hippo or hippo into star. Circle is always the target of the tween.

See the Pen aWaJYg?editors=0010 by GreenSock (@GreenSock) on CodePen

 

 

I haven't been able to study your demo in depth so perhaps you have different needs. Feel free to clarify or reduce the demo further to illustrate the issue.

 

 

  • Like 3
Link to comment
Share on other sites

Carl,

 

Thanks for your quick reply.

 

I did not end up changing the pen since I posted my issue; sometimes I've noticed that Codepen pens that have a lot of dependencies need to be reloaded occasionally for everything to work. In either event my embedded pen seems to be working.

 

When you said:

Quote

I think you want to get away from dynamically setting a firstSVG property and morphing it into a secondSVG. You should have some "base" shape that you morph into other shapes depending on which direction you swipe.

 

I checked into the pen you embedded and saw how you were always morphing from the initial svg element path into the other paths.

 

I can retool my pen to use this method and see if things work better without my having to resort to "magic" (as my comment in my pen would suggest).

 

However, because you brought it up about always morphing from the initial svg element's path, I am wondering how my pen was able to get back to showing the original #drupal path's shape if the #drupal path was changed through the morphing process?

 

 

 

Link to comment
Share on other sites

Great question. We anticipated folks wanting to morph back to the original shape sometimes, so MorphSVGPlugin actually saves a copy of the original path data as an attribute on the element itself, and then when you tween to the same target (like .to(yourElement, 1 {morphSVG:yourElement}), it pulls the data from that saved attribute. Does that answer your question? 

  • Like 2
Link to comment
Share on other sites

There's no magic going on. You're just losing track of the index because of this.

currSlideIndex++;	

 

Keeping track of stuff that can be cycled in any direction can be tricky. For something like this, I like to use a circular linked list instead of an array. A linked list is just a collection of objects that point to the object before and after it.

var obj1 = {
  prev: obj3,
  next: obj2,
  data: "foo"
};

var obj2 = {
  prev: obj1,
  next: obj3,
  data: "bar"
};

var obj3 = {
  prev: obj2,
  next: obj1,
  data: "baz"
};

 

So if you were working with obj1, and wanted to get the data from obj3, you could do this.

var data = obj1.prev.data; // "baz"

 

Likewise, if you were working with obj3, and wanted to get the data from obj1, you could do this as it's circular.

var data = obj3.next.data; // "foo"

 

That circular structure could really simplify your demo. You only need to keep track of 1 slide. When there is left of right swipe, you just get the prev or next slide from the current slide. There's nothing else to track or update.

 

See the Pen wdEdYN?editors=0010 by osublake (@osublake) on CodePen

 

  • Like 4
Link to comment
Share on other sites

Hi @Joseph Levin :)

 

Welcome to the forum.

 

Looks like I'm late to the party and many of the GreenSock Greats have already answered, but I'll throw my two cent demo into the mix. Though, with all the geniuses already present in this thread, my two cent demo may only be worth a penny. :D

 

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

 

Happy tweening and welcome aboard.

:)

  • Like 4
Link to comment
Share on other sites

 

Craig,

 

Your demo loops, while I wish mine to end when the last animation has occurred. I modified the code in your pen like so:
 

  if ($(this).index() === 0) {
    i > 0 ? i-- : i = 0;
    morphIt();
  } else {
    i < max ? i++ : i = max;
    morphIt();
  }

 

And that gets me the end points I was looking to hold on to.

 

I realized that if my order changed with the static definition of my array, I'd have to redo all of the indices, and that is no good. So I changed my array to push the data in:

 

        var slideArray = []; //slots in the 1,2,3,4,5 areas may be for future use
        slideArray.push(['#drupal',1,2,3,4,5]);        
        slideArray.push(['#twitter',1,2,3,4,5]);

 

This way, if I delete, add or re-order items I don't have to reindex manually or worry about what comes before or after each item in the array.
 

 

I will push forward (no pun intended) and see what I can get to work.

 

Thank you all for your help today!

 

(Just a side note- I am majorly impressed with how fast I have received responses here in the GS forums, and also how helpful the replies have been!

Y'all and GS rock!)

 

 

 

  • Like 2
Link to comment
Share on other sites

Happy to help. :)

 

It's kind of funny that you changed it to end at the last morph as that's how I originally wrote it and then changed my mind because it seems like almost everyone wants some kind of circular slideshow. I'm glad you found an answer that will work for you. Good luck with your project.

 

Happy tweening.

:)

  • Like 1
Link to comment
Share on other sites

Not me; I don't run around in circles :-D, nah, never.

 

Having a beginning and an end for the series of morphs is what I was trying to do from the beginning.

 

The idea for what I'm working on is that, eventually, once the last morphing tween completes, another timeline will be made to run-

The last shape will fade out and another logo with some buttons that the User will be able to select for more information will fade in (or something like that). That's why I need an "end" point for the set of morphs.

 

Take care!

 

 

 

 

Link to comment
Share on other sites

I just noticed you removed your comment. The reason I suggested a linked list is because I saw your comment about slots. The prev and next pointers is what makes them so flexible and easy to change. I use them all the time to manage large, dynamic collections, like

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

. GSAP uses them too. If you log out a timeline, and you'll see _prev and _next properties that link to other timelines.

 

Ihttps://en.wikipedia.org/wiki/Linked_list

 

 

Link to comment
Share on other sites

I put it in my comment without my fully understanding your modified pen and how you were working it.

After I looked closer at the modified pen, I saw what you were talking about and removed my comment.

 

Your JS is more sophisticated than my own and I have to ponder what you did a bit more; I think I can modify your code to not loop, as I require.

 

Thanks for your help!

 

 

Link to comment
Share on other sites

Just like @PointC, I thought you wanted it to loop. But it's easy to remove as it's not the default behavior.

 

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

 

I wrote that list by hand, which I normally don't do. I wrote several scripts for that, and they make adding and removing items much easier. Doing it manually can sometimes hurt my brain.

 

I can put them up online in a gist or something later on if you want.  

 

Link to comment
Share on other sites

Great discussion guys. Love the solutions.

 

I wrote that list by hand, which I normally don't do.

 

When I first saw @OSUblake linked list I thought "why would he hardcode all that? what a maintenance nightmare" 

Makes a lot more sense if there are some utility scripts to add / remove / shift stuff. 

Would love to see what you use for that.

 

 

Link to comment
Share on other sites

Turns out the issue I was having was solely because of my not doing the better practice of not setting a new path element value into firstSVG.

 

My guess now would be that the reason the following worked in my original pen was that the end morph was being asked to morph firstSVG (as #drupal) into secondSVG (as #drupal) and that the saved path data originally in the #drupal path was being referenced by the morphSVG plugin.

 

 

firstSVG=$(slideArray[currSlideIndex-1][0]);

 

 

Once again, thank you very much for all of your help. I'm good now and rarin' to go get into some more GSAP!

 

 

 

 

  • 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.
×