Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
codebloo

Reveal Image - alternating entrances left/right/left/right

Go to solution Solved by PointC,

Recommended Posts

Hi! Thank you so much for this incredibly valuable forum. I've learned a lot lurking already.
I am having trouble animating an alternating entrance point based on class name.
 

In my example all 3 images "reveal" from left to right, but I'd like them to alternate so the images ON the right reveal from the right.

Each block has a class of either "reveal-image-left" or "reveal-image-right" that could be leveraged instead if the "reveal-image" selector that's being used across all 3 images now. (The HTML is identical for each block  with the alternating positioning done with Flexbox)

 

I cannot for the life of me figure this out and I'm not fluent enough in GSAP/Js to get this over the finish line. 

Many thanks for your help!

See the Pen jOVoQxZ by codebloo-the-lessful (@codebloo-the-lessful) on CodePen

Link to post
Share on other sites

That shouldn’t be too hard.

First thing that comes to my mind is using gsap.to() ist’s not important from where an element is starting it“s just moved to the (same) coordinate x or left in your case. 
you could either built a timeline that is controlled by a ScrollTrigger  or attach a  ScrollTrigger to each element which would be probably the easier way. 
 

If those hints don‘t help, I or others surely will help in more detail. Good luck. 

Link to post
Share on other sites
2 hours ago, iDad5 said:

That shouldn’t be too hard.

First thing that comes to my mind is using gsap.to() ist’s not important from where an element is starting it“s just moved to the (same) coordinate x or left in your case. 
you could either built a timeline that is controlled by a ScrollTrigger  or attach a  ScrollTrigger to each element which would be probably the easier way. 
 

If those hints don‘t help, I or others surely will help in more detail. Good luck. 

Hi thanks for your suggestions!We're on the same page. I have a ScrollTrigger timeline built (in my codepen example above) it's the batch alternating factor that has me stuck since it needs to be tied to the class but the classes also alternate. Fingers crossed for a code solution :)

Link to post
Share on other sites

See the Pen WNoBqVJ?editors=1111 by mdrei (@mdrei) on CodePen

 

Not the most elegant solution, but I guess it points in the right direction.

 

(I had trouble at first getting the elements with querySelectorAll() - it was due to saving and rerun errors in codePen, but I thought that it might be due to the script running before the DOM was ready. So I encapsuled it in a function, as that's generally not a bad idea I left it that way and registered the plugin too)

 

As your code essentially  made a timeline with a scrollTrigger for each element I decided that I just select the element inside a left container and do the same wit those inside a left container. I did it by copying, you can make that more elegant, but that's up to you.

Edited by iDad5
Added Explanation
  • Like 1
Link to post
Share on other sites

 

Hey @codebloo - welcome to the forums.

 

There are various ways to this.

Which would work best for you depends on a) how complex you want things to become in the end and b) what is best for you to wrap your head around.

 

You could e.g. create different arrays/nodelists for left and right and loop over each of them and create everything individually (as iDad5 showed above) or you could leave things as you have them right now and include an if condition in your loop to check for a class on your image and create everything individually for the different conditions or (and in a simple scenario as your demo this would probably be most convenient) use a ternary operator for your xPercent value that does the same conditional check as above - just right at place and with less code.

 

xPercent: element.classList.contains('this-class') ? -100 : 100

 

 

53 minutes ago, codebloo said:

Fingers crossed for a code solution :)

 

This could be a nice test-case to become more fluent with JS, so I will leave that up to you ;) 

Give it a shot and let us know if you run into a problem with the implementation and we'll be glad to guide you in the right direction.

 

On a sidenote: 

It is recommended to use the new syntax. Migrating your code is not that hard and could save you some troubles further down the line.

 

  • Like 4
Link to post
Share on other sites
3 minutes ago, akapowl said:

It is recommended to use the new syntax

Oh yeah, I've seen that too, forgot to mention.

Link to post
Share on other sites
6 hours ago, akapowl said:

 

Hey @codebloo - welcome to the forums.

 

There are various ways to this.

Which would work best for you depends on a) how complex you want things to become in the end and b) what is best for you to wrap your head around.

 

