Jump to content

akapowl last won the day on March 21

akapowl had the most liked content!


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by akapowl

  1. Hello @agsymonds 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. https://codepen.io/akapowl/pen/XWPwaXK 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! https://codepen.io/akapowl/pen/jOvombV
  2. 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 set pinSpacing: false, too. You'll find more information on all of those properties mentioned in the Scrolltrigger docs. Good luck!
  3. 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.
  4. 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. 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
  5. 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! https://codepen.io/creativeocean/pen/gOvYEgq
  6. 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/or ScrollTrigger.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. https://codepen.io/akapowl/pen/vYzVmVQ
  7. 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. 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)? https://codepen.io/akapowl/pen/mdGzOJL
  8. 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.
  9. 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 a demo here 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 the trigger 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, like toggleClass: "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. Note that toggleActions don't apply to toggleClass. To have toggle class names in a different way, use the callback functions (onEnter, onLeave, onLeaveBack, and onEnterBack).
  10. 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. https://codepen.io/akapowl/pen/VwGEvaN 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. https://codepen.io/akapowl/pen/GRXYqgV
  11. 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. 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? https://codepen.io/akapowl/pen/NWLOqYW 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. https://codepen.io/akapowl/pen/zYJmvWm
  12. 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: https://codepen.io/GreenSock/pen/aYYOdN
  13. 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!
  14. 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 with y 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? https://codepen.io/akapowl/pen/KKxajmY
  15. Hey Mitchel. ScrollTriggers associated with timelines must wait 1 tick to do their calculations, so you could e.g. use a delaydCall to get what you need. https://codepen.io/akapowl/pen/wvEMNLa You can find a more thorough explanation by Jack in this recent thread (among others).
  16. 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. https://codepen.io/akapowl/pen/XWPXPqJ
  17. 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.
  18. 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. https://codepen.io/akapowl/pen/PodqJrb
  19. I see that you have updated your codepen demo - In future, please fork the example you initially provided, and post an updated fork instead. 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.
  20. 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, like toggleClass: "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. Note that toggleActions don't apply to toggleClass. To have toggle class names in a different way, use the callback functions (onEnter, onLeave, onLeaveBack, and onEnterBack).
  21. akapowl

    Peel Token

    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. https://codepen.io/akapowl/pen/dyqoPwq
  22. 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. https://codepen.io/akapowl/pen/WNgbLbB 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. https://codepen.io/akapowl/pen/xxabmYP 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😅 https://codepen.io/akapowl/pen/xxabMvv
  23. 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. https://codepen.io/akapowl/pen/dyqPYbX 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!
  24. Also as a heads up it is worth mentioning, that this will obviously only work for the first panel with simple instructions for start and end like 'top top' e.g., because of how that example is set up to be working with all panels positioned absolute; and thus all actually already being at that point when their top hits the top of the viewport. So if you were to set up ScrollTriggers for panels further down the line, you would need to properly calculate their starts and ends based on the calculations made for the ScrollTriggers in the forEach loop - which is where it would probably be good to set up any other ScrollTriggers, too, then. I added another ScrollTrigger for the orange panel in this other demo; just to give you an idea of what I mean by that. https://codepen.io/akapowl/pen/bGxGPEK
  25. Hello Bryn. The panels in this example do not scroll natively; instead they are being translated upwards by the ScrollTriggers set up forEach panel. panels.forEach((panel, i) => { if(i !== panels.length - 1) { gsap.to(panel, { yPercent: -100, // <-- see ease: "none", scrollTrigger: { start: heightSoFar, end: heightSoFar + panel.offsetHeight, scrub: true, } }); } heightSoFar += panel.offsetHeight; }); ScrollTrigger will use position: fixed for pinning by default, when the body is the scroller - which it is here. So you are basically trying to use position: fixed in a parent with transforms on it, which won't work as you might expect, because those transforms change the context of the 'fixing' to that parent then. Thus you will want to change the pinType to 'transform'. I would also suggest not to use pinSpacing: true here, as you don't seem to need it in this case, and it will throw things off - likely because the parent of the element is a flex-container. You can read more about pinType and pinSpacing in the ScrollTrigger docs. https://greensock.com/docs/v3/Plugins/ScrollTrigger You should probably also stick the creation of that seperate ScrollTrigger into the sizePanels() function to begin with, because on refreshInit all ScrollTriggers will get killed and only those in that function are being recreated in that example. So in your demo that ST you set up at the top will get killed when ScrollTrigger does its refresh on page load and then never created again and thus will not work at all. // see: ScrollTrigger.addEventListener("refreshInit", () => { // Kill off old ones ScrollTrigger.getAll().forEach(ST => ST.kill()); // Create new ones sizePanels(); }); Last but not least, it would be very helpful, if you could make your codepens forkable (by not setting them to private) in future; so the people helping here wo't have to re-create your example from scratch and have one less step to help you; which I hope this does. Happy tweening. https://codepen.io/akapowl/pen/ExexzgO