Jump to content
Search Community

All Activity

This stream auto-updates

  1. Past hour
  2. Today
  3. 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
  4. 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
  5. 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?
  6. Yesterday
  7. 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
  8. 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!
  9. 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?
  10. 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?
  11. 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
  12. 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?
  13. Resolved i need to incorporate it by CDN
  14. 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.
  15. Adding will-change: transform to the Gallery text and to the elements with images improved the scroll function. Thank you for your help.
  16. @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; }
  17. 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.
  18. 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}`) } }
  19. 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
  20. Alright, thank you for your help! Really appreaciate it.
  21. 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
  22. 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!
  23. Last week
  24. Hi, Maybe something like this: https://codepen.io/GreenSock/pen/VwOwymP Hopefully this helps. Happy Tweening!
  25. 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
  26. 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
  1. Load more activity
×
×
  • Create New...