Jump to content
Search Community

SplitText menu help

popflier 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 is probably very easy to do but as I am new to Greensock I am trying to figure out exactly how to do this.

 

I have been working on this menu for several days now for my personal website and I'm having some issues. I have a couple things to figure out.

 

1) I can't figure out how to have the menu links on the right (Home, About, Portfolio, Contact) to begin their animation sequence AFTER the background menu has completed it's dropdown animation sequence. I thought perhaps a solution would be to wrap the dropdown menu code inside of a named function and then write an if statement referencing that name, but seeing as how I am not very good with javascript I couldn't figure out how to write that code out.

 

2) I would like to have the right side menu links on hover to animate as well. I can figure out how to animate the text but I also want to have a line (like a strike through) animate through the text. I can't figure out how to add the line into the code.

 

3) Lastly, when a link is clicked I want all links to fade out and the dropdown menu animation to reverse. I have gotten it to reverse the entire sequence on click but I don't know how to get it to only reverse a portion of that sequence and not the full thing.

 

Any help with any of these questions would be wonderful! I'm about to pull my hair out.

 

Thanks,

Nicole

See the Pen WKvWRo by popflier (@popflier) on CodePen

Link to comment
Share on other sites

Thanks for the demo. 

 

To answer the first question, the reason the staggerFromTo() animation on the text was happening too early was because you had the "complete" function in the place of the position parameter.

 

bad: complete is in the wrong place so the position gets set to an absolute time of 0

tl.staggerFrom(chars, .42, {opacity: 1, scale:.01, y:0, rotationY:360,  ease:Back.easeOut}, .04, complete);

 

good: using the position parameter of "+=0" means add this 0 seconds after the previous animation has ended. You normally don't need position of "+=0" because its the default value, hower since you are using the onCompleteAll parameter, you need to put something in for the position

tl.staggerFrom(chars, .42, {opacity: 1, scale:.01, y:0, rotationY:360,  ease:Back.easeOut}, .04, "+=0", complete);

 

I added a background color to the menu so that its easier to see what is happening

 

See the Pen wxKewE?editors=0110 by GreenSock (@GreenSock) on CodePen

 

 

  • Like 4
Link to comment
Share on other sites

Just to add a little more to @Carl's excellent advice and information:
 

//You have this on line 8
 menuLinks = $('#menuLinks')

// then you're using it for your each() loop on line 32
menuLinks.each(function(index, element){

 

However, that is a class, not an ID so you need to change your variable to

menuLinks = $('.menuLinks')

 

If you make that switch, you'll be able to target those links in your animation. The other issue is you are setting some hover colors in your CSS, but your timeline tweens are trying to animate color. That won't work correctly. I'd recommend removing the hover color in the CSS and letting GSAP take care of that for you.

 

If you want the strike-though to animate, you'll have to add an element to each of those <li> tags. It could be a pseudo element or an absolutely positioned div and animate its width on hover. Here's a fork of your pen with some changes. I added a simple opacity to the hover timeline so you can see that it is working. You'll have to decide what to do about the hover colors. I also commented out line 32 as I had no idea what it should be animating. It's targeting child menuLinks of the menuLinks, but there are none so I wasn't sure why it was there. 

 

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

Hopefully that helps. Happy tweening.

:)

 

  • Like 3
Link to comment
Share on other sites

Thanks so much to both of you for your help. I really appreciate it!  I had been changing the names of classes and ID's to different things and missed getting that one  labeled correctly.

 

I could use some more help because I do not understand why I can get the links on the left to work (sort of the way I want) but that same logic won't work on the main menu.

 

I have tried 50 different ways to get this to work.

 

I have gotten the links on the left to hover correctly though I'd like to add in some actual tweening here to make it slightly more interesting. I have also gotten the left links to work when clicked correctly. (When any link is clicked the other links fade.)

 

I have been trying to get the main menu links on the right to work on hover using Greensock instead of CSS, as suggested above. I tried to apply the same code I used for the left links and changed the classnames but that isn't working. I tried using code from a couple of other Greensock pens but that didn't work either. I have been trying to get the right menu code that's on the pen to work first before tackling more advanced animations.

 

Final Goal

1)  on hover I am trying to have the right side links each animate the same way the links first appear on load (each letter spinning in order from left to right.) I also want to change their color on hover.  Just like with the links on the left the remaining links that the mouse isn't over would fade out a bit.

 

