-
Posts
1,984 -
Joined
-
Last visited
-
Days Won
98
Content Type
Profiles
Forums
Store
Blog
Product
Showcase
FAQ
ScrollTrigger Demos
Downloads
Posts posted by akapowl
-
-
Hello Pedro,
your thought process with regard to that has a couple of issues. But before I start explaining, let me first mention, that your html element for some reason has a height difference of about 16px in comparison to the body element - I'm not quite sure why exactly that is the case, but it leaves a blank space at the bottom of that amount when the pinning is done, and seems to be to be a CSS styling issue related to your .sidebars__list element. To ommit that, I set the font-size of that element to 0px in CSS in my fork of your example, and instead set a fixed font-size of 16px to the .vertical-bar element. This feels more like a workaround for me though, so that is something you might want to look into.
The first issue I see with regard to your animations, is that you are trying to use xPercent as the property to be tweened on for your scrollTween - that won't work because your individual panels all have different widths. That fake-horizontal-scrolling technique using xPercent will only work when each of your panels has the same exact width of 100vw.
If you want to have different widths for your panels, you would have to tween on the x instead, and calculate things depending on your needs. This in your case can become tricky because of how that example of yours is set up - depending where exactly you want things to end e.g. you will have to incorporate a multiple of the width of your .vertical-bar elements into your calculations (and on top of that the padding-left on your .container - unless you set your elements' box-sizing to border-box).
Additionaly for the calculations (mostly for those coming up) to be precise, you would have to incorporate the width of the browser's scrollbar because of how things are set up (and probably also need to be set up for this to work).
This is the case, because while your vertical bars are positioned fixed so they align with their right side flush against the browser's scrollbar, everything else is dependent on 100vw or window.innerWidth, which both also include the space below the scrollbar in their value. That's why you will see a lot of
15
added or substracted throughout my example, because that's a value that worked fine for my browser with that regard - with different browser's that value might change though, and getting it right throughout all of them can become quite a pain.Same goes for the ScrollTrigger for your vertical bars - you will need to calculate where exactly to tween them to, when the start of that tween should happen and where it should end; including all things already mentioned in those calculations.
The biggest issue I see in your thought process with ragard to that ScrollTrigger for the vertical bars, is that you want to use the vertical bar as the element to be animated and the trigger element for that animation - that won't work like you might expect because those vertical bars will not move at all, as your scrollTween is not referencing them in any way - it is the horizontal panels that are moving. If you want the bars to move in sync with their respective panel, you should use the respective panel as the trigger element for each bar.
As you can see in the example below, everywhere dynamic values are needed, I make use of function-based values, so ScrollTrigger can get the correct value again when the window gets resized. For start and end of a ScrollTrigger that will work out of the box - for values used for properties of the tween to be invalidated on refresh, too, you will also need to add
invalidateOnRefresh: true
to the ScrollTrigger.If I got the description of what you wanted to achieve right, this fork of your example should resemble a setup that would work in a scenario as such.
Although it is quite a bit more complex than you initially thought it might be, I hope this will help clear some things up.
You can read all about the properties mentioned above in the Scrolltrigger docs and general docs for GSAP.
I hope this will help. Happy tweening and scroll responsibly!
See the Pen xxaNyoe by akapowl (@akapowl) on CodePen
-
Hello @agsymonds
2 hours ago, agsymonds said:I was unable to fork the Codepen
I set to my example above to public, so you should be able to fork it now and tinker with it.
In general, I really think that is more of a CSS styling question, than it has to do with GSAP. As you can see in this example below, GSAP does its job of splitting into chars just fine, when you remove the
-webkit-text-fill-color: transparent;
on the .span-gradient.See the Pen XWPwaXK by akapowl (@akapowl) on CodePen
Albeit doing some quick searches, I'm not sure, if there is an easy way to apply a continuous gradient to multiple individual elements, which you would need in a scenario where you were to split by chars.
So I went ahead and fiddled together a quick and dirty forEach loop that sets the backgroundSize of each character in the .span-gradient to the width of the whole span element, and offsets each character's backgroundPosition depending on the width of the characters that come before it. For that, in CSS, the gradient is now applied to each element inside the span, instead of the span itself.
This should give you an idea for how to possibly approach it, if nobody else knows of an easier way to get that result - I'd be curious myself if there is.
I hope that will be somewhat helpful though. Happy tweening!
See the Pen jOvombV by akapowl (@akapowl) on CodePen
-
3
-
-
Since you are going to be acting in an actual horizontal scrolling scenario unlike that demo of mine which was purposed for fake-horizontal scrolling, you don't even need any of the fancy stuff from that demo of mine.
Just adjust the scrollerProxy, that Helper already mentioned, to also work with horizontal scrolling, by either exchanging all scrollTop values by scrollLeft or adding an extra part for scrollLeft alongside scrollTop, and then you can use ScrollTriggers pinning to achieve the result you are going for.
Just remember to also set
horizontal: true
on the ScrollTriggers you set up because you are working with actual horizontal scrolling - then you can e.g. use a start value like 'left left' and an end value depending on how exactly you want things to behave. If you want it to behave like that demo of mine you posted, you will probably want to setpinSpacing: false
, too.You'll find more information on all of those properties mentioned in the Scrolltrigger docs. Good luck!
-
1
-
-
Hey there, Luca.
So you want it to behave the exact other way around? Then you'd need to set it up the other way around.
E.g. set the image to opacity 0 initially, either in CSS or in JS before the ScrollTrigger is created; and then tween it to opacity 1.
If you are having problems achieving that, please post a minimal demo of what you have tried, so we can help you from there.
-
3
-
-
It only appears to be centered in the end - it was not my intention to make it become centered - and I already gave you an explanation for the movement on the horizontal axis earlier.
22 hours ago, akapowl said:I exchanged your images with lorem-picsum images, and push them off to the side here, just so you can see how the clearing of the canvas has an effect on the whole thing. If it wasn't cleared, the images that were drawn before would still be visible.
onUpdate: (self) => { ctx.clearRect(0, 0, example.width, example.height); // <-- clear canvas before re-drawing new image ctx.drawImage(loadedImages[Math.floor(self.progress * 60)].img, 5*Math.floor(self.progress * 60), 0); // |pushing next image to the right| }
If you don't want your picture/s to move on the horizontal axis, switch the part that I added just for showcasing back to 0.
That is btw generally more of a canvas related part and nothing GSAP really is responsible for, so it might be worth checking up on that.
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Using_images#drawing_images
-
1
-
-
As the Helper already mentioned, this forum isn't really for tutorial requests of any sort @NikzA - but in this case I remember Tom Miller crafting something quite similar together with Alex Trost on the Frontend Horse / TrostCodes Twitch-Stream.
https://www.twitch.tv/trostcodes
You can re-watch that episode over on Youtube - maybe consider giving them a thumbs up for their work or leaving a nice comment on the video.
It's not infinite and doesn't have the exact same effect as the website you referenced (the logic for that is for you to implement then, heads up; it will likely not be the easiest thing to do) - on that website they are probably not even relying on native browser scrolling or native browser elements but rather listenening to relevant events like the wheel or touch in combination with WegGL rendering - but at the very least this should be a good starting point. Hope it will help, good luck!
See the Pen gOvYEgq by creativeocean (@creativeocean) on CodePen
-
3
-
1
-
-
33 minutes ago, Rodrigo said:
I even tried in this example created by @akapowl and the issue persists
I'm pretty sure that happens, because when reloaded, the window/body/documentElement is not at the very top when locomotive-scroll gets initialized. From what I can tell, on its own, locomotive-scroll will always reload at the very top.
I have seen some issues over on their Github where people were asking, whether it was possible to use scroll restoration with locomotive, or for the locomotive-team to implement it, but none of those I remember got a postive answer, if any.
So my guess is, that it's just a thing, that is neccessary for locomotive-scroll to work the way it does (one reason I never really used it myself).
And a way to work around the issue then would be to set your
window.history.scrollRestoration
to 'manual' and/orScrollTrigger.clearScrollMemory('manual')
Obviously your page will not reload where it was then, but at least it will be working - as I said, I guess it's very likely just a locomoitve-scroll thing.
Does any of you get this updated demo to break? ...I couldn't.
-
3
-
-
14 minutes ago, EVA CORPORATION said:
Mm... I thought maybe I missed something and inserted your js from CodePen to myself, with your pictures. Why are there no pictures, it seems to be the same..
Because you are creating Errors, as you are not loading jQuery in your codepen, while there is code that relies on jQuery in that demo - again: check your console in dev-tools.
Also, JS is only one third of what makes the page; and it doesn't look like you changed what I mentioned earlier about putting your canvas inside of your section and positioning it absolute instead of fixed, in your codepen either - don't forget about that.
1 hour ago, akapowl said:..right now you have it positioned fixed, so that is what's to be expected. If you want it contained within your section, but still overlaying other elements, you should probably position it absolute in that section then. And if you want it to stay in place within a certain threshhold of scrolling, you could pin it via ScrollTrigger ( you can read all about
pin
in the ScrollTrigger docs ).And then again, in your last codepen there are now only 58 images - that's why at the end there won't be an image visible, because your calculation doesn't match up with the length of the array.
Best just swap out the number in your calculations with
(images.length - 1)
. That way you won't have to adjust it and probably won't have to worry about errors with that regard, or an image not showing.// this... loadedImages[Math.floor(self.progress * (images.length - 1))].img, // ...instead of this loadedImages[Math.floor(self.progress * 59)].img,
That works better now, right (even with your older jQuery version)?
See the Pen mdGzOJL by akapowl (@akapowl) on CodePen
-
3
-
-
Mitchel is right; but with regard to your ScrollTrigger, the jQuery version shouldn't make much of a difference anyway.
I just tested and reverted back to your jQuery version used, and for me the demo behaves exactly the same and works as expected.
Have you made sure, the index you are calculating is not larger than the largest index of your array (double-check the console in dev-tools); or maybe for some reason the last image is simply just blank/transparent? ...if you can not reproduce your issue in a minimal demo, I'm afraid I won't be able to be much more of a help than that.
-
2
-
-
Hello, @bntratox,
containerAnimation was made to make what you are trying to do a breeze. Have a look at it in the ScrollTrigger docs.
https://greensock.com/docs/v3/Plugins/ScrollTrigger
containerAnimation Tween | Timeline - A popular effect is to create horizontally-moving sections that are tied to vertical scrolling but since that horizontal movement isn't a native scroll, a regular ScrollTrigger can't know when, for example, an element comes into view horizontally, so you must tell ScrollTrigger to monitor the container's [horizontal] animation to know when to trigger, like containerAnimation: yourTween
. See aSee the Pen 9be5d371346765a8c9a426e8f65f1cea by GreenSock (@GreenSock) on CodePen
and more information here. Caveats: the container's animation must use a linear ease (ease: "none"
). Also, pinning and snapping aren't available on containerAnimation-based ScrollTriggers. You should avoid animating thetrigger
element horizontally or if you do, just offset the start/end values according to how far you're animating the trigger.For changing classes on elements, you could either implement logic of your own in the ScrollTrigger's callbacks, like you do with your console.log, or you could see if ScrollTrigger's toggleClass could be helpful for your usecase, too.
toggleClass String | Object - Adds/removes a class to an element (or multiple elements) when the ScrollTrigger toggles active/inactive. It can be either of the following: -
String - The name of the class to add to the
trigger
element, liketoggleClass: "active"
-
Object - To toggle a class for elements other than just the trigger, use the object syntax like
toggleClass: {targets: ".my-selector", className: "active"}
. The "targets" can be selector text, a direct reference to an element, or an Array of elements.
toggleActions
don't apply totoggleClass
. To have toggle class names in a different way, use the callback functions (onEnter, onLeave, onLeaveBack, and onEnterBack).-
3
-
1
-
String - The name of the class to add to the
-
1 hour ago, EVA CORPORATION said:
Then there was a question why the trigger stops the animation of the picture, but when scrolling the page the last frame goes on... and does not stop at the trigger point.?
Sorry, but I don't quite understand what it is you are asking here.
Could you maybe try and re-phrase or on the basis of a demo somehow make it clearer, what you mean?
As you can see in this version with markers on and some spacing around that section, the exchange of the images starts and ends exactly where you have set things up; so I'm a bit lost here.
See the Pen VwGEvaN by akapowl (@akapowl) on CodePen
Are you saying, you don't want the canvas to scroll with the flow of the page, e.g. when the visible window is above or below that section?
...right now you have it positioned fixed, so that is what's to be expected. If you want it contained within your section, but still overlaying other elements, you should probably position it absolute in that section then. And if you want it to stay in place within a certain threshhold of scrolling, you could pin it via ScrollTrigger ( you can read all about
pin
in the ScrollTrigger docs ).https://greensock.com/docs/v3/Plugins/ScrollTrigger
But again; I'm quite lost about what it is you're asking.
Edit: Here is an example with what I mentioned above.
See the Pen GRXYqgV by akapowl (@akapowl) on CodePen
-
1
-
-
1 hour ago, EVA CORPORATION said:
Kind of did... but not a single picture opens...
That is because you are trying to load images via http request on a website that is https secured (codepen) - that apparently won't work, and you get quite a load of console warnings in your dev-tools about that.
1 hour ago, EVA CORPORATION said:I'll try to figure it out >_<
I exchanged your images with lorem-picsum images, and push them off to the side here, just so you can see how the clearing of the canvas has an effect on the whole thing. If it wasn't cleared, the images that were drawn before would still be visible.
onUpdate: (self) => { ctx.clearRect(0, 0, example.width, example.height); // <-- clear canvas before re-drawing new image ctx.drawImage(loadedImages[Math.floor(self.progress * 60)].img, 5*Math.floor(self.progress * 60), 0); // |pushing next image to the right| }
On a different note:
You arenot loading jQuery in your codepen, but it has references to jQuery, so I loaded that in for you, too. There is also a closing </div> tag missing for the .container in your demo; i added that in my pen.
Furthermore, I added one more image to the array, so now it's 61 in total instead of 60, because when reaching the end, with how you have things set up in your drawImage() call, I was getting an error about an img not being found. That's because the array was an image short in that case as the last image you wanted to draw would have to have an index of 60 (progress being 1 multiplied by 60) but you only have 60 images, so the last index available would be 59.
Does this work more like you imagined now?
See the Pen NWLOqYW by akapowl (@akapowl) on CodePen
Edit:
Of course you don't have to add an extra image, but could also just limit your calculated index to 59 instead of 60.
-
3
-
-
Welcome to the GreenSock forum, @EVA CORPORATION
With regard to the images overlapping each other; that probably happens because you are not clearing your canvas before re-drawing the next image, so it is more of a canvas related question than a GSAP one - you might want to have a look at the thread linked below.
With regard to anything else, it is pretty hard to tell without a minimal demo that we can tinker with, and clearly see the issue in an isolated environment. On your website there might be several other things interfering and/or causing your issues, so it is not feasible for us to debug live websites - the issue could be caused by CSS, markup, a third party library, your browser, an external script that's totally unrelated to GSAP, etc.
If you can provide a minimal demo, I'm sure your cahnces of getting help will be a lot better.
Please don't include your whole project. Just some colored
<div>
elements and the GSAP code is best (avoid frameworks if possible). See if you can recreate the issue with as few dependancies as possible. If not, incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, then at least we have a reduced test case which greatly increases your chances of getting a relevant answer.Here's a starter CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo:
See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen
-
2
-
-
Hello @UD123
You will probably need to use some sort of clipping or masking.
There is a tutorial on Dynamic CSS Masks with GSAP over on codrops, maybe that can help.
As the helper already mentioned, please keep in mind that this forum is not intended to provide custom tutorials on effects.
Good luck and happy tweening!
-
1
-
-
I'm not sure I 100% understand what you want to happen, but as far as I understood things, I'd just create one ScrollTrigger that handles the pinning - as Mitchel already said, since your lottie svg is inside that section, and you are going to pin that section, there is no need to pin the lottie element, too.
After that, create your LottieScrollTrigger with pin set to false, and the same trigger and start as the pinning ST, then in the ST you set up for the images to move up, just use the end of the .previous() ScrollTrigger as the start - that way you won't have to make the calculations mentioned by Mitchel, as you can let ScrollTrigger handle that for you.
As for using yPercent vs. top - you could probably just keep your calculations as they are and swap out
top
withy
for the tweened property and should be set for better performance already, which all in all would result in something like this. Is taht what you were going for?-
4
-
1
-
-
-
Hello Alex.
In timelines the scrollTrigger object does not belong on individual tweens of the timeline, but on the timeline itself; not doing so is one of the most common ScrollTrigger mistakes. You can read more about it in the linked article.
Also I would suggest to just use your "-30" as a number instead of a string.
-
2
-
1
-
-
Welcome to the GreenSock forum @sergei86
That really sounds more like a canvas question than a GSAP question to me; but you'll probably have to make sure that you clear your canvas before drawing a new image on it. That's also suggested in this answer of an older thread. I hope that will help. Good luck.
-
1
-
-
It works just fine for me - in your case the effect will be very subtle though - especially on wide screens, because unlike the original demo, you did not set a fixed height to the .container; so instead the height in your example is depending on its contents - and xPercent is related to the height of the target.
When you add more content to the footer in your example, you should see it more apparent.
See the Pen PodqJrb by akapowl (@akapowl) on CodePen
-
3
-
1
-
-
I see that you have updated your codepen demo - In future, please fork the example you initially provided, and post an updated fork instead.
28 minutes ago, Redcase Software said:Ok, i get the issue with the selector.
Apparently not quite yet, as in your update you are now also targetting the wrong element in the gsap.set() call before the actual tween.
Again:
.container
is the element you need to target in both of them; the gsap.set() and the tween.-
2
-
-
Hello Alexander.
The ScrollTrigger docs have an explanation for how to do that - the object option is what you are looking for.
https://greensock.com/docs/v3/Plugins/ScrollTrigger
toggleClass String | Object - Adds/removes a class to an element (or multiple elements) when the ScrollTrigger toggles active/inactive. It can be either of the following: -
String - The name of the class to add to the
trigger
element, liketoggleClass: "active"
-
Object - To toggle a class for elements other than just the trigger, use the object syntax like
toggleClass: {targets: ".my-selector", className: "active"}
. The "targets" can be selector text, a direct reference to an element, or an Array of elements.
toggleActions
don't apply totoggleClass
. To have toggle class names in a different way, use the callback functions (onEnter, onLeave, onLeaveBack, and onEnterBack).-
3
-
String - The name of the class to add to the
-
Peel Token
in GSAP
2 hours ago, Rodrigo said:I think that with enough tinkering this could be achieved with GSAP.
Yeah; quite some time ago I've already explained some basics of GSAP to you and helped re-create that effect in the demo @Rodrigo just now posted, @jollygreen
That animation is nothing that is set in stone with strict rules - and tinkering, testing and exploring is nothing others can take off of your hands if you want to have it a very specific way.
So my suggestion would be to just start from the example we landed on back then and tinker around with each value of each tween, to see what they do until you'll eventually get a feeling for how all of them connected result in the overall visual animation.
I did the same just now and came to this demo - it does not perfectly resemble what I think you wanted to achieve, but it should come pretty close.
Now you could e.g. compare the values from this new codepen to those we landed on back then and see how they differ from each other.
I hope this will help - good luck and happy tinkering.
See the Pen dyqoPwq by akapowl (@akapowl) on CodePen
-
4
-
1
-
-
Or you could just set up your SVG a bit different.
Like e.g. create 4 circles, two of them sharing the same gradient; and mask each of them with a simple rect (one for each 'corner') - basically the other way around from what you tried. Then you could just tween on the mask rects.
See the Pen WNgbLbB by akapowl (@akapowl) on CodePen
Alternatively you could also boil this down to creating just two circles with gradients and two masks with the masks being customized paths that would show what you needed.
Oh, wait;
You can of course just add multiple rects to a mask - that would reduce the need for cirlces.
See the Pen xxabmYP by akapowl (@akapowl) on CodePen
Edit:
Coming to think about it again; technically for this specific usecase you'd even only need to mask the circle that is topmost on the z-axis - which would be even better, because this way you could avoid those nasty white lines in between the rects, that SVG tends to cause.
Okay, I'll stop now😅
See the Pen xxabMvv by akapowl (@akapowl) on CodePen
-
5
-
-
Hello there.
The main problem, is that you are targetting the wrong element in the tween.
// wrong element uncover.to(".footer-container", { yPercent: 0, ease: "none", onUpdate: function() { console.log("update", this.progress()); } }); // right element uncover.to(".container", { yPercent: 0, ease: "none", onUpdate: function() { console.log("update", this.progress()); } });
That changed, it should already work.
See the Pen dyqPYbX by akapowl (@akapowl) on CodePen
Some more things for your consideration:
-
In my original demo, the end of "+=75%" on the ScrollTrigger was chosen according to the height of the footer; you changed the height, so you might want to consider changing the end of the ST, too, to keep things consistent 'speed'-wise.
- You are using an element with no actual height as the trigger-element for the ScrollTrigger - while it appears to be working with that, I would suggest re-considering that choice or setting some height to that element, to prevent running into possible issues that might cause.
I hope that will help. Scroll responsibly!
-
2
-
In my original demo, the end of "+=75%" on the ScrollTrigger was chosen according to the height of the footer; you changed the height, so you might want to consider changing the end of the ST, too, to keep things consistent 'speed'-wise.
How to apply perspective effect on text with shape(trapezoid)
in GSAP
Posted
Sure you can. But getting that setup right has nothing to do with GSAP - it's just CSS styling.
This right here is the second result of a google search for '3d perspective div with text'.
https://3dtransforms.desandro.com/perspective
See the Pen PodvVGo by akapowl (@akapowl) on CodePen
Edit:
When you're going to animate it with GSAP, it will be best to set the perspective on the parent element.
Click anywhere in the pen to run the animation.
See the Pen GRXazdJ by akapowl (@akapowl) on CodePen
And if you want to animate the box and text individually, you will probably be best to not have them nested, e.g. like so.
Still, those are mostly CSS related things to consider. I hope that will help.
See the Pen dyqEaWr by akapowl (@akapowl) on CodePen