You could e.g. create different arrays/nodelists for left and right and loop over each of them and create everything individually (as iDad5 showed above) or you could leave things as you have them right now and include an if condition in your loop to check for a class on your image and create everything individually for the different conditions or (and in a simple scenario as your demo this would probably be most convenient) use a ternary operator for your xPercent value that does the same conditional check as above - just right at place and with less code.

 


xPercent: element.classList.contains('this-class') ? -100 : 100

 

 

 

This could be a nice test-case to become more fluent with JS, so I will leave that up to you ;) 

Give it a shot and let us know if you run into a problem with the implementation and we'll be glad to guide you in the right direction.

 

On a sidenote: 

It is recommended to use the new syntax. Migrating your code is not that hard and could save you some troubles further down the line.

 

thanks for your help. 
I understand most of what you said in theory but not in practice.
Where would I put the xPercent: etc line?
thanks again!

Link to post
Share on other sites
7 hours ago, iDad5 said:

 

 

 

Not the most elegant solution, but I guess it points in the right direction.

 

(I had trouble at first getting the elements with querySelectorAll() - it was due to saving and rerun errors in codePen, but I thought that it might be due to the script running before the DOM was ready. So I encapsuled it in a function, as that's generally not a bad idea I left it that way and registered the plugin too)

 

As your code essentially  made a timeline with a scrollTrigger for each element I decided that I just select the element inside a left container and do the same wit those inside a left container. I did it by copying, you can make that more elegant, but that's up to you.

thank you for putting this up. Yes I tried this version where I duplicated the whole block but figured there mist be a way to more cleanly integrate the alternating

Link to post
Share on other sites
6 hours ago, codebloo said:

Where would I put the xPercent: etc line?

 

This exact line only contains placeholders so it won't help much putting that anywhere.

 

You'd have to adjust it to the element you want to check for a certain class on and put it on every tween of your timeline that you want to use one value to tween from if the current image has that certain class and another value if it doesn't - in your case that would be both .from-tweens.

 

See the Pen ada50d20952e1b946e2f05a474934842 by akapowl (@akapowl) on CodePen

 

  • Like 4
Link to post
Share on other sites

Just my two cents but I'd take advantage of the .wrap() utility method and target the container and the image in the same tween. You could check the index of the loop target and flipflop the .wrap() array depending on whether the index is odd or even. That way you wouldn't need to add the extra class to your HTML markup. You can then add a bunch of copies of the targets without worrying about the left/right class. Maybe something like this:

 

See the Pen 14db07e23ea1235bc448c229a757098c by PointC (@PointC) on CodePen

 

More info about .wrap()

https://greensock.com/docs/v3/GSAP/UtilityMethods/wrap()

 

Use it or not. Just a thought. YMMV.

 

Happy tweening.

:)

 

  • Like 6
Link to post
Share on other sites
20 hours ago, akapowl said:

 

This exact line only contains placeholders so it won't help much putting that anywhere.

 

You'd have to adjust it to the element you want to check for a certain class on and put it on every tween of your timeline that you want to use one value to tween from if the current image has that certain class and another value if it doesn't - in your case that would be both .from-tweens.

 

 

ah thank you! that "classList.contains". makes a lot of sense now that i see how it's written out, thank you!

 

 

Link to post
Share on other sites
18 hours ago, PointC said:

Just my two cents but I'd take advantage of the .wrap() utility method and target the container and the image in the same tween. You could check the index of the loop target and flipflop the .wrap() array depending on whether the index is odd or even. That way you wouldn't need to add the extra class to your HTML markup. You can then add a bunch of copies of the targets without worrying about the left/right class. Maybe something like this:

 

 

 

 

More info about .wrap()

https://greensock.com/docs/v3/GSAP/UtilityMethods/wrap()

 

Use it or not. Just a thought. YMMV.

 

Happy tweening.

:)

 

Thank you! This makes a lot of sense of how it's structured. I will read up on wrap, thank you!

Link to post
Share on other sites
23 hours ago, PointC said:

Just my two cents but I'd take advantage of the .wrap() utility method and target the container and the image in the same tween. You could check the index of the loop target and flipflop the .wrap() array depending on whether the index is odd or even. That way you wouldn't need to add the extra class to your HTML markup. You can then add a bunch of copies of the targets without worrying about the left/right class. Maybe something like this:

 

 

 

 

More info about .wrap()

https://greensock.com/docs/v3/GSAP/UtilityMethods/wrap()

 

Use it or not. Just a thought. YMMV.

 

Happy tweening.

:)

 

Hey @PointC,

I admire your dedication and knowledge and I really don't want to criticize you, but as someone who has  loved GreenSock products for ages, but has to make a living with many other tools too, I feel that you overengineered that a bit. I'm all for the clever solution and I'm surely envious that you can do such things.

But I couldn't help but thinking, that if I or some one else had to work with that code (adjust it) in the future I or she/he/they would be doomed.
A lot of commenting would be necessary at least. Id 'go for your solution in a game or highly individual presentation anytime, but not in a website that might live on for years and with ever changing content. Just think about the (not too unlikely) scenario that we need a special full-size centered element in between the others. Maybe injected by an almighty adserver....
 

Jus my one an a half cents. 

Link to post
Share on other sites
2 hours ago, iDad5 said:

I admire your dedication and knowledge and I really don't want to criticize you

lol. then that's probably a good place to stop.

 

Unfortunately, the many folks like @PointC  that have volunteered countless hours of their time over the years don't often have the luxury of making sure that every line of code is understandable to everyone of every skill level that passes by. The original poster was already satisfied so there's really no need for a committee to come in to do a code review.  If you have an alternative, cleaner solution that would certainly be a welcome addition that would add value to the thread.

 

If something isn't clear you can simply ask for an explanation. That's much better than calling it "over-engineered" and yet somehow at the same time criticizing it for not being forward-thinking enough to handle an ad-server injecting an ad into the middle of it 🙄

 

It's great that you started in this thread by trying to help. That's exactly what makes this place so great. 

There's loads of opportunity to help people, offer solutions, be a part of the community, make it better, and have your own voice around here.

Stay positive, offer solutions, and you'll be amazed at how much more fun it is around here and how much you discover along the way!

 

  • Like 7
Link to post
Share on other sites

@Carl

I'm a bit irritated by your comment. 

 

First of: If you read the whole thread from the beginning I not only 'tried' to help by pointing in a direction with the same intention as @akapowl

not wanting to just offer a complete solution in a first answer.

On 3/18/2021 at 10:30 AM, akapowl said:

This could be a nice test-case to become more fluent with JS, so I will leave that up to you ;) 

Give it a shot and let us know if you run into a problem with the implementation and we'll be glad to guide you in the right direction.

 

@akapowl's and my my posts somehow overlapped there. 

 

After the op's specific request for code I built fully working solution. According to your implicitly stated policy no one should have chimed in after that?

 

I didn't feel criticized by by @PointC's solution, and I also had no trouble understanding it (so no need to be condescending). I really thought that open discussion is valued but I also wanted to make it perfectly clear upfront that my criticism is not at all directed at the person but it is meant to be constructive. If I offended anyone with my post I sincerely apologize. 

 

Code wise PointC's solution ist clearly superior to what I offered. Conceptually I stay by my opinion that a solution that

  • a) packs a lot of complex functionality in one line is harder to read after a while
  • b)  relies on the fact of alternation for manipulating (clearly named)  semantically distinguishable elements

is not what I would recommend.

 

I think it is very good practice to build animation on top of the semantic structure by e.g. using existent class names and their logical inheritance to find what elements to animate which way. That way if and when changes to the structure or content of a page happen (which often is the nature of the beast) it usually is much easier to find and remedy unexpected behavior or avoid  it in the first place, without touching the programming.

But I know that that's just my opinion and you clearly do not value it which is obviously fully within you rights.

 

PointC stated his intention

On 3/19/2021 at 12:58 AM, PointC said:

That way you wouldn't need to add the extra class to your HTML markup. You can then add a bunch of copies of the targets without worrying about the left/right class. Maybe something like this:

