All Activity
- Past hour
-
lienminhokvip joined the community
-
Ayush3513 joined the community
-
oscarsuarezdev joined the community
-
Tonya Lawrence joined the community
- Today
-
XYLIS_333 started following Is this the right way in vue?
-
louisjames2000 joined the community
-
solow joined the community
-
Sapristino joined the community
-
Umberto started following ScrollSmoother scrollTo not scrolling up
-
I have a question. How do I lock panels when scrolling? When I scroll to panel 2, panel 1 goes up, and I would like it to stop It's possible Thank you
-
fofo joined the community
-
IVolodymyr joined the community
-
Urban Panda Hostels changed their profile photo
-
trieuvy changed their profile photo
-
Any idea on how to Achieve this type of flip card animation ?
trieuvy replied to Chrisdag21's topic in GSAP
You can search for this animation using the keyword "Apple TV parallax." Some examples you can check out: https://codepen.io/iremlopsum/pen/WzKBpE https://codepen.io/thomasxiii/pen/MaByJa -
jingran started following can gsap make this section splitter?
-
https://mewsunfold.com/ the split line in this page is stretching as you scroll. I can't figure out how to implement this right now. is there any example code for this animation effect?
- Yesterday
-
CamiMarie started following Using GSAP ScrollTrigger for Horizontal Scroll
-
Hello! I am a total beginner and pretty sure this is a super basic question (apologies!), essentially I have directly copied a demo previously made in this thread which I have saved as my own (below). I don't need to alter the code except to change the image which is currently a random unsplash url. How do I change this to a media file uploaded to my wordpress gallery (elementor)? I have already tried directly renaming the url in the code below with the url provided in wordpress for the specific image I want to use but that didn't work... I don't quite understand how the ScrollTrigger code works in itself so have been deleting / renaming stuff randomly but sadly have not figured it out... @Rodrigo eternally grateful for any help you can provide! https://codepen.io/CamiMarie/pen/eYaYqWw muchas gracias
-
Issue with Scroll Position Resetting After Programmatic Scroll in GSAP
GreenSock replied to chillypills's topic in GSAP
Yeah, that doesn't look like it's GSAP-related at all. GSAP seems to be doing its job, but from what I can tell, you've got some other library or logic that's implementing a fake scrollbar and it's not getting updated properly when the window is scrolled to the appropriate position. I'd recommend looking at that library to figure out what it's doing (or not doing). Maybe there's some kind of update method you need to call from within an onUpdate on the scrollTo tween to get it to update that fake scrollbar to the correct position. We can't really do much if you don't provide a minimal demo (like a CodePen or Stackblitz) or if it's not a GSAP-related issue. Hopefully this gets you going in the right direction though. Good luck! -
Welcome to the forums, @Sandy Choudhary You should never animate the same element that you're pinning. Instead, just create a wrapper element that you pin instead: https://codepen.io/GreenSock/pen/JjqjQMV Is that what you're looking for?
- 1 reply
-
- 1
-
duck changed their profile photo
-
Chrisdag21 started following Any idea on how to Achieve this type of flip card animation ?
-
I'm trying to achieve this exact same flip card animation upon click as the Pokemon website. The cards should flip, enlarge and center in the middle of the screen exactly like this => https://tcg.pokemon.com/en-us/galleries/temporal-forces/#seeall Any ideas if and how I can achieve this with GSAP?
-
Hello Guys, while using scroll trigger iam getting two issue when scroll trigger is at end point then first-section-area is continue resizing and not stopped width height mention [ width:'235px', height:'235px',] for same as well giving 2 vertical scroll too. What iam trying to achieve that when scroll trigger reached to end point first section should stop resizing then able to apply second scroll trigger for second-section-area. Any help or reference is appreciated
-
ScrollTrigger animations triggered in fixed sections with fade in and out
xtinepak replied to SpaceHorse's topic in GSAP
Hi @Rodrigo Thank you, it was helpful. Thanks, Farhan -
I'm interested in this @ryan_labar – you're right I do need to re-math this for phones but I wondered why... surely the window innerWidth / svg width * 5 would be the same math on all devices?
-
Resolved i need to incorporate it by CDN
-
Hi thanks for the reply, To see my version break you need to scroll down until it is pinned and triggering one of the tabs, then change the vertical size of the browser window, then the markers jump for the pinned section to the top. Having said that, the version you have provided seems to fix the issue anyway, so thank you for providing it.
-
Adding will-change: transform to the Gallery text and to the elements with images improved the scroll function. Thank you for your help.
-
@Rodrigo I have this , but in console i have this error: Uncaught ReferenceError: Draggable is not defined Isn't free ? gsap.registerPlugin(Draggable, InertiaPlugin); function horizontalLoop(items, config) { items = gsap.utils.toArray(items); config = config || {}; let tl = gsap.timeline({ repeat: config.repeat, paused: config.paused, defaults: { ease: "none" }, onReverseComplete: () => tl.totalTime(tl.rawTime() + tl.duration() * 100) }), length = items.length, startX = items[0].offsetLeft, times = [], widths = [], xPercents = [], curIndex = 0, pixelsPerSecond = (config.speed || 1) * 100, snap = config.snap === false ? (v) => v : gsap.utils.snap(config.snap || 1), // some browsers shift by a pixel to accommodate flex layouts, so for example if width is 20% the first element's width might be 242px, and the next 243px, alternating back and forth. So we snap to 5 percentage points to make things look more natural populateWidths = () => items.forEach((el, i) => { widths[i] = parseFloat(gsap.getProperty(el, "width", "px")); xPercents[i] = snap( (parseFloat(gsap.getProperty(el, "x", "px")) / widths[i]) * 100 + gsap.getProperty(el, "xPercent") ); }), getTotalWidth = () => items[length - 1].offsetLeft + (xPercents[length - 1] / 100) * widths[length - 1] - startX + items[length - 1].offsetWidth * gsap.getProperty(items[length - 1], "scaleX") + (parseFloat(config.paddingRight) || 0), totalWidth, curX, distanceToStart, distanceToLoop, item, i; populateWidths(); gsap.set(items, { // convert "x" to "xPercent" to make things responsive, and populate the widths/xPercents Arrays to make lookups faster. xPercent: (i) => xPercents[i] }); gsap.set(items, { x: 0 }); totalWidth = getTotalWidth(); for (i = 0; i < length; i++) { item = items[i]; curX = (xPercents[i] / 100) * widths[i]; distanceToStart = item.offsetLeft + curX - startX; distanceToLoop = distanceToStart + widths[i] * gsap.getProperty(item, "scaleX"); tl.to( item, { xPercent: snap(((curX - distanceToLoop) / widths[i]) * 100), duration: distanceToLoop / pixelsPerSecond }, 0 ) .fromTo( item, { xPercent: snap( ((curX - distanceToLoop + totalWidth) / widths[i]) * 100 ) }, { xPercent: xPercents[i], duration: (curX - distanceToLoop + totalWidth - curX) / pixelsPerSecond, immediateRender: false }, distanceToLoop / pixelsPerSecond ) .add("label" + i, distanceToStart / pixelsPerSecond); times[i] = distanceToStart / pixelsPerSecond; } function toIndex(index, vars) { vars = vars || {}; Math.abs(index - curIndex) > length / 2 && (index += index > curIndex ? -length : length); // always go in the shortest direction let newIndex = gsap.utils.wrap(0, length, index), time = times[newIndex]; if (time > tl.time() !== index > curIndex) { // if we're wrapping the timeline's playhead, make the proper adjustments vars.modifiers = { time: gsap.utils.wrap(0, tl.duration()) }; time += tl.duration() * (index > curIndex ? 1 : -1); } curIndex = newIndex; vars.overwrite = true; return tl.tweenTo(time, vars); } tl.next = (vars) => toIndex(curIndex + 1, vars); tl.previous = (vars) => toIndex(curIndex - 1, vars); tl.current = () => curIndex; tl.toIndex = (index, vars) => toIndex(index, vars); tl.updateIndex = () => (curIndex = Math.round(tl.progress() * (items.length - 1))); tl.times = times; tl.progress(1, true).progress(0, true); // pre-render for performance if (config.reversed) { tl.vars.onReverseComplete(); tl.reverse(); } if (config.draggable && typeof Draggable === "function") { let proxy = document.createElement("div"), wrap = gsap.utils.wrap(0, 1), ratio, startProgress, draggable, dragSnap, roundFactor, align = () => tl.progress( wrap( startProgress + (draggable.startX - draggable.x) * ratio ) ), syncIndex = () => tl.updateIndex(); typeof InertiaPlugin === "undefined" && console.warn( "InertiaPlugin required for momentum-based scrolling and snapping. https://greensock.com/club" ); draggable = Draggable.create(proxy, { trigger: items[0].parentNode, type: "x", onPress() { startProgress = tl.progress(); tl.progress(0); populateWidths(); totalWidth = getTotalWidth(); ratio = 1 / totalWidth; dragSnap = totalWidth / items.length; roundFactor = Math.pow( 10, ((dragSnap + "").split(".")[1] || "").length ); tl.progress(startProgress); }, onDrag: align, onThrowUpdate: align, inertia: true, snap: (value) => { let n = Math.round(parseFloat(value) / dragSnap) * dragSnap * roundFactor; return (n - (n % 1)) / roundFactor; }, onRelease: syncIndex, onThrowComplete: () => gsap.set(proxy, { x: 0 }) && syncIndex() })[0]; } return tl; }
-
No it doesn't. if you go to page "about" in your stackblitz fork, scroll all the way down, and refresh the page 1, 2 times, the error still occures. this is something i have in a few production cases and breaks everything.
- 14 replies
-
- scrolltrigger
- nextjs
-
(and 1 more)
Tagged with:
-
Hello everyone, I'm currently facing an issue on a website that features a horizontally scrolling section. I've set up the site so that when a user clicks on a year from a menu, the page correctly scrolls to the corresponding element in the horizontal scroll section. However, after this scroll occurs and the target is reached, if the user attempts to manually scroll again, the scroll position automatically jumps back to where it was before the menu item was clicked. Here is a brief overview of the technologies and setup: JavaScript Libraries: I'm using GSAP for animations, with plugins like ScrollToPlugin and ScrollTrigger. Additionally, I'm integrating Swiper for swipe functionalities and Lenis for smooth scrolling effects. Behavior: Upon clicking a year in the menu, GSAP's ScrollToPlugin does its job to bring the target element into view. After reaching the target, any new user-initiated scroll action causes the page to revert to the original scroll position. Expected Behavior: The scroll position should remain at the new location after scrolling to the target, and any further manual scrolling should be based on this new position. I suspect there might be an issue with how the scroll position state is managed after a programmatic scroll, or perhaps there's a conflict between GSAP's scroll handling and Lenis's smooth scrolling. I've tried managing the update cycles of Lenis and ensuring the GSAP animations are synchronized with it, but the issue persists. I have also experimented with using flags and various methods to lock the scroll position temporarily, but nothing has resolved the issue so far. I'm doing it in Webflow so you can see the problem here: https://las-vidas-que-nos-dejaron.webflow.io/ // GSAP HORIZONTAL SCROLL LOGIC let isScrollingToYear = false // Add this line at the beginning of your script let horizontalItem = $('.horizontal-item') let horizontalSection = $('.horizontal-section') let moveDistance // Declare a variable to store the last scroll position // eslint-disable-next-line no-unused-vars let lastScrollPosition = 0 function calculateScroll() { // Desktop let itemsInView = 4 let scrollSpeed = 3 if (window.matchMedia('(max-width: 479px)').matches) { // Mobile Portrait itemsInView = 1 scrollSpeed = 1.2 } else if (window.matchMedia('(max-width: 767px)').matches) { // Mobile Landscape itemsInView = 1 scrollSpeed = 1.2 } else if (window.matchMedia('(max-width: 991px)').matches) { // Tablet itemsInView = 2 scrollSpeed = 1.2 } let moveAmount = horizontalItem.length - itemsInView let minHeight = scrollSpeed * horizontalItem.outerWidth() * horizontalItem.length if (moveAmount <= 0) { moveAmount = 0 minHeight = 0 // horizontalSection.css('height', '100vh'); } else { horizontalSection.css('height', '200vh') } moveDistance = horizontalItem.outerWidth() * moveAmount horizontalSection.css('min-height', minHeight + 'px') } calculateScroll() window.onresize = function () { calculateScroll() } let tl = gsap.timeline({ scrollTrigger: { trigger: '.horizontal-trigger', start: 'top top', end: 'bottom top', markers: false, invalidateOnRefresh: true, scrub: 1, }, }) tl.to('.horizontal-section .list', { x: () => -moveDistance, duration: 1, }) And function to scroll to the element with the given year and month ID (years menu) // Function to scroll to the element with the given year and month ID function scrollToYear(year, month) { const targetId = `#year-${year}-${month}` const targetElement = $(targetId) if (targetElement.length) { // Set the flag to true isScrollingToYear = true console.log('Is scrolling to year enabled?', isScrollingToYear) // Calculate the target scroll position const scrollX = targetElement.position().left console.log('Target scroll position:', scrollX) // Log the current scroll position console.log( 'Current scroll position:', $('.horizontal-section .list').position().left ) // Save the current scroll position lastScrollPosition = $('.horizontal-section .list').position().left // Animate the horizontal scroll to the target element's X position gsap.to('.horizontal-section .list', { x: () => -scrollX, duration: 3, ease: 'power3.inOut', onUpdate: Lenis.update, // Assuming lenis.update is the method that needs to be called on update onComplete: () => { console.log( `Smoothly scrolled to the year: ${year} and month: ${month}` ) // Remove --is-active class from any other elements that might have it $('.horizontal-section .list .--is-active').removeClass('--is-active') $('.horizontal-month-item.--is-active').removeClass('--is-active') // Add --is-active class to the target element targetElement.addClass('--is-active') // Format the month to have two digits const formattedMonth = month.toString().padStart(2, '0') // Find the corresponding .horizontal-month-item and add the --is-active class const targetMonthItem = $( `.horizontal-month-item[data-month="${formattedMonth}/${year}"]` ) if (targetMonthItem.length) { targetMonthItem.addClass('--is-active') } // Update the sticky title gsap.to('.sticky_title', { duration: 0.2, autoAlpha: 0, onComplete: function () { $('.sticky_title').text(year) gsap.to('.sticky_title', { duration: 1.5, autoAlpha: 1 }) // Log the current scroll position after the animation console.log( 'Current scroll position after animation:', $('.horizontal-section .list').position().left ) // Set the flag back to false isScrollingToYear = false console.log('isScrollingToYear enabled?', isScrollingToYear) // Update the move distance directly moveDistance = -$('.horizontal-section .list').position().left }, }) }, }) } else { alert(`No element found with ID: ${targetId}`) console.error(`No element found with ID: ${targetId}`) } }
-
Hi Rodrigo, thanks for your help. Unfortunately I've seen these examples before and haven't really managed to adapt the codepen I sent. And in your examples, the sections swipe but in my case, I would need to animate several elements per section, and I'm stuck on it, I don't know why
-
Alright, thank you for your help! Really appreaciate it.
-
Thank you for the info.....
-
Hi @Rodrigo, Thank you for your help, really appreciate it. Actually what I need card should hide on right with opacity 0 when user scroll down and should appear from the left . I have tried to modify the duration in your code and right now cards are hidding on scrolltrigger but they aren't appearing from the left. Same goes for scrollup event card should hide in the left and should appear from the right. Here is new codepen which I have modify with the duration. Any hint or help would be appreciated. Thanks in advance! https://codepen.io/dhamarobin/pen/BaearVR
-
Section not shrink equally on both side
Sandeep Choudhary replied to Sandeep Choudhary's topic in GSAP
@GreenSock Thanks for suggestion its worked. -
188bet15242 changed their profile photo
-
ScrollTrigger and cards animating vertically
Rodrigo replied to Fernando Matias Cohen's topic in GSAP
Hi, I don't have time now to dig into your code, but you could check @Carl's video on staggers and sequences: Hopefully this helps. Happy Tweenig! - Last week
-
Hi, Maybe something like this: https://codepen.io/GreenSock/pen/VwOwymP Hopefully this helps. Happy Tweening!
-
ScrollTrigger and cards animating vertically
Fernando Matias Cohen replied to Fernando Matias Cohen's topic in GSAP
I feel like I'm close to achieving at least the vertical slide animation, the cards appear one at a time correctly and go up, but I have 2 problems. The snap is not positioned well, since the card is not centered in the scroll, and when I scroll up, it seems that there is a glitch in the animation, could you guide me a little with that? https://codepen.io/designfenix/pen/bGybyrd?editors=0010 -
Does it solve it for you if you set immediateRender: false on the ScrollTrigger?: https://stackblitz.com/edit/stackblitz-starters-vynow2?file=src%2Fcomponents%2FHeroIntro%2FHeroIntro.js,src%2Fservices%2Fgsap.js
- 14 replies
-
- scrolltrigger
- nextjs
-
(and 1 more)
Tagged with: