Jump to content
Search Community

Search the Community

Showing results for 'page transition' in content posted in GSAP.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • GreenSock Forums
    • GSAP
    • Banner Animation
    • Jobs & Freelance
  • Flash / ActionScript Archive
    • GSAP (Flash)
    • Loading (Flash)
    • TransformManager (Flash)

Product Groups

  • Club GreenSock
  • TransformManager
  • Supercharge

Categories

There are no results to display.


Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Personal Website


Twitter


CodePen


Company Website


Location


Interests

Found 13,347 results

  1. Hello! I haven't asked for help in a while, but I haven't used Gsap in a while, so I'm a little rusty. I'm having trouble with a transition that I think should be pretty easy, but I'm getting tangled, I just need the section to be pinned, and that as you scroll, a card is positioned in the middle at the title level, and in the next scroll, that card goes up, and the second one remains, etc.. then I have I have to refer it to a page that is on the right side vertically, but I later see how to solve it, mainly I am getting dizzy with the snap and stagger
  2. I really can't do it, I'm nowhere near crying, I already achieved the transition like the video you shared with me, but I still need to make some changes that I can't achieve. I thought about doing a forech to be able to detect if it is the first card, that it is visible and only goes up, the rest of the card should act normally, they appear and disappear, and if it is the last one it only appears, it does not have to disappear. like a vertical slider. and then I have to apply the same logic with the navigation, once I achieved those animations I thought to see how to add a label to each card animation, to relate the navs when clicking to make me scroll to that card animation. could you give me a little help? Tell me that I'm doing everything wrong.
  3. Asking the following with a concern for performance, rather than code cleanliness or reusability: Is one better off using a single Scrolltrigger, or multiple, when animating elements across different components, but all on the same page? Some context — I'm using useGSAP in React (Next) to animate a timeline with Scrolltrigger that runs the length of a landing page. The elements animated are contained across several components, representing different sections of the page. On one hand, it is obvious to me that a single Scrolltrigger is less overhead than multiple (less initialization etc.). On the other hand, I'm unsure what GSAP does behind the scenes as far as ignoring out of viewport elements and so on. So - if I am using a single Scrolltrigger (less overhead), could I still be incurring more cost, since GSAP is tracking elements I no longer care about? Am I just better off using multiple Scrolltriggers and aggressively scoping? If anyone has any repos or sandboxes demonstrating suggested patterns that'd be much appreciated. (Hopefully higher level/concept questions are okay - and sorry if this is something touched on already - I tried searching for several minutes but couldn't find anything satisfactorily clarifying. Thanks!)
  4. Hello guys, Kindly help me figure this out. I have full page sections sliding to top on scroll. I want the sections pinned to top giving that stacked effect. So, I can kind of achieve that when I set position to sticky in css, but they don't unstick and slide down when you scroll back down. How can I correct that? or how can I achieve the stacked effect.
  5. Hello, I created a simple scrolltrigger animation that shows text when a card become visibile in the screen. Since I have multiple similar cards on my page, I thought it would be good to apply the same code to all of them together. I tried with a loop but it seems not to be working, can you help me understand what I'm missing? Thanks!
  6. i want create button same home page gsap.Who's that helpme.
  7. Hi, (stack : Next JS) i'm close to achieve an effect but am stuck! Here is the result of where i am for now : https://youtu.be/tXUPHLRPiDA As you can see, I'd like to make a transition on clicking to a project thumbnail. Problem : I don't want the container to scaleY up, but i want to keep the infos/image inside to a normal ratio. I tied to animate height, instead of scaleY, but then I have to also animation the scrollTo, and it was a bit messy... Here is the ProjectThumb component (I do have a project list with several ProjectThumb) : import React, { useRef, useState } from "react"; import { useGSAP } from "@gsap/react"; import gsap from "gsap"; import { lineAnimation, projectContainerAnimation, scrollAnimation, subtitleAnimation, titleAnimation, } from "../animations/animations"; import { ScrollToPlugin } from "gsap/ScrollToPlugin"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import Image from "next/image"; import { useRouter } from "next/navigation"; gsap.registerPlugin(ScrollTrigger); gsap.registerPlugin(ScrollToPlugin); const ProjectThumb = ({ project, setClicked, clicked, }: { project: any; setClicked: React.Dispatch<React.SetStateAction<number | null>>; clicked: number | null; }) => { const lineRef = useRef<HTMLDivElement>(null); const thumbContainerRef = useRef<HTMLDivElement>(null); const titleRef = useRef(null); const subTitleRef = useRef(null); const imageRef = useRef(null); const router = useRouter(); const [timeline, setTimeline] = useState<any>(); const [timeline2, setTimeline2] = useState<any>(); // set line animation timeline up useGSAP(() => { if (lineRef.current) { const tl2 = gsap.timeline({ scrollTrigger: { trigger: lineRef.current, start: "top 85%", toggleActions: "play end resume reverse", }, }); tl2.add(lineAnimation(lineRef)); setTimeline2(tl2); } }, [lineRef]); // Set project elements timeline up useGSAP(() => { const tl = gsap.timeline(); setTimeline(tl); // show off all project container but the one clicked if (clicked && clicked !== project.id && thumbContainerRef.current) { timeline.to( thumbContainerRef.current, { opacity: 0, duration: 0.5, }, `<${Math.abs((clicked - project.id) * 0.5) / 3}` ); } }, [clicked, thumbContainerRef]); const handlePlayAnimation = () => { if ( thumbContainerRef.current && subTitleRef.current && titleRef.current && timeline2 && timeline ) { setClicked(project.id); timeline2.clear(); timeline2.to(lineRef.current, { scaleX: 0, duration: 0.5, }); const offset = window.innerHeight * 0.5 - thumbContainerRef.current.getBoundingClientRect().height / 2 - 32; const thumbContainerScale = window.innerHeight / thumbContainerRef.current.getBoundingClientRect().height; timeline .add(scrollAnimation(thumbContainerRef, offset)) .add(titleAnimation(titleRef), "-=0.4") .add(subtitleAnimation(subTitleRef), "-=0.25") .add( projectContainerAnimation(thumbContainerRef, thumbContainerScale), "<=0.3" ); // .then(() => router.push(`/projects/${project.id}`)); } }; return ( <div className={`project_container_${project.id} overflow-hidden min-h-[25vh] relative`} ref={thumbContainerRef} > <div ref={lineRef} className="projectLine scale-x-0 h-2 bg-slate-500 opacity-100" ></div> <div onClick={handlePlayAnimation} className="project_infos button absolute w-full h-full z-10 cursor-pointer" > <div></div> <div className="project_title flex gap-4 p-8 items-end text-white" key={project.id} > <h3 ref={titleRef} className="project_title text-2xl w-full text-slate-800" > {project.title} </h3> <p ref={subTitleRef} className="project_subtitle w-full text-slate-800" > {project.subtitle} </p> </div> </div> <Image ref={imageRef} src={project.images.thumbnail} width={1920} height={1080} alt={project.title} className="h-full object-cover aspect-square opacity-30 absolute" /> </div> ); }; export default ProjectThumb; And here are the animations called by the previous component : import gsap from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import { ScrollToPlugin } from "gsap/ScrollToPlugin"; gsap.registerPlugin(ScrollTrigger); gsap.registerPlugin(ScrollToPlugin); export const lineAnimation = (ref: any) => { return gsap.to(ref.current, { scaleX: 1, transformOrigin: "left", duration: 0.75, }); }; export const thumbContainerAnimation = (ref: any) => { return gsap.to(ref.current, { height: "100vh", transformOrigin: "top center", duration: 1, ease: "expo.in", }); }; export const scrollAnimation = (ref: any, offset: number) => { return gsap.to(window, { duration: 0.75, scrollTo: { y: ref.current, offsetY: offset }, ease: "expo.inOut", }); }; export const titleAnimation = (ref: any) => { return gsap.to(ref.current, { duration: 0.4, y: -50, opacity: 0, ease: "expo.in", }); }; export const subtitleAnimation = (ref: any) => { return gsap.to(ref.current, { duration: 0.35, y: -50, opacity: 0, ease: "expo.in", }); }; export const projectContainerAnimation = (ref: any, scale: number) => { return gsap.to(ref.current, { scaleY: scale, transformOrigin: "center", duration: 1.2, ease: "power4.inOut", }); };
  8. Hello, Im just trying to get ScrollSmoother working on astro web, with new astro view transition Api. During the first page load, everything work as expected. But when Im transitioning to another page, the scrollSmoother stops working. It looks like during the initialisation of ScrollSmoother, it doesnt inject styles into the <body> tag, so there is scrollbar missing and users cant scroll the page. I also tried to set the styles manually loke this: useEffect(() => { const wrapperHeight = document.getElementById("smooth-content")?.offsetHeight; const smoother = ScrollSmoother.create({ smooth: 0.4, effects: true, }); if (document) { document.body.style.height = `${wrapperHeight}px`; document.body.style.overscrollBehavior = "none"; document.body.style.scrollBehavior = "auto"; } return () => { smoother.kill(); if (document) { document.body.style.height = ""; document.body.style.overscrollBehavior = ""; document.body.style.scrollBehavior = ""; } }; }, []); But unfortunatelly, the height is calculated wrong ( shorter than it should be ), and the ScrollSmoother is flickering ( somewhere about the half of the page, it jumps to the top of the page ). I've also tried to initialize and kill ScrollSmoother in Astro lifecycle hooks, in React component, and even in Vue components. Without view transitions, everything works as expected. Thanks for answer.
  9. Hello, I have a Flip transition that animates between a single column and a grid layout. This works, however there is further control + logic required to get the transition to feel smooth and to handle which images transition into view, as well as the position of the viewport during this transition. Here is my current implementation: Stackblitz and here is a good example of what I am trying to achieve with a smooth transition on another website (click the `index` button in the top right corner of the page to see the transition I am aiming for). This may not be strictly a GSAP question, and if not please disregard, though I am curious if anyone may have any pointers on what could help to get my transition closer to the linked example website. From what I can observe, the linked example improves the Flip by achieving the following: From grid view > column view, the grid view keeps track of which row is at the top of the viewport and always transitions so that the top row are the images that move into view in the single column view From column view > grid view, the image in view transitions into the top row of the grid The change in the height of the page is managed so that the viewport position does not end up away from the items on which the transition started, i.e. the items in view at the start of the transition stay in view throughout and until the end of the transition
  10. Hi guys, I'm trying to recreate the scaling effect that Apple is using for their Apple Watch page (https://www.apple.com/watch/), but haven't achieved the desired result yet. Currently, I'm using scale to shrink the images as I scroll down, it works as expected but the image shrinks along with its container frame. I want only the container frame to shrink while the image maintains its original size, similar to this video (https://streamable.com/n9xj3e).
  11. 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?
  12. 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}`) } }
  13. Hello, I am trying to animate a counter that animates a number from 0-x where x is some target number. The animation works but when I want it to happen on ScrollTrigger, it doesn't work. I followed GSAP guidelines and "Common Mistakes" but it still not working. Expected result: The counter should animate when a user sees the number on different devices. Actual result: The counter animates as soon as the page refreshes. How to reproduce the problem: Refresh the page or scroll to the bottom of the page then hit refresh and wait for 5 seconds then scroll up and the animation finishes. EDIT: The stackbit URL to the demo mentioned in GSAP guidelines: https://stackblitz.com/edit/stackblitz-starters-rvhe3n?file=app/page.tsx
  14. Hello, This question builds off of a previous question about multiple scrollTriggers, with some added elements concerning page refresh and triggering the scrollTrigger from the reverse direction. Outline: Page has a small header logo, that only appears when the user begins to scroll. Page has a large logo that appears on page load, that disappears when the user begins to scroll. Problem: The scrollTriggers work well on first load, but when the page is refreshed the #headerlogo appears immediately regardless of the scrolled position. Toggle action to play in reverse when scrolling back to top not working for me currently. Aim: Both logos should not be visible at the same time. #headerlogo fades in when scrolling past scroll trigger at top of viewport. #largelogo fades out when scrolling past scroll trigger at top of viewport. Animations play in reverse when returning to top of viewport. This site has the exact behaviour I am trying to achieve: https://www.magdabutrym.com/de-en Here is my current progress in this Stackblitz demo: Stackblitz link Many thanks for reading!
  15. useGSAP(() => { gsap.registerPlugin(ScrollTrigger) const rwd = gsap.timeline({ scrollTrigger: { trigger: ".rewardCard .s-block", pin: ".rewardCard .s-block", // pinSpacing:true, // pinnedContainer: ".s-block", markers: true, start: "top top", end: "bottom+=2000 top", scrub: 2, pinReparent:true, onRefresh: (e) => { console.log('erefresh', e); }, }, }); rwd.fromTo(".rwd-box:nth-child(2)", { xPercent: 93 }, { xPercent: 7 }); rwd.fromTo(".rwd-box:nth-child(3)", { xPercent: 100 }, { xPercent: 14 }); return () => { // console.log(`rwd==>`, rwd.vars.scrollTrigger); rwd.vars.scrollTrigger.onRefresh() ScrollTrigger.revert(); }; }); <div className="rewardCard"> <div className="s-block" > <div className="container" > <div className="rwd-area" > {data.map((card, ind) => { return ( <div className="rwd-box absolute" key={card} > <div className="rd-titl "> <h6>{card[0]}</h6> </div> <div className="d-lg-flex align-items-center"> <div className="rd-img"> <img src={card[3]} className="img-fluid animated bobo" alt="" /> </div> <div className="rd-cont"> <h4>{card[1]}</h4> {Ctext(card[2], "blue-tx")} <a className="btn-default" href={card[4]}> Learn more </a> </div> </div> </div> ); })} </div> </div> </div> </div>
  16. 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.
  17. I've been working with GSAP for quite some time now, utilizing the GSAP Premium Version. Specifically, I integrate GSAP into next.js applications (SSR). I've reviewed numerous documentation resources on GSAP/next.js and believe I'm employing GSAP according to best practices. For the most part, everything functions smoothly. However, I'm encountering issues with the Scrolltrigger. Whenever I bind animations to a Scrolltrigger that uses a React Ref (useRef) as a "trigger," errors consistently arise. During the initial load of a very long page, components on the page utilizing a Scrolltrigger sometimes throw an error: "Cannot read properties of undefined (reading 'end')." This problem seems to be related to the Scrolltrigger not having an element available. It is also the case that if I set the trigger via React ref, an error is thrown, but if the trigger is set via CSS class, no error is displayed. scrollTrigger: { invalidateOnRefresh: true, start: 'top center', trigger: containerRef.current // throws errors sometimes } scrollTrigger: { invalidateOnRefresh: true, start: 'top center', trigger: '.container' // throws no error, seems not working properly all the time } According to the documentation, there's an option to set nullTargetWarn: false in gsap.config, but this doesn't suppress the errors being thrown. Somehow, this seems to be related to SSR of the component, as the errors seem to disappear when I don't load the React component via SSR. I'm employing common patterns, such as "useIsomorphicLayoutEffect" or checking within the hook if the Ref element exists. However, this doesn't seem to resolve the issue either. import { useEffect, useLayoutEffect } from 'react' export const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect const List = ({ title, titleSize = 2, subtitle, items }) => { const containerRef = useRef() const listItemsRef = useRef([]) useIsomorphicLayoutEffect(() => { if (!containerRef.current) return const ctx = gsap.context(() => { gsap.to( listItemsRef.current, { clipPath: 'polygon(0% 100%, 100% 100%, 100% 0%, 0% 0%)', duration: 1, opacity: 1, scrollTrigger: { invalidateOnRefresh: true, start: 'top center', trigger: containerRef.current }, stagger: 0.2, y: 0 }, 0 ) }, containerRef) return () => ctx.revert() }, []) return ( <div ref={containerRef}> ... gsap.config({ nullTargetWarn: false }) The error is quite ugly because on the production environment, the entire frontend crashes if the error is thrown and not caught manually. Does anyone have any tips on what might be causing this?
  18. Hello, I am trying to animate an element in when the page loads, and also whenever the user starts to scroll I want to animate that same element out. So far I am able to achieve this, but not optimally, because the out animation is not exhibiting the specified duration. The out animation is triggered with scrollTrigger, and it simply should animate the autoAlpha to 0, to make the element disappear over a duration of 2 seconds. Currently, it abruptly disappears, rather than animating out for the course of the specified duration. Here is my minimal reproduction to demonstrate my issue: Stackblitz To summarise what I am trying to achieve: 1. Logo fades in on page load 2. When user begins to scroll down, the logo fades out as a result of a scrollTrigger Currently happening: 1. Logo fades in on page load 2. Logo disappears abruptly without fading out when scrollTrigger is triggered Notes: 1. If the useGSAP() code for the scrollTrigger is moved to the parent, to the page level, the scroll trigger animation fades out as intented — but only when I change the gsap.to() to a gsap.fromTo(). I don't understand why. 2. Moving this code to the page level solves the scrollTrigger (somewhat) but there is a new issue with the logo flashing when the page loads. Many thanks in advance for any suggestions on where I am going wrong
  19. Hi @WEB1995. That's actually a super complex thing to try to do because you've got some wild variation in the direction and pacing of the line. At some points the line is going UP...but you're scrolling DOWN. And sometimes it's going directly horizontal (so no vertical movement at all), while the page is scrolling down. So logically, it's literally impossible to have it "centered" the whole time (if the page is moving down and the line is moving up, see the problem?). You can sort of approximate things with the magic of that pathEase() helper, but it'll never be perfect: https://codepen.io/GreenSock/pen/BaeaZqd?editors=1010 The only way to have it perfectly centered is to take an entirely different approach, like by putting everything in a container that you then translate it dynamically to keep it centered. That's not a super simple thing either, and it's well beyond the kind of help we can provide for free in these forums, but you can contact us for paid consulting services. I hope that helps!
  20. Using killAll is still being called. Since now my page is loading repeatedly it crashes so I'm looking for the cause https://github.com/hengshanMWC/gsap-ScrollTrigger gsap@3.12.5
  21. I see a lot of people hung up on creating buttons to scroll to a particular point on a page while using ScrollTrigger. Of course GSAP has you covered with this! See the ScrollTo plugin! But as with everything in GSAP it starts with an animation. First of please read my post about creating a stacking card effect, it will be used for the bases of this post So as usual everything in GSAP starts with an animation, so you first have to have an animation before you start doing anything on scroll, first focus on creating the animation you want to happen and when that is done we can worry about enhancing it with some scrolling https://codepen.io/mvaneijgen/pen/WNWqEYx If you’re happy with the animation you can add some ScrollTrigger logic to see how your animation works on scroll. https://codepen.io/mvaneijgen/pen/OJGevrB?editors=0010 Ok, now for the reason you’re here. How can we have a button that scrolls to a certain position on the page? That is where the ScrollTo plugin comes in, if you check the docs (https://gsap.com/docs/v3/Plugins/ScrollToPlugin/), the most simple setup is to just animate to a pixel value, let’s see how that works! The below example scrolls to 1000px, simple enough but I hope it illustrates what it is doing under the hood, because scrolling to a specific section will be nothing more than getting the pixel value you want to scroll to and using this as the value in the scrollTo: property! https://codepen.io/mvaneijgen/pen/JjVQOyK But now we want to scroll to the third card in the animation, how can we do this? We know the total scroll distance of the ScrollTrigger because we define that in the start and end properties, right now the ScrollTrigger starts on the top of the browser and has a distance of 4 times the current window height (end: `${window.innerHeight * 4} top`) and we have in total 4 animations! This means each slide animates over the hight of the window, so what do you think will happen if we animate to the current window hight times 2? Well let's see! https://codepen.io/mvaneijgen/pen/BaEgwoz It animates to the third slide! As you can see I’ve wrapped the code in an arrow function, this indicates to GSAP that we want to recalculate this value if ScrollTrigger.refresh() is triggered, which happens on a page resize, because when the page resized probably the height of the browser changes, so we need to get new values. If you do not use a function based value you indicate to GSAP that it should not recalculate it’s values and can use its cached values. If you want to read more please check out the docs https://gsap.com/docs/v3/GSAP/gsap.to()/#function-based-values Great we’re done! lets add some more content to the page and everything will be working just fine! But wait!? Why does it now only scroll to the second slide? Before it was scrolling to the third slide. Well all ScrollTrigger is doing is animating to a specific pixel value and because we’ve add another section before it, the scroll distance will be different. What you can do in this case is add the ScrollTrigger start value to the calculations, so instead of just animating to twice the window height, we animate to tl.scrollTrigger.start + window.innerHeight * 2, just try it your self and you’ll see it will always scroll to the top of the ScrollTrigger + twice the window height https://codepen.io/mvaneijgen/pen/BaEgwoz Ok, I hear you thinking, but I want to animate to each slide, and what if my scroll distance changes then I need to update my calculations every where! You are totally right! And the folks on the GSAP team has thought of everything! So what you can do is add labels to your timeline and then scroll to those labels! This can be as simple as scrolling to a specific label eg tl.scrollTrigger.labelToScroll("label3") or this can be be fancy like the example below by getting the next label in the timeline and scrolling to that, I hope you see that you can as easily scroll to the previous label. https://codepen.io/mvaneijgen/pen/gOyNeqj?editors=0010 If you don't have labels in your timeline you can also do some math to scroll to a specific point in a timeline. The progress of a timeline is always between 0 and 1, so what you can do is get the end and start values of you ScrollTrigger and then subtract and then multiply that by 0.5 to that the halfway point of the animation or any other value! Again to emphasise all ScrollTo need is a pixel value and it is up to you to get the correct value. GSAP gives you all the tools you need, but it is for you to figure out what the math is behind the logic you are looking for! Hope it helps and happy tweening!
  22. Hey guys, I need a little help with this one. I have single section want to use multiple time in same page with same animation but different content . when i use same section its breaking the animation . Pls advice. Many thanks
  23. You still have transition: all 0.25s ease; in your css which is conflicting with your JavaScript animations. highly recommend removing this and never to use transition: all 0.25s ease! Just change all to the property you want to transition eg transition: opacity 0.25s ease; but glad you’ve solved your issue. Happy tweeting
  24. Hi I'm quite new to GSAP and having an issue I can't figure out. I have full width section that pins when it gets to the top of the window, then inside that section I have scrolltrigger which toggles the class on some tab sections to open them as you scroll. This works well until the browser is resized, then the markers for the tabs jump to the top of the page and therefore aren't being triggered any more. You can see it on the lower green section of my dev site https://avidd2024.dev.avidd-design.co.uk if (window.innerWidth > 640) { // Pin the tabs container when a tab title is active const tabsContainer = document.getElementById("pintrigger"); gsap.to(tabsContainer, { scrollTrigger: { trigger: tabsContainer, start: 'top 0', // When to start pinning at the top of the screen end: '+=1000', // Unpin after scrolling 1000px past the start pin: true, // Pin the element pinSpacing: true, // Maintain the pinned element's position invalidateOnRefresh: true } }); } // Loop through each tab title and define ScrollTrigger const tabTitles = document.querySelectorAll(".vertical .tabs-title"); tabTitles.forEach((tabTitle, index) => { gsap.to(tabTitle, { scrollTrigger: { trigger: tabTitle, start: "top top", // Start when top of tab title reaches top of screen end: "bottom top", // End when bottom of tab title reaches top of screen scrub: true, invalidateOnRefresh: true, toggleClass: { targets: tabTitle, className: "is-active" }, onToggle: (self) => { const panelId = tabTitle.querySelector('a').getAttribute('href'); const panel = document.querySelector(panelId); } } }); }); <section class="primary-color full-width" > <div class="block-tab-container" id="pintrigger"> <?php if (have_rows('repeater_content_tab')) { $counter = 0; ?> <ul class="tabs vertical" data-responsive-accordion-tabs="small-accordion medium-tabs" data-multi-expand="true" id="<?php echo esc_attr($id); ?>"> <?php while (have_rows('repeater_content_tab')) { the_row(); $tab_heading = get_sub_field('tab_heading'); $counter++; ?> <li class="tabs-title"> <a href="#tab<?php echo $counter?>-<?php echo esc_attr($id); ?>" aria-selected="true"> <div class="tabs-title-container"> <div class="text"><?php echo $tab_heading ?></div> </div> </a> </li> <?php } ?> </ul> <?php $counter = 0; ?> </div> <div class="tabs-content secondary vertical" data-tabs-content="<?php echo esc_attr($id); ?>"> <?php while (have_rows('repeater_content_tab')) { the_row(); $tab_content = get_sub_field('tab_content'); $counter++; ?> <div class="tabs-panel" id="tab<?php echo $counter?>-<?php echo esc_attr($id); ?>"> <?php echo $tab_content ?> </div> <?php } ?> </div> <?php } ?> </div> </section>
  25. Hi, This is not actually related to GSAP but just the way browsers work and the inner works ScrollTrigger has to do in order to do it's calculations. ScrollTrigger takes the page back to the top in order to make the calculations and make sure everything is rendered and positioned the way it should, something that is more difficult if the scroll position is not at the top. In your particular case, since you have toggleActions in your setup, that tells ScrollTrigger to play the timeline which hides the large logo and shows the small one. What you could try is to store if the scroll is more than 0 (meaning that is not at the top) in local/session storage. Then when the page is refreshed you check that if it is, you could set the timeline's progress at 1. Maybe the ideas in these threads could help: Hopefully this helps. Happy Tweening!
×
×
  • Create New...