and gave a well working solution. Kudos.

 

I have over 25 years of experience with developing web solution (even if my status here in the forum is newbie) and I thought that maybe my 2 cents could help. I didn't want to offend and will tread more carefully in the future.

 

 

Link to post
Share on other sites
9 hours ago, iDad5 said:

packs a lot of complex functionality in one line

 

That’s really the beauty and simplicity of all the Utility Methods. Many of the Helper Functions also utilize these methods. GSAP overall provides this same general premise so designers and developers can just get on with the creation and development aspect. Without users generally needing to write reams of complex animation code / logic or worry about browser support, etc.

 

GreenSock always intends to simplify the overall experience not complicate it. GSAP is immensely flexible and powerful so it’s always delightful that various examples (as seen in this thread and throughout the forum) can be derived to accomplish the same task in multiple ways. It’s generally not about who’s right or wrong, though we can all stand corrected at times. But rather demonstrating the powers of GSAP, which can come in many forms and through various approaches.

 

9 hours ago, iDad5 said:

I really thought that open discussion is valued

I built fully working solution. According to your implicitly stated policy no one should have chimed in after that?

 

Open discussion is certainly encouraged especially when directly focused on GSAP products. I’m not sure though of the impression why others should not also provide alternative solutions. Some of the best threads historically found on the forums are multiple users showing different solutions or building further upon each others approaches. That's largely part of what makes the forum, it's users and GSAP so great.

 

  • Like 4
Link to post
Share on other sites
5 minutes ago, Shrug ¯\_(ツ)_/¯ said:

Open discussion is certainly encouraged especially when directly focused on GSAP products. I’m not sure though of the impression why others should not also provide alternative solutions. Some of the best threads historically found on the forums are multiple users showing different solutions or building further upon each others approaches. That's largely part of what makes the forum, it's users and GSAP so great.

 

I'm totally on board with you on all that! But Carls' comment obviously isn't

13 hours ago, Carl said:

lol. then that's probably a good place to stop.

 

can't men anything else than shut up.

 

6 minutes ago, Shrug ¯\_(ツ)_/¯ said:

"According to your implicitly stated policy no one should have chimed in after that?"

 

I meant this as a reply to Carls' statement: 

13 hours ago, Carl said:

The original poster was already satisfied so there's really no need for a committee to come in to do a code review.

 

I am fully of the opinion that anyone can criticize my ideas but I'm not a committee. I would like to learn from you, but  getting eyerolls and being told to shut up when the grown ups talk?

Let's just say I'm somewhat disappointed about the style in which all that went down.

I provided a solution, and akapowl also offered assistance. I still think that we didn't do that bad, but I'm really open for discussion on that.
 

When with PointC a moderator came in and provided an other solution without acknowledging anything we had offered before I was slightly astonished. Noting wrong with that but it made me wonder if my solution was so bad and what I can learn from his. 
I took a closer look at his solution and was, as I stated, impressed but without meaning any disrespect weighed in with some thoughts of my own.
Based on actual experience and well meaning, but probably not well worded.

 

Then an other moderator chimes in and get personal with me for daring to contradict instead of discussing the conceptual disagreement. When I answer to that, I don't not get an answer from hin or the one who's approach I criticized while expressing my sincerer admiration for his work in general - no, the next moderator takes to answering me - all the while the others virtually stand around and applaud...

 

I really like, respect and support all the gerat work that all of you are doing here. I never wanted to challenge your authority. 

 

Shrug, I agree that the Utility Methods are beautifully I just dared to say that in this case I would have chosen not to use them. I - and i guess also most of those asking questions here - love to work with GSAP but I/we don't use it as often ,as advanced and as regularly as probably you do. In my experience whenever possible without signifikant  disadvantages it pays to write easily readable, easy to comment code even if it means 4 more lines.
It's just my own experience that when I have a hard time reading code I've written a year ago, I'm mostly angry at my former self for finding a very clever solution that forces me to do research on that rarely used  magic function - and only very rarely I compliment my former self for having found a cleverer solution. But that's likely  just dump old me...