2) on click I am wanting  the link that is clicked to keep the same color that it would turn on hover and I would like there to be a very small delay before having the entire menu background to reverse the same way it first came in. Does that make sense?

 

Any tips or info anyone can provide on any of this would be grateful. I've been working on this for 4 hours today and 5 hours yesterday trying different things.

 

Thanks!

Here's a codepen I'm working on.

See the Pen KBdRXW?editors=1010 by popflier (@popflier) on CodePen

 

Link to comment
Share on other sites

I'm not sure I follow everything correctly. You said you wanted the main links to display the same initial SplitText animation on hover? Since those links have already animated into view on load, how did you want them to have the same animation? Should the letters disappear and animate in again? Most anything is possible. I'm just not sure what should be happening here.

 

Changing color on hover: are you targeting the <li> or the <a>? If you're creating a timeline in an each() loop for those .menuLinks you'll want to target the <a> element. So something like this:

tl.to($(this).find("a"), 1, {color:newColor}, 0)

 

I also didn't see any timelines or animations for those main links in your new pen. Maybe you're still working on it? If you can start putting those timelines together with what you want to happen we can most likely point you in the right direction. 

 

Happy tweening.

:)

 

  • Like 3
Link to comment
Share on other sites

Okay, no problem. I will try and clarify. I'll break it down into sections. So let's focus on just the right main menu for this post. I've tried to get the hover function on the main menu links to do the animation that I am wanting. Take a look at this other pen I made. Do you see how when you put your mouse over the menu ALL of the links animate and not just the one that you placed your mouse over? I can't seem to figure out how to target each link individually.

 

As an example of what I am wanting,  I just want it so when you place your mouse over "Home" only the "Home" letters animate and when you move your mouse off of "Home" the "Home" letter animation plays in reverse. The idea is that when each letter flips around it reveals the new color and when your mouse is off of that link it reverses the animation to reveal the white color again.

 

I've looked at a thousand pens and tried all sorts of different code but I can only seem to target all of the links at once. I was able to get the links on the bottom left to target individually on hover on another pen I had but when I applied that same logic to the main menu on the right it didn't work. The only difference between the two is that I am using splitText on the main menu and I'm not using it on the bottom left links. (yes, the bottom left links are not working right now as I just want to focus on the main menu on this post.)

 

Can someone please help me with what I am doing wrong?

 

Thanks in advance for any help anyone can provide.

 

See the Pen BPLZoQ by popflier (@popflier) on CodePen

 

Link to comment
Share on other sites

The problem is you're targeting all the characters in each hover. The text is already split into divs so you could use an each() loop to create a timeline for each link and play/reverse that on hover, but target the divs in that <li> instead of the chars. Is this what you need it to do?

 

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

 

  • Like 3
Link to comment
Share on other sites

30 minutes ago, PointC said:

The problem is you're targeting all the characters in each hover. The text is already split into divs so you could use an each() loop to create a timeline for each link and play/reverse that on hover, but target the divs in that <li> instead of the chars. Is this what you need it to do?

 

YES!!!  This is what I've been trying to do for over 10 hours. Thank you!! I thought I was targeting each link by looking for the index of the class ".menulinks," but apparently I was wrong.

 

$(".menuLinks").hover(function(over,out) {
var i = $(this).index(".menuLinks");

 

Can you answer a couple of questions for me please so I can understand a bit better what you've done?

 

1) Can you explain why the "?" and ":" are needed here?

tl.reversed() ? tl.play() : tl.reverse();

 

2)Why do you need to pass in makeItWork twice into the .hover?

