Jump to content

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

Search the Community

Showing results for tags 'gsap3'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


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

Product Groups

  • Club GreenSock
  • TransformManager
  • Supercharge


  • FAQ


  • Examples
  • Showcase


  • Products
  • Plugins


  • Learning Center
  • Blog


  • ScrollTrigger Demos


There are no results to display.

Find results in...

Find results that contain...

Date Created

  • Start


Last Updated

  • Start


Filter by number of...


  • Start



Personal Website



Company Website



  1. I've reached my witts end here, I have been trying to solve this issue for the past hour or so but with no avail. I created an animation with GSAP that creates an illusion that you are zooming into a planet, then the planet will disappear and a random image of a lake with large rocks will appear and two text boxes appear, one of them with a button. Once you click on the button, the image of the lake and the two text boxes will disappear and another image of the night sky will take its place. Everything works well up to this point, however, when I resize the viewport, the image of the night sky disappears and the image of the large rocks appears again when it shouldn't. I've included the CODEPEN for this but I can't recreate the bug/error. gsap.timeline({ scrollTrigger: { trigger: ".earth_container", start: "-20% 0%", markers: false } }) .to(".earth_planet", { width: "+=2500", height:"+=2500", duration: 3 }) .set(".earth_container", { backgroundImage: "url('https://i.postimg.cc/Dy9ryPpB/earth-forest.jpg')", backgroundSize: "cover" }) .to(".earth_planet", { opacity: 0 }) .from(".text_info_box_earth_one", { opacity: 0 }) .from(".text_info_box_earth_two", { opacity: 0 }); the timeline above executes automatically and the code below is only executed when the user clicks on the button "Night Time". As i stated before, everything works fine to this point, but once i resize the window AFTER i click on the "Night Time" button, however, the backgroundImage of the ".earth_container" reverts back to the image of the lake, when it shouldn't... why do you think this is happening? function change_to_night_earth() { let newHTML = "The night sky is just as beautiful " + "as the the day time sky. Millions of stars in every " + "corner of the sky. There may be less light, but there isn't " + "less beauty at this time of the planet"; let new_HTML = "Click the button below if you want to return to " + "the day time of earth..." + "<br><br>" + "<button type='button' class='btn'> Day Time </button>"; gsap.timeline() .to(".text_info_box_earth_one", { opacity: 0 }) .to(".text_info_box_earth_two", { opacity: 0 }) .to(".earth_container", { opacity: 0 }) .set(".text_info_box_earth_one", { innerHTML: newHTML, attr: {class: "text_containers_white text_info_box_earth_one transitioning_fast"} }) .set(".text_info_box_earth_two", { innerHTML: new_HTML, attr: {class: "text_containers_white text_info_box_earth_two transitioning_fast"} }) //-----this is propbably where the error happens---------------------------------------------- .set(".earth_container", { backgroundImage: "url('https://i.postimg.cc/x8km9XKw/earth-night.jpg')", }) //---------------------------------------------------------------------------------------------- .to(".earth_container", { opacity: 1 }) .to(".text_info_box_earth_one", { opacity: 1 }) .to(".text_info_box_earth_two", { opacity: 1 }) }
  2. Hey, I have kinda a big Issue - i've implemented a Text Rotation into a React Application. Locally everything works completely fine. After building it and deploying it on a Server (as a static version) it crashes and is not rotating as it was rotating locally. When it arrives at the last step it scrolls all items down until the first. it's not rotating from the beginning. Check for the Comment " // Start Rotation Animation". GSAP v3.8.0 is installed. Check the WeTransfer link for demo videos of local and staging env. https://we.tl/t-9MCJFOHefo Check the Demo Instance: https://gsap.elbcouture.com/ (maybe you have to reload it a few times, if the issue didn't happend) /* global fullpage_api */ import React, { createRef, useEffect, useRef } from 'react'; import gsap, { Power0 } from 'gsap'; import styled from 'styled-components'; import Header from 'components/Header'; import Stage from 'components/Stage'; import Headline from 'components/Headline'; import ScrollToExplore from 'components/ScrollToExplore'; import xsmallVideo from '../../assets/video/intro/414x896.mp4'; import smallVideo from '../../assets/video/intro/768x1024.mp4'; import mediumVideo from '../../assets/video/intro/1024x768.mp4'; import largeVideo from '../../assets/video/intro/1920x1080.mp4'; const StyledIntro = styled(Stage)` padding: 0; &::before { z-index: 1; pointer-events: none; } `; const StyledHeader = styled(Header)` display: block; @media screen and (min-width: 1024px) { display: none; } `; const StyledContent = styled.div` position: absolute; z-index: 1; margin-top: 71px; padding-left: 15px; @media screen and (min-width: 414px) { margin-top: 115px; } @media screen and (min-width: 768px) { margin-top: 70px; } @media screen and (min-width: 1024px) { right: 0; display: flex; flex-direction: column; justify-content: center; margin-top: 0; width: 50%; height: 100%; } @media screen and (min-width: 1440px) { right: 0; display: block; margin-top: 228px; width: 50%; height: 100%; } @media screen and (min-width: 1920px) { width: 46%; } @media screen and (min-width: 2560px) { margin-top: 15%; } `; const StyledMaskedText = styled(Headline)` font-size: 54px; line-height: 65px; ${({ backgroundImage }) => backgroundImage?.small ? `background: url(${backgroundImage.small}) no-repeat;` : ''} background-size: cover; background-position: center; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; @media screen and (min-width: 414px) { font-size: 64px; line-height: 77px; } @media screen and (min-width: 768px) { font-size: 104px; line-height: 125px; } @media screen and (min-width: 1024px) { font-size: 74px; line-height: 88px; } @media screen and (min-width: 1440px) { font-size: 98px; line-height: 129px; } @media screen and (min-width: 1920px) { font-size: 124px; line-height: 124px; } @media screen and (min-width: 2560px) { font-size: 130px; line-height: 120px; } `; const StyledHeadline = styled(Headline)` height: 52px; font-size: 44px; line-height: 52px; color: #00917e; overflow: hidden; white-space: nowrap; @media screen and (min-width: 414px) { height: 62px; font-size: 51px; line-height: 62px; } @media screen and (min-width: 768px) { height: 100px; font-size: 83px; line-height: 100px; } @media screen and (min-width: 1024px) { height: 71px; font-size: 59px; line-height: 71px; } @media screen and (min-width: 1440px) { height: 103px; font-size: 86px; line-height: 103px; } @media screen and (min-width: 1920px) { height: 132px; font-size: 105px; line-height: 132px; } @media screen and (min-width: 2560px) { height: 160px; font-size: 140px; line-height: 160px; } `; const StyledList = styled.div` list-style-type: none; padding: 0; margin: 0; `; const StyledVideo = styled.video` position: absolute; left: 0; right: 0; bottom: 0; width: 100%; @media screen and (min-width: 1024px) { position: static; display: block; height: 100vh; } `; const StyledHeadlineItem = styled.span` display: block; `; const Intro = ({ backgroundImage, switchingHeadline, active, lastActive, text, scrollTo }) => { const stageRef = useRef(null); const videoRef = useRef(null); const overlineRef = useRef(null); const headlineRef = useRef(null); const sublineRef = useRef(null); const listRef = useRef(null); const listItemRef = useRef([]); const scrollToExploreRef = useRef(); useEffect(() => { switchingHeadline.push(switchingHeadline[0]); if (listItemRef.current.length !== switchingHeadline.length) { // add or remove refs listItemRef.current = Array(switchingHeadline.length) .fill() .map((_, i) => listItemRef.current[i] || createRef()); } }, [switchingHeadline]) const getVideoSrc = (width) => { if (width >= 1920) return largeVideo; if (width >= 1024) return mediumVideo; if (width >= 768) return smallVideo; return xsmallVideo; }; // Start Rotation Animation const vSlide = gsap.timeline({ repeat: -1, paused: true, }); useEffect(() => { console.log('el', listItemRef.current) listItemRef.current.forEach((_slide, index) => { const label = `slide${index}`; const lineHeight = headlineRef.current.clientHeight; if (active) { if (index === 0) { vSlide.to( listRef?.current, { delay: 0, duration: 0.4, y: index * -1 * lineHeight, ease: Power0.ease, }, label ); } if (index > 0) { vSlide.to( listRef?.current, { delay: 3, duration: 0.4, y: index * -1 * lineHeight, ease: Power0.ease, }, label ); } vSlide.play(); } vSlide.add(label); }); }, [vSlide, active]); // End Rotation Animation const [isVideoLoaded, setIsVideoLoaded] = React.useState(false); const src = getVideoSrc(window.innerWidth); const onLoadedData = () => { setIsVideoLoaded(true); }; useEffect(() => { if (active) { videoRef.current.currentTime = 0; gsap.set([overlineRef.current, headlineRef.current, sublineRef.current], { y: 0, opacity: 1, }); gsap.set(scrollToExploreRef.current, { opacity: 1, }); } if (lastActive) { videoRef.current.play(); gsap.to(overlineRef.current, { opacity: 0, delay: 0, duration: 0.25, ease: Power0.in, }); gsap.to(headlineRef.current, { opacity: 0, delay: 0, duration: 0.25, ease: Power0.in, }); gsap.to(sublineRef.current, { opacity: 0, delay: 0, duration: 0.25, ease: Power0.in, }); gsap.to(scrollToExploreRef.current, { opacity: 0, delay: 0, duration: 0.25, ease: Power0.in, }); vSlide.pause(); } }, [active, lastActive, vSlide]); return ( <StyledIntro className="fp-noscroll" ref={stageRef}> <StyledHeader /> <StyledContent> <StyledMaskedText ref={overlineRef} backgroundImage={backgroundImage}> {text?.[0]} </StyledMaskedText> {switchingHeadline && ( <StyledHeadline ref={headlineRef}> <StyledList ref={listRef}> {switchingHeadline?.map((item, index) => ( // eslint-disable-next-line react/no-array-index-key <StyledHeadlineItem key={`${item}-${index}`} ref={listItemRef.current[index]}> {item} </StyledHeadlineItem> ))} </StyledList> </StyledHeadline> )} <StyledMaskedText ref={sublineRef} backgroundImage={backgroundImage}> {text?.[1]} </StyledMaskedText> </StyledContent> <StyledVideo ref={videoRef} playsInline muted src={src} onLoadedData={onLoadedData} style={{ opacity: isVideoLoaded ? 1 : 0 }} /> <ScrollToExplore className="scroll-to-explore" isLight label={scrollTo} dataLabel={scrollTo} ref={scrollToExploreRef} onClick={() => ( fullpage_api.moveSectionDown() )}/> </StyledIntro> ); }; export default Intro;
  3. Here's the codesandbox: https://codesandbox.io/s/gsap-transition-snap-react-p421y5 I want the building to smoothly disappear when it hits the trigger point. Instead of animating, building just snaps to opacity: 0.
  4. Hi! When I remove the markers property or set it to false, the ScrollTrigger stops working. Why? PS: With markers it works let tl2 = gsap.timeline(); tl2.from(".root--offer__header", { xPercent: 650, }); ScrollTrigger.create({ animation: tl2, trigger: ".root--offer__header", start: "top top", end: "+=4000", scrub: true, pin: true, anticipatePin: 1, duration: 2, ease: "none", markers: true, });
  5. This is my first time trying scroll trigger in gsap I am trying to understand how locomotive scroll and scroll trigger work together but when the animation is going on I am facing some kind of sticky-ness in the animation I mean the animation is not smooth there some kind of delay in between but I don't know what is the reason for this. I tried to recreate this situation in my code pen which I have linked below. It will be helpful if some one can help me to solve this. thank you
  6. If you find yourself writing multiple tweens to animate one target, it may be time to reach for keyframes. Keyframes are a great way to move a target through a series of steps while keeping your code concise. Take a repetitive timeline like the one below — It can be simplified down nicely to fit into one tween: // timeline let tl = gsap.timeline(); tl.to(".box", { x: 100 }) .to(".box", { y: 100 }) .to(".box", { x: 0 }) .to(".box", { y: 0 }); // Array-based keyframes gsap.to(".box", { keyframes: { x: [0, 100, 100, 0, 0], y: [0, 0, 100, 100, 0], ease: "power1.inOut" }, duration: 2 }); We like to think of keyframes as a sub-timeline nested inside a tween. There are a few different ways to write keyframes. If you're a visual learner, check out this video. Keyframe Options Object keyframes - v3.0 This keyframes syntax lets you pass in an Array of vars parameters to use for the given target(s). Think of them like a sequence of .to() tween vars. You can use a delay value to create gaps or overlaps. The default per-keyframe ease is linear which you can override in individual keyframes. You can also apply an ease to the entire keyframe sequence. gsap.to(".elem", { keyframes: [ {x: 100, duration: 1, ease: 'sine.out'}, // finetune with individual eases {y: 200, duration: 1, delay: 0.5}, // create a 0.5 second gap {rotation: 360, duration: 2, delay: -0.25} // overlap by 0.25 seconds ], ease: 'expo.inOut' // ease the entire keyframe block }); Percentage keyframes - v3.9 This familiar syntax makes porting animations over from CSS a breeze! Instead of using delays and duration in the keyframe object, you specify an overall duration on the tween itself, then define the position of each keyframe using percentages. To be consistent with CSS behaviour, the default per-keyframe ease is power1.inOut which generally looks quite nice but you can override this in individual keyframes or on all keyframes using easeEach. gsap.to(".elem", { keyframes: { "0%": { x: 100, y: 100}, "75%": { x: 0, y: 0, ease: 'sine.out'}, // finetune with individual eases "100%": { x: 50, y: 50 }, easeEach: 'expo.inOut' // ease between keyframes }, ease: 'none' // ease the entire keyframe block duration: 2, }) Simple Array-based keyframes - v3.9 Just define an Array of values and they'll get equally distributed over the time specified in the tween. The default per-keyframe ease is power1.inOut, but you can override this by using easeEach. The Arrays do not need to have the same number of elements. gsap.to(".elem", { keyframes: { x: [100, 0, 50], y: [100, 0, 50] easeEach: 'sine.inOut' // ease between keyframes ease: 'expo.out' // ease the entire keyframe block }, duration: 2, }) Easing keyframes Easing is integral to animation and keyframes give you a huge amount of flexibility. Percentage keyframes and Simple keyframes allow you to control the ease between each of the keyframes with easeEach. See the Pen Keyframe easing by GreenSock (@GreenSock) on CodePen. With Object keyframes and Percentage keyframes you can drill down and add different eases into individual keyframes. See the Pen Bounce Party with GSAP keyframes, by GreenSock (@GreenSock) on CodePen. You can even combine multiple easing properties, keyframes and normal tween values. 🤯 gsap.to(".box", { keyframes: { y: [0, 80, -10, 30, 0], ease: "none", // <- ease across the entire set of keyframes (defaults to the one defined in the tween, or "none" if one isn't defined there) easeEach: "power2.inOut" // <- ease between each keyframe (defaults to "power1.inOut") }, rotate: 180, ease: "elastic", // <- the "normal" part of the tween. In this case, it affects "rotate" because it's outside the keyframes duration: 5, stagger: 0.2 }); See the Pen keyframe easing by GreenSock (@GreenSock) on CodePen. Keyframe tips Both the Object keyframes and the Percentage keyframes behave similarly to tweens, so you can leverage callbacks like onStart and onComplete. gsap.to(".elem", { keyframes: [ {x: 100, duration: 1}, {y: 200, duration: 1, onComplete: () => { console.log('complete')}}, {rotation: 360, duration: 2, delay: -0.25, ease: 'sine.out'} ] }); gsap.to(".elem", { keyframes: { "0%": { x: 100, y: 100}, "75%": { x: 0, y: 0, ease: 'power3.inOut'}, "100%": { x: 50, y: 50, ease: 'none', onStart: () => { console.log('start')} } }, duration: 2, }) We hope this has helped you get your head around keyframes - if you have any questions pop over to our forums. Happy tweening!
  7. Are you guilty of any of the most common mistakes people make in their ScrollTrigger code? Nesting ScrollTriggers inside multiple timeline tweens Creating to() logic issues Using one ScrollTrigger or animation for multiple "sections" Forgetting to use function-based start/end values for things that are dependent on viewport sizing Start animation mid-viewport, but reset it offscreen Creating ScrollTriggers out of order Loading new content but not refreshing Why does my "scrub" animation jump on initial load? Or my non-scrub animation start playing? Tip: How to make scrub animations take longer Navigating back to a page causes ScrollTrigger to break Note: There's also a separate article that covers the most common GSAP mistakes. Debugging tip: In many cases, the issue isn't directly related to ScrollTrigger, so it's helpful to get things working without ScrollTrigger/any scroll effects and then, once everything else is working, hook things up to ScrollTrigger. Nesting ScrollTriggers inside multiple timeline tweens A very common mistake is applying ScrollTrigger to multiple tweens that are nested inside a timeline. Logic-wise, that can't work. When you nest an animation in a timeline, that means the playhead of the parent timeline is what controls the playhead of the child animations (they all must be synchronized otherwise it wouldn't make any sense). When you add a ScrollTrigger with scrub, you're basically saying "I want the playhead of this animation to be controlled by the scrollbar position"...you can't have both. For example, what if the parent timeline is playing forward but the user also is scrolling backwards? See the problem? It can't go forward and backward at the same time, and you wouldn't want the playhead to get out of sync with the parent timeline's. Or what if the parent timeline is paused but the user is scrolling? So definitely avoid putting ScrollTriggers on nested animations. Instead, either keep those tweens independent (don't nest them in a timeline) -OR- just apply a single ScrollTrigger to the parent timeline itself to hook the entire animation as a whole to the scroll position. Creating to() logic issues If you want to animate the same properties of the same element in multiple ScrollTriggers, it’s common to create logic issues like this: gsap.to('h1', { x: 100, scrollTrigger: { trigger: 'h1', start: 'top bottom', end: 'center center', scrub: true } }); gsap.to('h1', { x: 200, scrollTrigger: { trigger: 'h1', start: 'center center', end: 'bottom top', scrub: true } }); Did you catch the mistake? You might think that it will animate the x value to 100 and then directly to 200 when the second ScrollTrigger starts. However if you scroll through the page you’ll see that it animates to 100 then jumps back to 0 (the starting x value) then animates to 200. This is because the starting values of ScrollTriggers are cached when the ScrollTrigger is created. See the Pen ScrollTrigger to() logic issue by GreenSock (@GreenSock) on CodePen. To work around this either use set immediateRender: false (like this demo shows) or use .fromTo()s for the later tweens (like this demo shows) or set a ScrollTrigger on a timeline and put the tweens in that timelines instead (like this demo shows). Using one ScrollTrigger or animation for multiple "sections" If you want to apply the same effect to multiple sections/elements so that they animate when they come into view, for example, it's common for people to try to use a single tween which targets all the elements but that ends up animating them all at once. For example: See the Pen ScrollTrigger generic target issue by GreenSock (@GreenSock) on CodePen. Since each of the elements would get triggered at a different scroll position, and of course their animations would be distinct, just do a simple loop instead, like this: See the Pen ScrollTrigger generic target issue - fixed with scoping by GreenSock (@GreenSock) on CodePen. Forgetting to use function-based start/end values for things that are dependent on viewport sizing For example, let's say you've got a start or end value that references the height of an element which may change if/when the viewport resizes. ScrollTrigger will refresh() automatically when the viewport resizes, but if you hard-coded your value when the ScrollTrigger was created that won't get updated...unless you use a function-based value. end: `+=${elem.offsetHeight}` // won't be updated on refresh end: () => `+=${elem.offsetHeight}` // will be updated Additionally, if you want the animation values to update, make sure the ones you want to update are function-based values and set invalidateOnRefresh: true in the ScrollTrigger. Start animation mid-viewport, but reset it offscreen For example try scrolling down then back up in this demo: See the Pen ScrollTrigger reset issue by GreenSock (@GreenSock) on CodePen. Notice that we want the animation to start mid-screen, but when scrolling backwards we want it to reset at a completely different place (when the element goes offscreen). The solution is to use two ScrollTriggers - one for the playing and one for the resetting once the element is off screen. See the Pen ScrollTrigger reset issue - fixed with two ScrollTriggers by GreenSock (@GreenSock) on CodePen. Creating ScrollTriggers out of order If you have any ScrollTriggers that pin elements (with the default pinSpacing: true) then the order in which the ScrollTriggers are created is important. This is because any ScrollTriggers after the ScrollTrigger with pinning need to compensate for the extra distance that the pinning adds. You can see an example of how this sort of thing might happen in the pen below. Notice that the third box's animation runs before it's actually in the viewport. See the Pen ScrollTrigger creation order issue by GreenSock (@GreenSock) on CodePen. To fix this you can either create the ScrollTriggers in the order in which they are reached when scrolling or use ScrollTrigger's refreshPriority property to tell certain ScrollTriggers to calculate their positions sooner (the higher the refreshPriority the sooner the positions will be calculated). The demo below creates the ScrollTriggers in their proper order. See the Pen ScrollTrigger creation order issue - fixed by GreenSock (@GreenSock) on CodePen. Loading new content but not refreshing All ScrollTriggers get setup as soon as it's reasonably safe to do so, usually once all content is loaded. However if you're loading images that don't have a width or height attribute correctly set or you are loading content dynamically (via AJAX/fetch/etc.) and that content affects the layout of the page you usually need to refresh ScrollTrigger so it updates the positions of the ScrollTriggers. You can do that easily by calling ScrollTrigger.refresh() in the callback for your method that is loading the image or new content. Why does my "scrub" animation jump on initial load? Or my non-scrub animation start playing? Most likely the ScrollTrigger’s start value is before the starting scroll position. This usually happens when the start is something like "top bottom" (the default start value) and the element is at the very top of the page. If you don’t want this to happen simply adjust the start value to one that’s after a scroll position of 0. Tip: How to make "scrub" animations take longer The duration of a "scrub" animation will always be forced to fit exactly between the start and end of the ScrollTrigger position, so increasing the duration value won't do anything if the start and end of the ScrollTrigger stay the same. To make the animation longer, just push the end value down further. For example, instead of end: "+=300", make it "+=600" and the animation will take twice as long. If you want to add blank space between parts of a scrubbed animation, just use empty tweens as the docs cover. Navigating back to a page causes ScrollTrigger to break If you have a single-page application (SPA; i.e. a framework such as React or Vue, a page-transition library like Highway.js, Swup, or Barba.js, or something similar) and you use ScrollTrigger you might run into some issues when you navigate back to a page that you've visited already. Usually this is because SPAs don't automatically destroy and re-create your ScrollTriggers so you need to do that yourself when navigating between pages or components. To do that, you should kill off any relevant ScrollTriggers in whatever tool you're using's unmount or equivalent callback. Then make sure to re-create any necessary ScrollTriggers in the new component/page's mount or equivalent callback. In some cases when the targets and such still exist but the measurements are incorrect you might just need to call ScrollTrigger.refresh(). If you need help in your particular situation, please make a minimal demo and then create a new thread in our forums along with the demo and an explanation of what's going wrong. Still need some help? The GreenSock forums are the best place to get your questions answered. We love helping people develop their animation superpowers.
  8. I've been scouring the archives and the web but can't seem to find out a proper workflow using Adobe Animate and GSAP if there is even one or is it even worth it. I am working off some files that were done by another developer and they seem to have used Adobe Animate for the HTML portion of is and then GSAP for the actual animation. I have been trying to break down how they managed to use both and can't seem to make it work in my head because everything that I pump out of Adobe Animate has a js file that is way overloaded with symbols and such. As I've mentioned elsewhere I am trying to get back into using GSAP so I am rusty as all get out. I may be asking the wrong question so there's that too! Any help would greatly appreciated. I guess I am missing the link between how to go from Animate to GSAP. Does the GSAP happen within the Animate file? Or is published and then coded.
  9. I tried to pin the current page (div1) and when the next page(div2) will slide up, the current page (div1) will keep going 30 percent to the top, creating a parallax effect. But the problem is, when The 2nd page(div2) pins and 3rd page(div3) slides up, the 2nd(div2) page's parallax effect breaks the whole design. I need help.
  10. the onDragEnd function is not working? Also what I want to achieve is that I want to prevent dragging in left as well as in right direction with animation or specifically with slight bounce animation. If I am not using boundsprop everything is working just fine.
  11. Hi, I've been having an issue with this error ("Uncaught TypeError: t[0] is undefined"), whenever I try to use motionPath and give it a value of an object with multiple values in it, it gives me that error, and I've been trying to solve it for so long with no use. I tried gsap.registerPlugin, I tried importing instead of CDN, I tried different syntax, all with no use. Please help, I've been at this for so long. Should also mention that the error keeps getting spammed, goes up to 90 times sometimes, but it's repeats anyways. Here's the code: Javascript: CSS: HTML: Here's the error itself:
  12. I have a section middle of page and into this section i have inner scroll When user reached this section firstly pin the section until inner Scroll end then unpin the section on the parent scroll child scroll run until child scroll end.... Please i need help
  13. I am confused with gsap.to moving to coordinates. I have a game board with 182 tiles and 182 playing tiles. The goal When the user clicks the bag, a random playing tile is selected and is "supposed" to move over the tile on the board. The CodePen example is just testing for column A and B. Note: SVG image was create in Inkscape.
  14. I'm new to Greensock and it's amazing, i decided to use GSAP with scrollTrigger plugin for one of my project, my question is - how do we use multiple timelines with scrollTrigger plugin, i have done it like below and it works, is there any better way to do it? let sections = gsap.utils.toArray(".big-row"); let tl = gsap.timeline({ scrollTrigger: { trigger: ".horizontal-container", pin: true, scrub: 1, snap: 1 / (sections.length - 1), end: () => "+=" + document.querySelector(".horizontal-container").offsetWidth }, }) tl.to(sections, { xPercent: -100 * (sections.length - 1), ease: "none" }); let tl2 = gsap.timeline({ scrollTrigger:{ trigger:'.present-img', start:"top 80%", end:"bottom 10%", markers:true, scrub:true, toggleActions:"restart pause reverse none" } }) tl2.fromTo('.present-img',{x:-400},{x:0})
  15. I'm converting a project using gsap 2 to gsap 3. BezierPlugin.bezierThrough() is used, but I don't see a compatible method in the MotionPathPlugin. What would I use to replace that function?
  16. Hello everyone, I'm new in Gsap and ScrollTrigger. I'm trying to make scroll animation in block that firstly animates with gsap, but I have an issue with it. Strict order of animation is: first-screen moves from bottom, after it, when person scrolling that first-screen sticky-block pins to the screen and moves to the end of long-block. When I'm changing first-screen position in move from bottom animation, sticky-block doesn't pins (it just teleports to end of animation with pinning), but if I will change opacity instead of position, sticky-block will magickly pin and everything works like I wanted. I'm trying to fix it for 2 days, but I wasn't much succeed in it. May be someone could help me to fix that bug, or tell how to make this animation correctly.
  17. Hi, I want to make texts fadein and slideup when page loaded, then slideup again and fadeout when user scrolls down. But first letter not animated and hidden immediately. https://codepen.io/rokuta/pen/QWOwmYG I also tried fromTo instead of to for fadeout animation but it makes first animation flickers. https://codepen.io/rokuta/pen/WNXbzqR What am I missing? thanks
  18. Hello I'm going to make a digital book like a flipbook. By looking at the tutorials, I was able to make a typical right-to-left example, but the pages are not as soft as the pages of a real book. https://codesandbox.io/s/flipbook-rtl-k8w8f?file=/src/App.js:845-849
  19. So I am trying to rotate a circle and snap it to 90 degrees but I can rotate it but It doesn't trigger the onDrag en snap function. I don't know why, I also don't get any errors. let rotationSnap = 90; Draggable.create(vinyl, { type:"rotation", OnDrag: () => console.log('works'), snap: function(endValue) { console.log(endValue); console.log(Math.round(endValue / rotationSnap) * rotationSnap) //this function gets called when the mouse/finger is released and it plots where rotation should normally end and we can alter that value and return a new one instead. This gives us an easy way to apply custom snapping behavior with any logic we want. In this case, just make sure the end value snaps to 90-degree increments but only when the "snap" checkbox is selected. return Math.round(endValue / rotationSnap) * rotationSnap; } }) }
  20. Hi! I find on documantation page property startAt What different between .fromTo and startAt? What are the features of using startAt
  21. Hello green fellas! What I'm trying to accomplish is I think very simple but I'm still stuck on it. This is what I want when an user scroll : -> while the user is scrolling, the div must appear slowly (with opacity) at the center of the screen -> when opacity is at 1, keep it like that and do nothing for some defined px/vh while keep scrolling -> when those px/vh are ended then change the opacity from 1 to 0 while user keep scrolling -> go to next div/section and do the same So the div must appear on the center of the screen and disapear on the center of the screen. (And I need to do the same with the following div's). Here is a codepen of what I tried. Thanks a lot in advance for your help!
  22. Hi GSAP champs, Soon, I'm going to start working on a project which is a product landing page full of GSAP animations. So, currently we're planning to go with GatsbyJs & one an only GSAP. The animations required in that landing page: DrawSVG ( is it free?) Pinning ScrollTrigger So, I wanna confirm that does GSAP & GatsbyJs have full support for the GSAP, I mentioned above ? any useful resource or help or guidance would be appreciated. Thanks
  23. I have simple animation. It works just once. Is there a simple way solve that problem? Thanks!
  24. Everything works fine, but only once. How to solve that?
  25. hi guys, i need your help, it's been a couple days that i'm trying to solve this. i have a box wich contains SVGs that are draggable, that box needs its box-sizing to be "content-box", and the draggable SVGs bounds needs to be inside the box (not touching the borders) that's why i created a bounds-box which take 100% width and height of the parent box, and set the draggable bounds to that bounds-box, it works fine , the only problem is when i zoom in or out, the bounds change after dragging the svg around and u can see that the bounds got -1px on every side. thank you.