Jump to content
GreenSock

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

Leaderboard

Popular Content

Showing content with the highest reputation since 10/09/2021 in all areas

  1. Looping back with a codepen. ✨ https://codepen.io/cassie-codes/pen/zYdxopE
    8 points
  2. Hi and welcome to the GreenSock forums, Thanks so much for the clear demo. You can use an onComplete callback to apply clearProp:"all" to remove the inline styles. Be sure to inspect your box after the animation runs in the demo below https://codepen.io/snorkltv/pen/bGrVwxv?editors=1010 more on clearProps: https://greensock.com/docs/v3/GSAP/CorePlugins/CSSPlugin#h3-clearprops this video on callbacks and scope may help too
    6 points
  3. Hi there Mantrone! Welcome to the forums and thanks for joining club GSAP How about something like this as a starting point? https://codepen.io/GreenSock/pen/qBXdywG?editors=1010 You can control how the morph looks by tweaking the shapeIndex - read the docs for more info ☺️
    5 points
  4. The issue is the arrow function. The same goes for using let. IE is forever stuck using an older version of JavaScript. Most people use babel to do the conversion, or they don't even worry about IE because it's a waste of time as Microsoft doesn't even support it. var mobile_menu = gsap.timeline({ scrollTrigger: { trigger: "#site_content", toggleActions: "play none none none", start: "top top", end: "bottom bottom", onUpdate: function(self) { if(self.direction == -1){ mobile_menu.reverse(); } else if (self.direction == 1){ mobile_menu.play(); } } } });
    5 points
  5. let explodeCont = document.querySelectorAll('.anim-explode-container'); explodeCont.forEach((container) => { let svg = container.querySelector('.anim-explode'); let shapes = [ 'M254 286.11a50 50 0 0050-50H204a50 50 0 0050 50z', 'M255.5 271a20 20 0 10-20-20 20 20 0 0020 20zm0 30a50 50 0 10-50-50 50 50 0 0050 50z', 'M307.5 250a50 50 0 11-50-50 50 50 0 0150 50', 'M234 237a22.5 22.5 0 0045 0h27.5a50 50 0 01-100 0z', 'M258 202.5a12 12 0 00-12 12v26h-26a12 12 0 000 24h26v26a12 12 0 0024 0v-26h26a12 12 0 000-24h-26v-26a12 12 0 00-12-12z', ]; container.addEventListener('mouseenter', (e) => { let animatedShapes = []; for (var i = 0; i < 10; i++) { let newElement = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' ); newElement.setAttribute('d', gsap.utils.random(shapes)); newElement.style.fill = gsap.utils.random([ '#4899DF', '#f0f0f0', '#00C0CC', '#DE2870', '#C7DBF4', ]); svg.appendChild(newElement); animatedShapes.push(newElement); } function killShapes() { animatedShapes.forEach((shape) => { svg.removeChild(shape); }); } gsap.set(animatedShapes, { transformOrigin: 'center', scale: 'random(0.2, 1)', }); gsap.to(animatedShapes, { onComplete: killShapes, keyframes: [ { rotate: 'random(180, -180)', x: 'random([-150, -100, -200, 200, 100, 150])', y: 'random([-150, -100, -200, 200, 100, 150])', ease: 'expo.out', duration: 4, stagger: { amount: 0.1, }, }, { opacity: 0, delay: -3 }, ], }); }); }); Apologies for the wall of code - but I did a similar thing on this site for the tickets button up at the top right. Might be helpful to see another approach. It's using SVG which is quite nice for responsive/crisp vector stuff (I'll try to loop back and pop this in a codepen next week, but I have sunday roast and wine waiting right now πŸ‘€)
    5 points
  6. Hey there @Dipit Maurya I'd probably work with a data-attribute on each .inner-listing for something like that. Maybe something like this: https://codepen.io/akapowl/pen/c95cfa7260c37ea092daef8f5c92fd13 Edit: ... here is another version, polished up a bit with regard to margins/padding and a slight change on the start/end of the ScrollTrigger. https://codepen.io/akapowl/pen/d4b4927ba6227d308fb947c1cf4f388d
    5 points
  7. My pen above pretty much (except for the additional pinning and different start/end) does what's happening to the image of the two women in the example you posted above. Maybe you didn't see the correct one, because I first posted a link to the wrong pen. As @GreenSock already mentioned, please note, that these forums are not intended to provide free "build-to-order" solutions (please read the forum guidelines). First and foremost these forums offer support with GSAP specific questions. If you have trouble getting an effect done as you wish (which is not what these forums are there for in the first place), please provide a minimal demo of what you have tried so far and explain in a bit more detail what you want to happen and you will drastically increase your chances of gettig a solid answer. Thanks.
    4 points
  8. Hi there @GiGiX As already mentioned in that other thread of yours by @GreenSock and @Cassie, the order of creation of your ScrollTriggers is very important. If you create the ScrollTrigger on your .triggerClick before all the other ScrollTriggers, it can not know about the pinSpacing that is being added by the other ScrollTriggers you are creating later on - although they affect elements that are prior to the .triggerClick in their appearance in the DOM. https://codepen.io/akapowl/pen/0130dd24ddea70c666830307c8d388da As already mentioned, too; if for whatever reason you can't create them in order of appearance on the page, you can set a refreshPriority. More info on that here: https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.sort()
    4 points
  9. Hi Mark, I'm surprised this didn't crash your app. You're creating a new scale animation on every animation frame. It's generally a bad idea to create an animation inside an onUpdate callback, especially an animation that has a repeat of -1 as that will run an infinite amount of times. tweenRotateCube = gsap.to(addCube.rotation, { y: Math.PI/2 , duration: 3, repeat:-1, ease: "none", onUpdate: function () { gsap.to(addCube.scale, { duration: 0.1, repeat:-1, x: 1.2, y: 1.2, z: 1.2, }); }, }); Checking for an active animation is ok for very basic stuff. With what you have going on, you'll need a better way to keep track of the hover states. I just made a little animator class to handle that. A Pen by GreenSock (codepen.io)
    4 points
  10. Hi there Jenda, Welcome. ☺️ I'm not quite certain what you were trying to achieve with your first loop? Looks like you're looping through multiple containers but pinning the main one? I've removed that until you can tell me what your goal was! Here's a simplified loop pinning the numbers, is that what you were looking for? Positioning the first number would be down to styling things differently and pinning it for the duration - but again, I wasn't really sure what you were after. Hopefully this helps! https://codepen.io/GreenSock/pen/yLoYbpL
    4 points
  11. Might be able to dissect this pen a bit to get what you're looking to achieve, functionality wise: https://codepen.io/elegantseagulls/pen/wvazXLe Obviously bit more going on than what you're looking to do, but it's still tweening a path with text along it still.
    4 points
  12. Hey there welcome to the forums! This is an easy thing to get confused by. You're looking for a loop. https://codepen.io/GreenSock/pen/eYENLLw This article is a good read if you want to avoid common mistakes
    4 points
  13. You could also use once: true, if I am not mistaken. https://codepen.io/akapowl/pen/e26c8669cb90500b27e682f32259fb0a
    4 points
  14. Also - there's a difference between a path that *is* a stroke, and a path *with* a stroke. https://codepen.io/svganimationworkshop/pen/oNegWGy
    4 points
  15. An option for this case could be using a media query listener and clearProps? (I can't fork your pen I'm afraid. Apologies for the snippet instead) function addMQListener(mq, callback) { if (mq.addEventListener) { mq.addEventListener("change", callback); } else { mq.addListener(callback); } } addMQListener(window.matchMedia("(min-width:800px)"), event => { if (event.matches) { console.log('not smol') gsap.set(".notice", { clearProps:"all" }); } else { console.log('smol') } } );
    4 points
  16. Welcome to the forums @dve46 I would put a wrapper element around the canvas and use that instead since the inline styling that GSAP is apply for the pinning is not going to match the attributes that three.js sets. ScrollTrigger Pinning with three.js (codepen.io)
    4 points
  17. Yep - masking is the best choice IMHO. I have a whole tutorial about variable width strokes and calligraphy handwriting. I also cover how to handle it when sections of the letters overlap themselves. https://www.motiontricks.com/svg-calligraphy-handwriting-animation/ https://codepen.io/PointC/pen/zYqYOrp Happy tweening.
    4 points
  18. Hey there @animationmagic By disabling the first ScrollTrigger onLeave and thus removing the pinSpacer, you are changing the height of the document and since that second ScrollTrigger's start will be set when the pinSpacer of the first ScrollTrigger is still there, you would actually have to call a ScrollTrigger.refresh() after disabling the first ScrollTrigger, so the start of the second ScrollTrigger can be set again to its now correct value. Usually you'll just want to wrap all your content inside a wrapper and pin that wrapper if you don't want any pin-spacing to be visible in cases as such. Now in your scenario with the first ScrollTrigger that is being disabled onLeave things will be sort of tricky if you wrapped all the content, so I'd suggest just wrapping the portion of content after that first section you are pinning individually before in a wrapper and pin that. Something like this: https://codepen.io/akapowl/pen/8c708012c35eff9fc01c5b89265d7a0d Please note though, that if you will add any subsequent ScrollTriggers on elements inside that .second-pin wrap, you will likely have to specify that wrap within the pinnedContainer property on those subsequent ScrollTriggers, as they can not take any pinSpacing into account because they will be within that wrap. I hope that's helpful, happy scrolling!
    4 points
  19. Hey there @jamis0n Here's a pass at a solution using Jack's suggested technique of popping the progress to the end, doing a calculation and then resetting it. I hope it helps, I'd suggest scaling the text is possible because you'll get a smoother end result than if you're animating the text size. I've added some comments too. https://codepen.io/GreenSock/pen/dyzPyXx?editors=0011
    4 points
  20. Hey @EmAnd It would probably be best to create your timeline beforehand (and set it to paused) and then in the mouseenter function just toggle its playstate. If I am not mistaken, you are actually not adding tweens to a timeline there but creating new individual tweens with each of your function calls. ... tl = gsap.fromTo( ... ) ... I changed that a bit, so now the tweens get added to that one timeline, so you can change the playstate of the timeline easily. (And I also moved the delay from the delay var to the position parameter.) ... tl.fromTo(...) ... Here's one possible solution that only restarts the timeline when it is not active. https://codepen.io/akapowl/pen/53f4df1227ef6b3e28cdcbf9d4330d52 The big plus of creating it beforehand (and adding the tweens to the tl instead of creating new individual tweens) is that if all you want to do is to play it from scratch when you re-enter with the mouse, you won't even have to check on the active state. https://codepen.io/akapowl/pen/98f8a54d976ee4112e5e94e8df2d7c70
    4 points
  21. Hi Deepus, We added directional snapping in 3.8 which seems to have affected this demo. I've set directional to false and it's behaving as expected now. https://codepen.io/GreenSock/pen/bGexQpq
    4 points
  22. Hello @ttiimmaacc GSAP's ScrollTrigger is a super powerful tool to do things like these. It might really help you with this. Here is what your example could look like ( I just pushed the start and end away from the edges of the window for better visualization). https://codepen.io/akapowl/pen/b01fd41c0a80f02caa7803c413c41e37 Since version 3.8.0 ScrollTrigger also comes with a .isInViewport helper function - which for your needs in this case shoudln't really be neccessary though. Before taking a deeper dive into the documentation, I would suggest checking out the getting started article:
    3 points
  23. It's really not going to matter one way or the other. I wouldn't put much thought into micro-optimizing for performance unless you notice a problem. I see people waste a lot of time worrying about stuff that will never matter in the real world. They key to animation performance is to be mindful of what properties you are animating. Some properties perform better than others, like x, y, and scale vs left, top, and width/height. And the type of object you are animating matters too. So SVG would be slower than an HTML element, and all of those would be slower than canvas/WebGL.
    3 points
  24. Hello @Juku123 You will have to incorporate a similar logic to the end and start of the individual ScrollTriggers as is used for the x-property of the fake-horizontal tween. When you horizontal section moves to the left, the left side (0% of the element) will be the nearest to the center so then you'd want its start to be "0% 50%" and its end to be when the side that is further away (100% of the element) hitse the center, so "100% 50%". When your horizontal section moves the other way though, so to the right, the nearest side of each element will be the right side (so 100% of the element) and the side that is further away being the left (so 0% of the element) - making the start and end exactly the opposite of when your horizontal section moves to the left. This is how you could implement that logic above with ternary operators; hope it helps. ... // Add class to active item // ========================= sections.forEach((sct, i) => { ScrollTrigger.create({ trigger: sct, containerAnimation: scrollTween, start: thisAnimWrap.classList.contains('to-right') ? "100% 50%" : "0% 50%", end: thisAnimWrap.classList.contains('to-right') ? "0% 50%" : "100% 50%", toggleClass: { targets: sct, className: "active" }, // markers: true }); }); https://codepen.io/akapowl/pen/7310d420d471b75bb9ed61a6b395fae1
    3 points
  25. Hello @renny As @GreenSock mentioned, the more minimal your demo, the more likely you'll get a proper answer, as it can be quite cumbersome to wade through that many of lines of code - and debugging whole projects is not really within the scope of these forums. Here are some notes on your demo: First things first - whenever possible you should create your ScrollTriggers in order of their appearance on the page. Secondly; except for some special cases where it might be neccessary, it almost never is a good idea to change the position property of an element, especially if you are using it as a trigger. You can achieve the effect you are going for by pinning your element and setting pinSpacing: false - same goes for your header-video. If you need to have a scrub as high as 2 on the animation ScrollTrigger for the fade out of that title, you will have to make sure you are pinning that title (in the ScrollTrigger you created just for that pinning) long enough, so that it's unpinning won't become noticable (as the fading out 'lags' behind the scroll 2 seconds because of that scrub-value). You can in fact just set the end to a very high value - like 5000 - since it won't really matter as the element won't be visible anymore and because of the pinSpacing false won't have an effect on following elements. Does this look more like what you inteded already? https://codepen.io/akapowl/pen/d2c7509df85eeee3ff908f9d9ba9b103
    3 points
  26. Hello there, @Jona Anders For performace reasons, ScrollTrigger does all its calculations upfront - so it won't change the start and end while you change the height of an element that you have a ScrollTrigger on when you're scrolling. There was a similar question just recently, that might help you get in the right direction. Here's what your example could look like then - unfortunatelly, if I am not mistaken, I don't think you can use values like rem for the end of a ScrollTrigger, so you'll probably have to do the neccessary calculation based on the window's height and pixels instead. https://codepen.io/akapowl/pen/e867259e3e0c5b3d2fcd21eaa5985fe3
    3 points
  27. Just echoing this Listening to the resize event and recalculating during resize is a pointless performance drain in most cases. It's a lot of work for the browser and most people don't even look at the content while they're resizing. It's a really small micro detail that devs obsess over - but it's not really of concern to the average user.
    3 points
  28. Thank you so much Carl! That's so simple to do, GSAP is amazing. 😍 I wish I used the word 'complete' in my search instead of 'animation finished', completely missed this functionality. I'll implement this into my project now, you're a saviour, cheers 🍻 - I'll watch the video now and see what else I have to learn.
    3 points
  29. Resizes are debounced for performance. There's really no need to recalculate stuff until the browser size has settled. If you want to listen for resizes you can use add an event listener. https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.addEventListener()
    3 points
  30. This is all very intentional - There are browser bugs and quirks that this works around. GSAP is protecting you We switch the transformOrigin to 0 0 because if we don't, you'll see funky behavior in Safari, for example. Firefox also has various bugs related to transform-origin on SVG elements. We bake all the calculations into the matrix(), including the origin offsets. πŸ‘
    3 points
  31. Welcome to the forums @dtpmike2 You probably shouldn't be using onUpdate for something like that. Just make an animation on your timeline that moves it. It will probably help if you focus on your animations first without using ScrollTrigger or any other 3rd party libraries like smooth scrollbar first. Once your animation works the way want, then add in all the scrolling stuff. GSAP Starter Template (codepen.io)
    3 points
  32. Welcome to the forums @liow You need to use immediateRender on your 2nd tween. Otherwise it would be animating from black to black. GSAP + ScrollTrigger (scrub) Change text color (codepen.io) You can learn more about immediateRender here.
    3 points
  33. Welcome to the forums, @GiGiX! Nah, it's not a rookie mistake - you've got a tricky scenario there. But don't worry, it's totally solvable. The problem is that you were pinning an element inside another element that's also pinned. That's not a good recipe for success Just pin the outer element in both scenarios. You can even make the horizontal one pick up exactly where the previous ScrollTrigger picks up by using a function-based end value of self => self.previous().end https://codepen.io/GreenSock/pen/rNzVWjL?editors=0010 Is that more like what you wanted?
    3 points
  34. We can't fork your pens because they are private, but here's how I do media queries. Media Query Watcher (codepen.io)
    3 points
  35. You can put what you have a in CodePen. We don't want to see your entire site, just the problem you are having an issue with. It's nearly impossible to help someone fix a problem on a live site, especially if we can't interact with the code. You don't need to include any assets from your site. The simpler the demo, the better.
    3 points
  36. Hey Jenda, If you just want to the container for the duration of the timeline you can do this - let tl = gsap.timeline({ scrollTrigger: { trigger: ".layer-story-box", scrub: true, pin: true, start: "top top", end: '3000px', markers: true } }); I also positioned your text boxes absolutely so that they're on top of each other. Adjusted pen https://codepen.io/GreenSock/pen/eYEmdrm?editors=0011
    3 points
  37. Your GSAP code looks fine, except you really don't need the gsap.ticker.fps(fps) as GSAP will run at the correct fps. I looked at your URL, and there really aren't any animations. Just a bunch of dots floating around. The only thing that stuck out is that you have have a massive canvas. The height on my monitor was almost 7000 pixels high. That's a ton of pixels you're asking the browser to process. Your canvas should really never be larger than the screen.
    3 points
  38. Welcome to forums @Sowjanya TweenMax was replaced in version 3 with a simpler gsap object. Check out the migration guide to see all the changes and the new way to create animations.
    3 points
  39. This is exactly what I tried to achieve. Thank you for your time, really appreciate it. I'll read the whole documentation again to know more about the library!
    3 points
  40. Here you go. https://codepen.io/GreenSock/pen/dyzyxaZ For future reference - It's polite to provide a minimal demo as a starting point. It really helps to cut down on the work you're requesting from people. Hope this helps.
    3 points
  41. Hello @rolandr welcome to the forum. I suppose it is this example that you meant? https://codepen.io/GreenSock/pen/rNOebyo?editors=1010 For that example to work within the structure you have in mind, keeping the same base of logic for the ScrollTriggers as in the example, you would actually have to expand the logic by quite a bit. There's a lot of things you will have to consider, when doing scroll-based animations like these, so getting a basic understanding of how the code triggering those works, will be essential to tweak them to get the result you'd like/need - unfortunatelly, even though GSAP and ScrollTrigger make all the things way easier than they would be without them, there is no out-of-the box magic tricks when it comes to things like these. Since I was intrigued myself, here is an example of how you could tackle things - but please note; these forums generally try to stay focussed on GSAP specific questions and are not intended to provide 'how-do-I-do-this-effect" ready-made code-solutions, as there will always be quite some thinking that has to go into effects like these. https://codepen.io/akapowl/pen/RwZwOey Some quick explanations: I changed the variable names in the JS from sections to panels because at some point when tinkering with this, I had to make a differentiation between scrollable sections and the .panel sections - I found that not to be neccessary in the end, but the name changes remain nonetheless. This whole concept relies on the animated .panel sections being wrapped in that .animation_container and the normal scrollable sections being wrapped in a .no_animation container All those are then again placed in a main container which serves as the trigger and thus the basis for the calculations of start and end of the ScrollTriggers Instead of setting the body's height beforehand accordingly with regard to the amount of panels as in the original example, I here rely on pinning for making the height adjust - I'm pinning a wrapper (.everything) around the whole thing here, for pinSpacing not to have a visible effect (so there will be no white-space added) The start & end of the ScrollTriggers now inlclude a getOffset() which basically loops over all the previous containers and adds up on value for those previous containers that don't have the animation/pinning going on (plus once the header's height). Additionaly in the setPanel-function I added a check for the first of each container's panels to only fade out when scrolling down and the last one of each container's panels to only fade out when scrolling up, so they remain visible when you scroll back to that container. and last but not least There might pretty certainly be an easier way of doing that - as in different scenarios usually different solutions make more sense, but I didn't want to stray away too far from the basic example's functionailty. Hope this will come in handy. Happy ScrollTriggering
    3 points
  42. Welcome to the forums @Ikuro1o There's no real CSS equivalent in the example code you just gave as CSS only works with DOM elements. If you'd like to know how GSAP works, I'd suggest checking out some of the Coding Math videos on tweening and easing (episodes 27-31). He even mentions GSAP. 😁 https://www.youtube.com/user/codingmath/videos
    3 points
  43. Hello @tibo78 It's really hard to tell from just a code-snippet of your JS code, that's why the forum guidelines state, that it's always best to add a minimal demo to your question. If your .btn-ripple and your .ripples are within the same container, you might just need to select the specific .ripples within that container the button you are looping over is in, something like gsap.utils.toArray(".btn-ripple").forEach(btn => btn.addEventListener("click", function(ev) { gsap.fromTo(btn.parentElement.querySelectorAll('.ripples'), { // <------ ... ... or if the .ripples are only just within that button it would just be gsap.utils.toArray(".btn-ripple").forEach(btn => btn.addEventListener("click", function(ev) { gsap.fromTo(btn.querySelectorAll('.ripples'), { // <------ ... Depending on how the structure of your HTML markup is, things might become more complicated though. Although this is not really GSAP specific in the first place, but more of a general JS question, your chances of getting a solid answer will be way higher with a minimal demo attached.
    3 points
  44. Welcome to the forums @Firmin Martin I would probably do things a bit different altogether. For one you don't really need two different forEach-loops, you can create the timelines with scrollTriggers for your containers from within that first forEach-loop you have for the sections by just targetting the sections container element. For the snapping I would probably juts create one extra ScrollTrigger, that 'spans' across the whole page-scroll. For the logic of the snapping, think about it this way: You have two states (starting-state and end-state of the animation of each section) with the duration of the pinning being equal to the duration of the free-scrolling in between sections (i.e. the window's height) so you could just take the number of your scenes, multiply that by 2 (because of the two 'states') and then in the end substract 1 (because snapping to 0 will be added automatically and you have to consider that). ScrollTrigger.create({ start: 0, end: "max", //snap: [0, 0.2, 0.4, 0.6, 0.8, 1] snap: 1/(scenes.length * 2 - 1) }); That could then look something like this: https://codepen.io/akapowl/pen/be907573a8ade3f0eea9076ce04a1083 That works just fine, but with a scenario like this you will run into following issue: Since you will be snapping to points where the pinning is just about to start/end and after snapping you continue scrolling up or down (depending on where you snapped to) you will be seeing nasty jumps of the pinned container - which is nothing ScrollTrigger can do much about because scrolling and js-processing are handled on two different threads by the browser. So here is another version including a suggested workaround for that by @GreenSock from this thread where it just offsets the snapping by a little bit depending on where you snap to. I'm not exactly sure if this is the simplest implementation of that workaround (because I had to also work around how JS is handling small numbers) but it works just about right. I Hope that will help Cheers. https://codepen.io/akapowl/pen/42a73ce2154cb620af866c6e3d90a394
    3 points
  45. That's really not something that can be tweened. Those waves have to be calculated dynamically on every animation frame. The demo you provided is probably about as simplified as you can get it. There are ways to do simpler waves with GSAP. Just search around the forum...
    2 points
  46. Hi there, It's hard to see without a minimal demo but I assume this is an SVG element and you're looking to use either svgOrigin: 168 163 or transformOrigin: center https://codepen.io/GreenSock/pen/waKrNj Note - if it is SVG make sure you have any fill-box declarations removed in your CSS too
    2 points
  47. No worries. Knowing that suppress events would work isn't obvious unless you've done a lot of work with GSAP.
    2 points
  48. Just for the record, if you wanted to reverse() a child animation and have it appear smooth/seamless, that requires that the startTime get adjusted accordingly and that means you must set smoothChildTiming: true on the parent. The playhead of child animations are always in sync with the parent, so imagine the playhead reaching the END of the child and then if you reverse() without adjusting that child's startTime, that means the playhead would now be at the START of that tween, thus the animation would instantly jump. To make it smooth, it would literally need to pick up that tween, flip it, and make its startTime wherever the playhead currently is on the parent. That's what smoothChildTiming: true is for. https://codepen.io/GreenSock/pen/ExvjYvm?editors=0010 (click to toggle the direction) But the way you're trying to do the reversing isn't a true reverse - it looks like you're trying to create separate tweens that operate on the playhead of a single one, thus the tweenTo() or tweenFromTo() is a great option. I just wanted to clarify the behavior with reverse().
    2 points
  49. Happy to help 1) It really isn't in the docs, didn't know that - I picked it up here in the forums. And yes, it is an accepted value; you can even see @GreenSock suggesting the use of it in this thread here. 2) By two "states" I meant The position of the container's top meeting up with the window's top edge and The position when the animation/pinning has finished in other words the ScrollTrigger's end "+=100%" - which is one window-height later. So basically you are right with regard to the pinning being responsible for it working like that. The equal heights of the pinSpacing added and the sections themselves are what's making the calculations I used work.
    2 points
  50. Hi Renny, Sure, that's relatively simple. Have you checked out the scrollTrigger docs? https://greensock.com/docs/v3/Plugins/ScrollTrigger If you set up a minimal demo with the necessary HTML and styling we'll be able to nudge you in the right direction.
    2 points
Γ—