Jump to content
Search Community

All Activity

This stream auto-updates

  1. Past hour
  2. Today
  3. 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?
  4. 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
  5. 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?
  6. Resolved i need to incorporate it by CDN
  7. 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.
  8. Adding will-change: transform to the Gallery text and to the elements with images improved the scroll function. Thank you for your help.
  9. @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; }
  10. 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.
  11. 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}`) } }
  12. 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
  13. Alright, thank you for your help! Really appreaciate it.
  14. 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
  15. @GreenSock Thanks for suggestion its worked.
  16. 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!
  17. Yesterday
  18. Hi, Maybe something like this: https://codepen.io/GreenSock/pen/VwOwymP Hopefully this helps. Happy Tweening!
  19. 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
  20. 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
  21. Howdy, brothers and sisters of the green sock. I'm getting up to speed on GSAP and while trying to dial in the type of ease I want for something, I was playing around with the Easing Visualizer of course. I noticed some of them take parameters but I cannot for the life of me find any documentation on what those parameters are in the official docs. After much searching outside the forum I found one or two old references mentioning amplitude and frequency for elastic but I like to be able to see the docs for the others as well. Are they right under my nose and I'm just overlooking them? Are they not documented? Appreciate any help!
  22. Hey Fernando! I don't know if there is a single demo around that does everything you need, so most likely this will reduce to get inspiration and bits from several of them. Here are others that can definitely help: https://codepen.io/GreenSock/pen/poBRQRj https://codepen.io/GreenSock/pen/BaMOapv https://codepen.io/GreenSock/pen/rNbELKO https://codepen.io/GreenSock/pen/xxjErmp https://codepen.io/GreenSock/pen/wvrXRdZ It's always a good idea to keep these collections in your bookmarks just in case: https://codepen.io/collection/AEbkkJ https://codepen.io/collection/DkvGzg Hopefully this helps, Happy Tweening!
  23. Hi @BiKe and welcome to the GSAP Forums! Maybe this demo can help: https://codepen.io/GreenSock/pen/YzgGwpM Hopefully this helps, Happy Tweening!
  24. Hi, Sorry but I really don't understand what the issue is here exactly. I tested your demo and tried different screen sizes and everything is working as it should. The only advice I would offer is to not make the body tag a flex container. Also I would advice you to create the ScrollTrigger that is pinning the container after creating the ScrollTriggers of the tabs, since those are not pinned they don't affect the start/end position of the pinned one, but the pinned one does have an impact because of the pin space is created. I'm not sure if you're looking for something like this: https://codepen.io/GreenSock/pen/GRaROvZ Hopefully this helps. Happy Tweening!
  25. Hey Rodrigo - totally understood, and hope my comment wasn't rude. The machine I mentioned indeed struggles (when my hundred+ tab browsers are open anyway). Since perf is my north star, it comes in handing for testing and setting a reliable criterion for acceptable frames. But woah, yeah, I would've def gone with canvas or three - didn't realize that was all SVG! Totally get it with clients sometimes tho - dealing with a headache right now as well (unrelated to the SVG question above).
  26. I found the error... it's on an import.
  1. Load more activity
×
×
  • Create New...