function onComplete() {
  $(".menuLinks").each(function(i, element) {
    var tl = new TimelineMax({ paused: true, reversed: true });
    var targets = $(this).find("div");
    tl.staggerTo(targets, 0.75, { color: "#731012", rotationY: 360, ease: Back.easeOut }, 0.04);

    $(element).hover(makeItWork, makeItWork);

    function makeItWork() {
      tl.reversed() ? tl.play() : tl.reverse();
    }
  });

 

Thanks so much for all of your help. I really appreciate it! I am going to work on the other links and see about getting them to work how I want.

 

Link to comment
Share on other sites

The "?" and ":" are part of the ternary operator. It's basically a shorthand if/else

 

// ternary 
tl.reversed() ? tl.play() : tl.reverse();

// if/else
if ( tl.reversed() ) {
   tl.play();
} else {
   tl.reverse();
}

 

More info:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator

 

Calling the makeItWork() function twice isn't absolutely necessary. It's just a habit of mine. The jQuery hover() method is shorthand for mouseenter and mouseleave so it takes two handlers. In this particular case we want the same function called for both, but you may want different functions called for each event. I'm just in the habit of putting them both in even when they're the same, but in this case it would work fine with one.

 

More info:

https://api.jquery.com/hover/

 

Hopefully that helps. Happy tweening.

:)

 

 

  • Like 3
Link to comment
Share on other sites

I've figured out how to get the secondary links to load  the way that I want them to and I've gotten both the main and secondary hover states to work how I want them. However, I can't figure out the click events and right now I have the left links on one pen working and the main links on another pen working but I can't get them to work together in the same pen. I know it's something to do with the onComplete function and probably the naming conventions but I feel like I've tried all possibilities. (yes, I have literally been sitting here for the last 7 hours working on this. Still in my PJ's and it's 5pm!)

 

My questions: How to get the these to work in the same pen and how to get the click events to work.

For the click events I am trying to create something similar to this website where the close button that I have yet to put in but is currently called "button here" would close out the entire menu and revert the navMenu animation as it initially loaded. Then if a link was clicked all of the links would fade out so that I could load in the appropriate page.

 

https://cuberto.com/about/

 

Any direction on how I can achieve this is warmly welcomed!

 

This is the pen for the left side links:

See the Pen ?editors=1010 by popflier (@popflier) on CodePen

 

This is the pen for the main right side links:

See the Pen qyaVVW by popflier (@popflier) on CodePen

 

Link to comment
Share on other sites

For both sets of link hovers to work, you can add both each() loops to your onComplete function.

 

After you animate the social links by character you revert() them and split by word. I'm not sure if this is actually necessary as they're each individual words anyway, but I left it the way you had it.

 

Your click handlers have a couple issues. The first is each time you click, you're adding time to the tl timeline for that element. You'll probably want to create a new timeline in that handler.  The second is the tween that removes the menu. You have it set up with a staggerFrom tween, but there are two vars for a fromTo() tween. It doesn't have to be a stagger since there is only one element and you don't need a fromTo() tween if all you're doing is making the menu exit. Since you're exiting you'll also want an easeIn instead of an easeOut.

 

// bad
tl.staggerFrom(navMenu, 1, { y: -450 }, { ease: Back.easeOut.config(1.2), y: 0 });

//good
.to(navMenu, 1, { y:-450 , ease: Back.easeIn.config(1.2)});

 

I created a separate timeline in the mainLinks click handler that sends the menu back up, but I left the socialLinks click handlers broken so you can see the difference.

 

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

Hopefully that's what you needed. Happy tweening.

:)

 

 

Link to comment
Share on other sites

Not sure if this is bad etiquette to ask a question on another thread but as it was on the same topic I thought It would save the clutter.

 

I was wondering how you would use this in combo with what you helped me with yesterday @PointC. The thing that confuses me is how to make the split text trigger via it's parent object. i.e. for each grey box on hover, trigger it's children eg the blue div & the split text together.

 

I feel it's this part that's the problem, as it's referring to the title, not the grey box.

 

$(element).hover(makeItWork2, makeItWork2);

 

See the Pen rrMRBd?editors=1010 by smallio (@smallio) on CodePen

 

 