I really would like to move on, but I feel can't without a personal note to @PointC When I 'returned' to the forum some weeks ago after a time of not even reading here, I read your introductory post that's pinned to the top of the forums and really liked it and your work. If I offended you with my criticism I feel really sorry and do apologize, I didn't mean to. Still, I really would have appreciated it if you personally would have told me so or annihilated my silly remarks.


 

Link to post
Share on other sites

@iDad5 Yes, multiple solutions are very much welcome around here. I love that you've been chiming in on various threads to try to help others, and I value the fact that you bring 25+ years of development experience. Most people only "take" around here (ask a question, get their answer and leave), so I'm always grateful when folks like you take the time to read other questions and risk offering a solution. 

 

As I'm sure you've noticed, we are very intentional about the "tone" that's encouraged in these forums; there are too many developer forums on the web that tend to have snarky or condescending tones to them, where someone posts a solution and someone else insults it or nit-picks. Or someone posts a question and the response they get is sorta like "why in the world would you ever do that???" (which could make them feel stupid and never want to ask a question there again). You said something very similar in another thread, although I don't think you meant it as condescending it still comes across that way. Your "over-engineered" comment came across that way to me too, but based on your other threads I don't believe you intended it that way. I personally didn't think @PointC's approach was over-engineered at all but I get that it's a subjective thing.

 

We want the GreenSock forums to be a warm, welcoming place where both experienced AND newbies hang out and feel like they can contribute and get something out of it without fear that they'll get bashed or something. Ironically, it sounds like you feel like you're getting bashed here which goes against that vibe, but I think @Carl's comment was aimed at protecting the vibe we're trying to create (some of your comments have come across in ways that could alienate rather than making people feel welcome). 

 

It's one thing to say "here's another solution...my goal was to make it very readable and maintainable", but it comes across differently when you just point out what you think are the stylistic deficiencies in someone else's solution without forking it to show specifically what you might do differently and ask for input on any blind spots you might have. I suspect some of the gentle push-back you're experiencing from the moderators may be informed by other threads you've participated in (like the "why in the world would you do that?" comment). 

 

Trust me - every single moderator here is a very kind, generous, and sharp person who isn't out to argue with you or insult you (or anyone around here). In fact, I think it's fair to say that we're all excited when we see someone else with dev experience weighing in on questions and offering solutions because we know that takes time, effort, and skill. Sometimes the sheer volume and complexity of the questions that roll in everyday is overwhelming - the more hands on deck the better. So I hope you don't take any of this as combative or personal at all - I think you've got a ton of potential to offer insights on questions in these forums; I'd appreciate it personally if you'd make every effort to join us in fostering that welcoming, kind vibe around here which I have seen you do on several occasions, so thank you for that. 

  • Like 4
Link to post
Share on other sites

oh no I'm sorry my question has spurred so much forum-centric drama 🙈

  • Haha 4
Link to post
Share on other sites
11 hours ago, codebloo said:

oh no I'm sorry my question has spurred so much forum-centric drama 🙈

I am sorry for my part in inadvertently hijacking your thread. Are you happy with all the help offered or can I, as an atonement :-), offer any help?

 

@GreenSock I thank you for your warm words and good advice. I'm sorry to have caused you to spent so much of your valuable time on that matter. I still have trouble understanding how Carls' intention could have be to remind me to be more warm and welcoming and less snarky by being sarcastic, somewhat condescending and borderline rude to me, but that might be my misunderstanding due to poor language skills, being no native speaker and all. I accept that.

@PointC I once again apologize for having been rude. I didn't mean to bee. As the offending word seems to have been "over-engineered" - maybe a little personal history might help you forgiving me: I'm actually an engineer, and what's worse a German one with a diploma form one of the universities where they teach us to built those BMW's, Audis, Mercs etc. "Over-engineering" is what we proudly do. The way I use the phrase, it's 90% praise, 5% compliment and the rest ist mostly self-deprecation with a grain of criticism. But you could have not know this and it was probably presumptuous from me in the first place to comment on your work like I was an equal, which I know I'm not. I'm sorry.  

  • Like 1
Link to post
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.

×