Thanks, 

Smallio

Link to comment
Share on other sites

You can add the SplitText animation to the timeline that animates the blue box. That timeline is the same as creating one manually. You can add whatever elements you want, use the position parameter, add callbacks etc. The each() method just does the heavy lifting by looping through and easily targeting the child elements. 

 

So, in your example, you can create a a new SplitText from the <h2> in each project tile. You then add that SplitText stagger to the end of the timeline that animates the blue box into view and you'll be all set.

 

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

Hopefully that helps. Happy tweening.

:)

 

  • Like 3
Link to comment
Share on other sites

Happy to help. I'm glad to hear things are starting to click for you. As long as you're having fun with each() loops, here's a bit more info. All the animations don't have to be the same. Sometimes you may want that, but you may also want some variety. You can still have each() do the heavy lifting for you. Using each element's index allows you to create different animations.

 

Here's a version where you can use the index and each 'y' position animation is different.

 

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

 

You can also create entire animations and/or properties in arrays and plug those into the tweens based on the index. Here's a version showing the basics of how that's done.

 

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

 

Hopefully that gives you some more ideas about what can be done with loops. I'm glad you're now obsessed with GSAP and moving from lurker to a more active status. It really does get more fun as you increase your forum participation.

 

Have fun and happy tweening.

:)

 

 

  • Like 5
  • Thanks 1
Link to comment
Share on other sites

On 7/19/2018 at 5:49 PM, PointC said:

<<For both sets of link hovers to work, you can add both each() loops to your onComplete function.>>

Okay.  I've looked through your code and that makes sense to me how you set it up.

 

On 7/19/2018 at 5:49 PM, PointC said:

 

<<After you animate the social links by character you revert() them and split by word. I'm not sure if this is actually necessary as they're each individual words anyway, but I left it the way you had it.>>

 

I did it because it's the only way for the code to make sense to me. After spending a stupid amount of money and 3 months this year in a full-time full stack certificate program I realized that JS doesn't really make sense to me unless I write it in a weird and redundant way.

 

On 7/19/2018 at 5:49 PM, PointC said:

<<Your click handlers have a couple issues. The first is each time you click, you're adding time to the tl timeline for that element. You'll probably want to create a new timeline in that handler.  The second is the tween that removes the menu. You have it set up with a staggerFrom tween, but there are two vars for a fromTo() tween. It doesn't have to be a stagger since there is only one element and you don't need a fromTo() tween if all you're doing is making the menu exit. Since you're exiting you'll also want an easeIn instead of an easeOut.

 


// bad
tl.staggerFrom(navMenu, 1, { y: -450 }, { ease: Back.easeOut.config(1.2), y: 0 });

//good
.to(navMenu, 1, { y:-450 , ease: Back.easeIn.config(1.2)});

 

I created a separate timeline in the mainLinks click handler that sends the menu back up, but I left the socialLinks click handlers broken so you can see the difference.>>

 

Thanks for leaving them broken. It allowed me to mess with them a bit. Your code and your information make sense to me so thank you.

 

On 7/19/2018 at 5:49 PM, PointC said:

 

<<Hopefully that's what you needed. Happy tweening.

:)>>

 

It's sooooooo close but not exactly what I'm wanting. I think if I knew how to do one last thing that I could get the rest of it to work the way I wanted. Can you answer this question for me?

 

How can I target all of the other links in the menus aside from the one being clicked on? For example, if you just look at the social media links right now, when you click on a link the color of that link clicked turns to #cd2026. Let's say I clicked on "Dribble." How can I change the color of ALL of the OTHER links in the same menu (like Facebook, Twitter, and Behance) when the Dribble link is clicked? I'd like to have it setup so that regardless of what link is clicked in that menu the clicked link turns to the dark red color and all of the other links turn to a different color. My problem is that I cannot figure out how to target all of the other links ? I tried using an index and doing targets and targets but that didn't work for me.  I am ultimately trying to get the main menu on the right to exit exactly like the menu on this website does when a main menu button link is clicked or the Close button is clicked. (Im doing my social media links differently in how they work on click) : https://cuberto.com/about/

 

The pen that I have been working on is here: Thanks in advance for any help. You've been wonderfully helpful and I greatly thank you!

 

See the Pen vaggeo?editors=1010 by popflier (@popflier) on CodePen

On 7/19/2018 at 5:49 PM, PointC said:
On 7/19/2018 at 5:49 PM, PointC said:

 

 

 

Link to comment
Share on other sites

A fairly simple way to do that would be adding one tween to that timeline.

 

// this targets all socialLinks including the one you just clicked on
exitSocialTL.to($(".socialLinks a div"), 0.55, {color:"yourColorHere"});

// this overwrites the above tween to only target the one you clicked on
exitSocialTL.staggerTo(targets, 0.55, {color: "#cd2026"},.05, 0);

 

Does that make sense?

  • Like 2
Link to comment
Share on other sites

18 hours ago, PointC said:

A fairly simple way to do that would be adding one tween to that timeline.

 


// this targets all socialLinks including the one you just clicked on
exitSocialTL.to($(".socialLinks a div"), 0.55, {color:"yourColorHere"});

// this overwrites the above tween to only target the one you clicked on
exitSocialTL.staggerTo(targets, 0.55, {color: "#cd2026"},.05, 0);

 

Does that make sense?

 

Ok. So you're using the hierarchy to change the colors. I knew that worked with CSS, but I guess I didn't know that it worked the same with JS. Meaning, you make a change to something and then any changes you make to that same thing further in the script overrides the previous code. Yes, that makes sense...thank you!

  • Like 1
Link to comment
Share on other sites

On 7/20/2018 at 4:28 PM, PointC said:

 

 

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

 

 

 

 

@PointC One last question on the whole "this" topic. 

 

Say you wanted to have three different pictures that are fullscreen in the background, none of them are showing to start but on the hover of each grey box it shows the correct picture correlating to box 1, 2 and 3 . How would one go about that as they are then targeted outside?

 

Cheers,

Smallio

Link to comment
Share on other sites

I'm not sure I follow. Do you mean a picture as the background of the grey box or did you mean a background image for the entire page behind the grey boxes? Both are certainly possible. I just want to make sure which you needed.

 

Happy tweening.

:)

 

  • Like 1
Link to comment
Share on other sites

Hey @smallio :)

 

Okay, I re-read your question and I'm fairly certain you meant a background image for the page. The answer to that is you use the index of the loop to target the elements that are not part of the jQuery each() loop or $(this). Accessing that index number is quite powerful. Here's one way to do it.

 

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

Hopefully that's what you needed. Happy tweening.

:)

 

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

I think I'm learning more in this thread than I did in 3 months of coding bootcamp.  ;)

You've been so wonderful with your time and I understand if you will need to just cut me off from asking questions. That being said...I have a couple more questions about the menu I'm trying to code. However, I also have a question pertaining to the pen you did above for @smallio.

 

For the pen, my question is about the "part 2" in the code. You have used

tl.add("part 2");

 

And then called "part 2" again at the end of the timeline tween code:

tl.to(theTarget, 0.5, { backgroundColor:colors[i], ease:Linear.easeNone }, "part2");
  tl.staggerTo(splitText.chars, 0.75, animations[i], 0.04, "part2");

 

So you can use the .add to literally add tweens to the timeline? Does this content get initiated after the previous content completes? For example, if I had a tween that said move box  to x:0, y:0. Then I used the tl.add and then had a second tween on the same timeline that said move box  to x:10, y:20. Would the box complete it's movement to x:0, y:0 and THEN do it's movement to x:10, y:20 because I used the .add?

 

Can you explain why you are calling an ID that doesn't exist in the HTML or CSS here?  There is an ID that is #image1, #image2, #image3 but there isn't an ID that is just "#image" and that's confusing to me.

tl.to("#image" + (i+1), tl.duration(), {opacity:1}, 0);

 

I'll ask the question pertaining to my menu in a separate post to not confuse the two.

 

Thanks!

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