Jump to content
GreenSock

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

Search the Community

Showing results for tags 'gsap3'.



More search options

  • 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 88 results

  1. Hello again, I've been using GSAP3' ScrollTrigger plugin for a little while now and managed to make the skew on scroll effect work, which I really enjoyed using. Although it does work perfectly with normal scrolling, I can't seem to make it work while using the SmoothScrollbar.js plugin (https://idiotwu.github.io/smooth-scrollbar/). Please note to the Pen provided: when the SmoothScrollbar is removed, the skew on scroll effect works. I know GSAP and SmoothScrollbar are separate plugins so I'd understand if it just wouldn't work but I hope someone can find a solution. Sincerely, Julius
  2. Hello, The delay property doesn't seem to work for me while using ScrollTrigger; it does work on loaded animations. Is it supposed to be disabled on scroll? If so, is there another way to delay scroll triggered animations? Really loving GSAP3 so far. Thank you, Julius
  3. Hello, First of all, sorry for just copying and pasting the whole project, but I didn't have enough time to replicate the issue in a minimalistic way. Hope it's useful to solve the problem I'm facing. I'm currently working on my personal site which its homepage consists of a slider. When the slide changes, a div covering the whole viewport with a background image should also change accordingly. It is done using gsap.timeline() and as you can notice, there's a really noticeable amount of lag when the animation happens. Without the background change, everything is smooth. Tested on a 2018 15inch Macbook Pro running macOS Catalina 10.15.6 on Google Chrome v84.0.4147.89 (laggy), Firefox v79.0 (really really laggy) and Safari v13.1.2 (somehow smooth). Thank you in advance, Arnau. ps: I was just testing and I know the background image is incredibly stretched, already tried with a properly sized one and same results. ps2: As of now, only the next page button works ("següent").
  4. Hey guys So i am making a project with gsap3 kind of like the apple airpod website I have like 500 + images and on scroll these images are being rendered in the canvas. I want to animate some text which will depend on the frame count the sequence is - frame ==0 animate in some text frame>0 animate out the previous text frame>10 again animate in some text frame>200 animate out the previous text so it goes... can some one tell me how can i do this in a efficient way. Thanks
  5. Hi, I'm very new to gsap and been trying to do this layout today but without any luck. In the pen you can see 4 items to the left, what I'm trying to achieve is to pin this items in the left and change the content in the right with the relevant one. the pen js is very small is where I started and i have been trying different things but I don't know if im going in the right direction I highlighted one of the items as an example of the result I'm looking for, when you scroll past certain offset the element goes to active and the content that shows is the relevant one, in this case, Ipsum would show Thank you very much if anyone can point me in the right direction.
  6. Hello all. I know using calc in JS is not recommended. But as long as it is not in the not supported category, I'd call these bugs. Click the toggle button twice and now the h1 has top: 4.75px instead of calc(1vh). I don't know if GSAP is trying to optimize something, but even if it is it should set 1vh, not 4.75px. https://codepen.io/taylankasap/pen/ZEWMLbB It's jumping to some huge values. https://codepen.io/taylankasap/pen/YzqONVR It is changing values (see devtools) even when from and to are same. https://codepen.io/taylankasap/pen/MWyqJdO It would be good if I could let CSS calculate things for me but with these issues I don't think it's possible. I guess I'll not use calc, just wanted to let you know of these issues.
  7. Hi! I try to change animation with (window.matchMedia()).matches How can i get tween from timeline and replace (or edit) it? I read about .remove() method, but how can i add on removed place other tween and how can i add label to tween. for example: tl .addLabel('start') .to('.box-1', {x:100}, "start") // <--- how to change this or how to .remove() this and place other tween on this place .to('.box-2', {x:100}, "start")
  8. Hi, I'm looking for help regarding scroll trigger and items positioned fixed within a pinned section. I'm having an issue where I have a modal that needs to stay in window view once it's open, but it looks like it's being positioned relative to its pinned parent and I'm able to continue scrolling as normal. Hoping someone would be able to help me out!
  9. Are you guilty of any of the most common mistakes people make in their ScrollTrigger code? Loading the wrong "ScrollTrigger" Creating to() logic issues Nesting ScrollTriggers inside multiple timeline tweens Using one ScrollTrigger 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 Why does my "scrub" animation jump on initial load? Tip: How to make scrub animations take longer Note: There's also a separate article that covers the most common GSAP mistakes. Loading the wrong "ScrollTrigger" There's a different JavaScript library out there called "ScrollTrigger" which is totally unrelated to GSAP. Avoid that! It's pretty common, for example, to add GSAP to a CodePen by typing "gsap" into the search field in JS settings but you can’t add GSAP plugins this way. Instead, just copy the whole official GSAP URL, paste it and swap "gsap.min.js" with "ScrollTrigger.min.js" (load both GSAP and the correct ScrollTrigger plugin). Or just fork the GSAP starter pen. 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). Nesting ScrollTriggers inside multiple timeline tweens A very common mistake is applying ScrollTrigger to a bunch of tweens inside a timeline. This doesn’t make much sense because both the timeline and the ScrollTrigger would try to control the tweens' playhead. It's best to apply a ScrollTrigger to either a standalone tween or to a parent timeline. Using one ScrollTrigger 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. Why does my "scrub" animation jump on initial load? 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. Still need some help? The GreenSock forums are the best place to get your questions answered. We love helping people develop their animation superpowers.
  10. Hi Devs, I don't know what's wrong in my code , the animations are super slow in firefox and sometimes in chrome as well. I have two issues Translating animations are super slow in firefox and sometimes in chrome Text animations are flickering on scroll I use SVG as react components Can u guys please help me improve my code. Im using NextJs and GSAP3. Thanks. let timeline = gsap.timeline({ delay: tableAndAbove ? 0.5 : 0, scrollTrigger: !tableAndAbove && { trigger: "#sellersLandingMobileContainer", start: "30% 20%%", }, }); if (tableAndAbove) { timeline.from("#sellersLandingMobile", { duration: 1, scale: 0.8, autoAlpha: 0, rotation: 0.01, }); timeline.from( "#sellersLandingMobile", { duration: 1, translateX: "20%", ease: "expo.out", rotation: 0.01, }, "-=0.6" ); } timeline.to( "#sellersLandingHeroText .hide-text", { duration: 0.8, ease: "expo.out", translateY: 0, delay: 0, autoAlpha: 1, rotation: 0.01, }, "-=0.9" ); timeline.from( "#sellersLandingCTA", { duration: 0.5, ease: "expo.out", scale: 0.5, autoAlpha: 0, rotation: 0.01, }, "-=0.5" ); document.querySelectorAll("#sellersLandingStoreLink").forEach((el) => { timeline.from( el, { duration: 0.5, ease: "expo.out", translateY: 20, autoAlpha: 0, rotation: 0.01, }, "-=0.3" ); }); const images = [ "#sell24By7Img", "#chatBroadcastInvoiceImg", "#lightningfastpaymentsImg", ]; const sections = [ "#sell24By7TextContainer", "#chatBroadcastInvoiceTextContainer", "#lightningfastpaymentsTextContainer", ]; useScroll(); useEffect(() => { gsap.to("#punchGrowthHeading .hide-text", { scrollTrigger: { trigger: "#punchGrowthHeading", start: "top 80%", }, duration: 1, ease: "expo.out", translateY: 0, rotation: 0.01, }); images.forEach((el, index) => { gsap.from(el, { scrollTrigger: { trigger: el, start: "30% 80%", }, duration: 1, ease: "expo.out", autoAlpha: 0, transform: `translate3d(${index === 1 ? 100 : -100}px, 0, 0)`, perspective: 1000, rotation: 0.01, force3D: true, }); }); sections.forEach((el) => { gsap.to(`${el} .hide-text`, { scrollTrigger: { trigger: el, start: "30% 80%", }, duration: 1, ease: "expo.out", translateY: 0, rotation: 0.01, }); gsap.from(`${el} p`, { scrollTrigger: { trigger: `${el} p`, start: "30% 80%", }, duration: 1, ease: "expo.out", autoAlpha: 0, }); });
  11. Hello devs , i'm trying to implement smooth scroll and scrollTrigger pinning on same view port. As the smooth scroll works by disabling scroll and translating -Y , pinned div also translates instead of pinning. Reference : https://codepen.io/wooooosky/pen/LQNZgv Can anyone give me a solution , would be helpful. Thanks in advance.
  12. Hi ! I have a problem for tweening my camera . I create a codepen with the minimum of code just to reproduce my issue and I annotate all my code (sorry for my English I'm french by the way ^^ ) I also put a lot of console.log() for debugging purpose . the question is at line 75-122 the start point is my camera.postion line 23 : camera.position.z = 30; and my tween001 line 75 : var tween001 = gsap.to(camera.position,{ delay:2,duration:5,z:60,onUpdate:function(){ camera.updateProjectionMatrix(); console.log("play"); },onComplete:function(){ console.log("complete"); },ease:"elastic" }); so the tween is about to move my camera from the Z = 30 to Z = 60 its work perfectly but ... When the user move the camera(line 90: when the user move/over/click on the 3d its fire and eventlistener that pause "tween001.pause()" ) I want the tween001 use the "actual" camera.postion and not when the camera.postion used when the tween 001 get fire . Cause when the tween001 is played again or it resume from a pause the start point used is the default one x=0 y=0 z=30 . An idle function play the tween001 again at line 109 window.setInterval(checkTime, 1000);// every 1 second lauch checktime function checkTime() { //idleCounter get 1 every second and at 5 second coz timeout is 5 checktime relauch the tween001 if (idlecounter < timeout) { idlecounter++; //console.log("++ "); } else if (idlecounter == timeout) { tween001.play(); console.log('timeout'); } } Any help will be welcome
  13. Hi guys. I am trying to achieve an overlay menu animation using this stack: React, styled-components and gsap. I made a simplified example of my code in here: https://codesandbox.io/s/young-wildflower-ld94q The main overlay animation plays smoothly, but the menu items dont. I am trying to create a stagger effect for each MenuItem component. As you can see using useRef() hook only works only for the last component. When Iterating an array of components useRef() is not the right choice since the same ref has been passed to multiple objects, but still I have no idea how to get a progressive fade for each component and I'm not even sure I'm using gsap in the correct way. What am I doing wrong? Thank you in advance, Matteo.
  14. There is a problem with gsap ScrollTrigger issues when try to achive horizontal scroll effect on those section and then end of ehis section going to next section. But the problem is when i added pin:true the specific section it's scroll but not pinned on that moment also the next section is moving up before finish the horizontal scroll finished. what i want to achieve https://drive.google.com/file/d/1SpJS5NxL0yK2hs1Ou7G3LSQ3gkvdhcWL/view And What i am facing problem with scrollTrigger when pin:true https://drive.google.com/file/d/1rHEMFfC8JB6GGOEH6MAa8t2jsvdBSXi4/view Here Is my code for Horizontal Scroll with ScrollTrigger let container: any = document.documentElement.querySelector( '.brand-showcase' ); let tl = gsap .timeline({ scrollTrigger: { pin: true, scrub: 1, trigger: container, end: container.scrollWidth - document.documentElement.clientWidth, }, defaults: { ease: 'none', duration: 1 }, }) .to( '.panel-section', { x: -(container.scrollWidth - document.documentElement.clientWidth), }, 0 ) .to( '.panel-item', { opacity: 1, scale: 1, duration: 0.6, stagger: { amount: 0.8, }, }, 0 ); Here Is The HTML Structure for every scroll-item <div class = 'brand-showcase'> <div class="brand-strategy-showcase-container"> <div class="panel-section"> <div class="panel-item"> <div class="showcase-content"> <div class="bss-title">Brand Research & Strategy 1</div> <div class="bss-content"> Spending quality time with our clients in order to uncover what your brand really stands for is by far the most important step. After taking an objective look at your industry and key audiences, we will articulate your purpose, proposition, and personality. From there, we will be able to create experiences that will connect your brand with your customers. </div> <ul class="bss-list"> <li>Market & Landscape Research</li> <li>Market & Landscape Research</li> <li>Market & Landscape Research</li> <li>Market & Landscape Research</li> </ul> <a href="#" class="btn co-btn"> view Project <div class="icon"> <img src="@/assets/img/next_icon.svg" alt="next" /> </div> </a> </div> <div class="showcase-sticky-img"> <img class="item-img" src="@/assets/img/brand-showcase-sticky-img.jpg" alt="Brand Image" /> </div> </div> </div> </div> </div> Hope you understand my issues. Looking for the help from the team gsap or any other coder with gsap master. Thanks in advance
  15. As you can see in my codepen code there is a image and I want to fixed its position center in the section. When scrolling down it will follow the scroll. When the following section comes up there will be a parallax effect. That means image will stick at the bottom of that section and following sections going up over the image. Here is a simple example. Like the form on that website, I want my image but in the center of viewport. If you don't understand please let me know.
  16. I want to create something like function with parrameters to generate template for timeline Example: let tl = gsap.timeline({paused: true, defaults: {duration: 0.2}}) /** opt format: opt = { prop: "", // x, y from: "", // value "+=10".. to: ""// value "0" } */ function tlgenerator(element, opt){ let tl = gsap.timeline(); tl.fromTo(element, {opt.prop: opt.from, autoAlpha: 0}, {opt.prop: opt.to, autoAlpha: 1}) return tl } tl.addLabel("start") .add(tlgenerator(element1, {prop: "y", from: "-=10", to: "0"}), "start") .add(tlgenerator(element2, {prop: "x", from: "+=10", to: "0"}), "start") .... It is not working example I'm not sure that this question need codepan demo?
  17. Recently, I created gatsby project and I wanted to implement show animation to a card component. The problem comes when my 'react-intersection-observer' detects when a card appears on a screen. Then gsap gives me warning with content: 'Invalid property autoAlpha set to 0 Missing plugin? gsap.registerPlugin()' instead of animating my card component. I've already read many topics about this issue. I've tried to use 'gsap.registerPlugin()' function or to put 'CSSPlugin' to 'const plugins' but they don't solve the issue. I see the same issue when I use properties like: 'opacity' instead of 'autoAlpha'. I hope you'll point what is an issue here! There is code of my card component: export default function Card({ number, title, text, fixed, ...props }) { const [ref, inView] = useInView({ threshold: 0.2, triggerOnce: true }) function show() { gsap.registerPlugin(CSSPlugin) const tl = gsap.timeline() tl.set(ref, { autoAlpha: 0 }).to(ref, { duration: 1, autoAlpha: 1 }) } useEffect(() => { if (!inView) return show() }, [inView]) return ( <StyledCard ref={ref} {...props}> <ImageWithMask as={Img} fixed={fixed} brightValue={0.5} /> <StyledContent> <StyledSmall>{number}</StyledSmall> <Heading style={{ textAlign: "right" }}>{title}</Heading> <Paragraph className="paragraph" color={paragraphColor.grey}> {text} </Paragraph> </StyledContent> </StyledCard> ) }
  18. Hi i want to make exact animation for testimonial section from this website (https://appinventiv.com/) at the end you will find testimonial section Please provide complete step by step tutorial i was noob to GSAP please help me
  19. I've got a bunch of elements I'm doing a stagger animation on. I'd like to set different properties (say scale/position) for each of these elements based on index of stagger. Is there a straightforward way of doing this with a single gsap call? The current solution I'm thinking of involves looping through the elements to get index and setting the properties and delay as per this with individual gsap calls in the loop. Any ideas are appreciated, I didn't make a codepen cause I felt like the description explained it well enough.
  20. altaircena

    Draggable

    Hi, I've got some Qs, I wanna create a draggable slider in react like in "http://robinmastromarino.com" and as I was checking the forum, I got confused about the algorithm and also, as I added and tried some of code instances, it didn't work. I use gsap module itself, not react-gsap. plz help
  21. I'm trying to create a write on text animation that changes with each repeat of the timeline, but even though I have repeatRefresh set to true, (which should invalidate the tweens) it only repeats the same text over and over. I'm using a function in the "text" property of .vars that returns a random item from an array of strings. Am I missing something, and is it possible to achieve the effect I'm trying to with this method?
  22. With over 100,000 posts in the popular GreenSock forums, we've noticed some common mistakes that you'd be wise to avoid. We threw in a few tips as well. Here is a summary of the mistakes: Creating from() logic issues Not setting ALL transforms with GSAP Not using xPercent and yPercent Recreating animations over and over Adding tweens to completed timelines Not using loops Importing things incorrectly Using the old/verbose syntax Creating from() logic issues It's usually smart to use .to() and .from() tweens instead of .fromTo() because they're more dynamic - they pull either the starting or ending values from whatever they happen to CURRENTLY be at the time that tween renders for the first time. It’s one of the tips in the article on animating efficiently. But be careful because that dynamic nature can bite you in a few scenarios. First, keep in mind that .from() tweens go from the provided value to the current value. Take a look at this example: See the Pen Illustrating .from() effects - Part 1 by GreenSock (@GreenSock) on CodePen. Try clicking it one time and letting it play. It works, fading in the element. Now try clicking it multiple times right after each other. The box stops showing up because it uses the current opacity as the end point which, if the animation has not completed, is some value less than 1. The fix for this is simple: use a .fromTo(). Alternatively you could create the animation beforehand and use a control method (we'll talk more about this approach later in this article). See the Pen Illustrating .from() effects - Part 1 by GreenSock (@GreenSock) on CodePen. Second, keep in mind that by default immediateRender is true by default for .from() and .fromTo() tweens because that's typically the most intuitive behavior (if you're animating from a certain value, it should start there right away). But if you create a .from() tween after a .to() tween affecting the same properties of the same object, try to figure out what will happen: const tl = gsap.timeline() tl.to(".box", {x: 100}); tl.from(".box", {x: 100}); You might expect the box to animate x from 0 to 100 and then back to 0. Or maybe you'd expect it to animate from 0 to 100 and then stay at 100. Let’s see what happens: See the Pen Illustrating .from() effects - Part 1 by GreenSock (@GreenSock) on CodePen. The box animates x from 100 to 100 and then back to 0. Why is that? By default .to() tweens wait to render until their playhead actually moves (it's a waste of CPU cycles to render at a time of 0 because nothing will have changed). But since from() has immediateRender: true, x jumps to 100 immediately on the current tick! Then it runs the .to() tween on the next tick (since it’s first in the timeline) and records the current starting value which is 100! So it animates 100 to 100 over 0.5 seconds. Then it runs the .from() tween which has the cached value of 0 as the end value. If you have several timelines affecting the same element, situations like this can be a little tricky to catch. So just be mindful of how things work when using .to() and .from() tweens. They’re very powerful but with power comes responsibility. A simple solution here is to set immediateRender: true on the .to() tween, or immediateRender: false on the .from() tween. The third situation is similar but involves repeatRefresh and repeats. Let’s say you have a situation where you want a looped animation that fades in some text and fades it out. You could create a timeline, use a .from() to fade in the text, then use a .to() to fade it out: const tl = gsap.timeline({repeat:-1}); tl.set(".text", { color: "random([green, gray, orange, pink])" }, 2); tl.from(chars, { opacity: 0 }); tl.to(chars, { opacity: 0 }); This will work just fine! Here’s the same thing but staggered using SplitText to make it look a little nicer: See the Pen Fade in and out text by GreenSock (@GreenSock) on CodePen. But this only randomizes the colors at the start. What if we want new random values each repeat? That’s where repeatRefresh comes in. Let’s add repeatRefresh: true to see what happens: See the Pen Random on Reset (wrong way) by GreenSock (@GreenSock) on CodePen. The animation plays correctly the first time but after that the elements don’t fade in a second time! Why is that? repeatRefresh uses the end values of the animation as the starting values of the next iteration. In this case, the opacity of our text elements are all 0 at the end. So when the animation gets to the .from() the second time around, the opacity animates from a value of 0 to a value of 0 since the tween is relative. What we want to do instead is always animate from a value of 0 to a value of 1 so here the easiest fix is to use a .fromTo(): See the Pen Random on Reset by GreenSock (@GreenSock) on CodePen. Now it does what we want. There are other solutions like using a .set() before the .from() but most often it’s easiest to just use a .fromTo() in cases like this. Not setting ALL transforms with GSAP If you are going to animate an element with GSAP, even the initial transform values (including on SVG elements) should be set with GSAP because it delivers better: Accuracy - The browser always reports computed values in pixels, thus it's impossible for GSAP to discern when you use another unit like % or vw in your CSS rule. Also, computed values are in matrix() or matrix3d() which are inherently ambiguous when it comes to rotation and scale. The matrix for 0, 360, and 720 degrees are identical. A scaleX of -1 results in the same matrix as something with rotation of 180 degrees and scaleY of -1. There are infinite combinations that are identical, but when you set transform-related values with GSAP, everything is saved in a perfectly accurate way. Performance - GSAP caches transform-related values to make things super fast. Parsing all of the components from a computed value is more expensive. If you are worried about a flash of unstyled content, you can handle that by using a technique that hides the element initially and then shows it via JavaScript as this post covers. Or you can set the initial styles with CSS rules and ALSO set them in GSAP. Not using xPercent and yPercent Did you know that you can combine percentage-based translation and other units? This is super useful if, for example, you'd like to align the center of an element with a particular offset, like {xPercent: -50, yPercent: -50, x: 100, y: 300}. We often see people use percent values in the x and y properties which is technically possible but can cause confusion at times. For example, if you set x and y to "-50%" and then later you set xPercent: -50, you'd see it move as if it's at xPercent: -100 because the x and xPercent both have -50%. Whenever you're setting a percentage-based translation, it's typically best to use the xPercent and yPercent properties. // Not recommended x: "50%", y: "50%", // Recommended xPercent: 50, yPercent: 50 Recreating animations over and over Creating your tweens and timelines beforehand has several advantages: Performance - Instead of having to create them right as they’re needed, you can do it ahead of time. Additionally, you need fewer instances of animations. Most of the time you’d never notice, but it’s good practice. Simplified logic - This is especially true when related to user interaction events. Freedom - Want to pause an animation when an event happens? Do it. Want to reverse an animation when the user does something? No problem. This sort of thing is much more difficult to handle when you create animations inside of event callbacks. Most of the time when you create animations beforehand, you will want to keep them paused until they’re needed. Then you can use control methods like .play(), .pause(), .reverse(), .progress(), .seek(), .restart(), and .timeScale() to affect their play state. Here’s a simple example: See the Pen Playing and reversing an animation on hover by GreenSock (@GreenSock) on CodePen. For more information related to creating animations beforehand, you can see the animating efficiently article. One exception to this rule is when you need things to be dynamic, like if the initial values may vary. For example, if you’re animating the height of the bars in a chart between various states and the user may click different buttons quickly, it’d make sense to create the animation each time to ensure they flow from whatever the current state is (even if it's mid-tween) like the demo below. See the Pen Playing and reversing an animation on hover by GreenSock (@GreenSock) on CodePen. Adding tweens to completed timelines A common pattern of mistakes that I’ve seen goes like this: const tl = gsap.timeline() tl.to(myElem, { x: 100 }); myElem.addEventListener("click", () => tl.to(myElem, { x: 300 }) ); Did you catch the mistake? If you add new tweens to a timeline that is already completed, they won’t be called unless you re-run the timeline. Almost always in these situations you should just use control methods for a previously created animation or create a new animation instead (not using an existing timeline) following the guidelines that we covered in the previous section. Not using loops If you want to apply the same effect to multiple elements (sections, cards, buttons, etc.) when a certain event happens to each one, you should almost always use a loop. For example, don’t use a selector like "button" when you want it to affect just one button. For example, if you wanted to fire an effect when each button is clicked: // BAD: immediately animates ALL buttons at once! gsap.effects.explode("button", { direction: "up", duration: 3 }); // GOOD: animation is specific to each button, and only when clicked gsap.utils.toArray("button").forEach(btn => btn.addEventListener("click", () => gsap.effects.explode(btn, { direction: "up", duration: 3 })) }); Inside of this loop, you can use a selector that is scoped to the given element so that you're only getting things INSIDE that element. For example: gsap.utils.toArray(".container").forEach(container => { let info = container.querySelector(".information"), silhouette = container.querySelector(".silhouette .cover"), tl = gsap.timeline({ paused: true }); tl.to(info, { yPercent: 0 }) .to(silhouette, { opacity: 0 }, 0); container.addEventListener("mouseenter", () => tl.play() ); container.addEventListener("mouseleave", () => tl.reverse() ); }); See the Pen Who&#39;s That Pok&eacute;mon? - forEach example demo by GreenSock (@GreenSock) on CodePen. Importing GSAP incorrectly A common issue people face when using GSAP in a module environment is importing GSAP or its plugins incorrectly. Most of the time import errors error can be avoided by thoroughly reading the relevant parts of the installation page. I won't copy all of the details into this post, but be sure to make use of that page if you're facing any sort of import error. It even has a very handy GSAP install helper tool that can generate the correct import code to use in most environments. Using the old/verbose syntax Drop the Lite/Max I regularly see people using the old syntax even though they are loading GSAP 3. Old habits die hard. Even though the old syntax still technically works, the new modern GSAP 3 syntax is sleeker and simpler. Plus the old syntax won't be supported in GSAP 4 (which is far off in the future, but it's still a good idea to write future-friendly code). For example instead of using something that has Lite/Max in it, just use gsap: // old TweenLite.to() TweenMax.from() new TimelineMax() // new gsap.to() gsap.from() gsap.timeline() Use the string form for eases The shorter string form of eases requires less typing and lets you avoid extra import statements in module environments. // old Power2.easeOut Sine.easeInOut // new "power2" // The default is .out "sine.inOut" Duration belongs in the vars parameter Putting the duration inside of the vars parameter does require a bit more typing, but it makes things more readable and intuitive. GSAP’s defaults and effects are very helpful but you can’t make use of them if you’re putting the duration as the second parameter. // old gsap.to(elem, 1, { x: 100 }); // new gsap.to(elem, { duration: 1, x: 100}); // using GSAP’s defaults: const tl = gsap.timeline({ defaults: { duration: 1 } }); tl.to(elem, { x: 100 }); // no duration necessary! tl.to(elem, { y: 100, duration: 3 }); // easily overwrite the default value For a more full listing of changes in GSAP 3, check out the GSAP 3 Migration Guide. Numerical values don’t usually need to be strings For example if you want to set the x transform to 100 pixels, you don’t need to say x: "100px", you can just say x: 100. Simple! The only time when you need to pass numerical values as strings are if you need to change the unit (like x: "10vw") or pass in a complex value (like transformOrigin: "0px 50px"). The target of a tween can be a selector string I often see people do something like this: gsap.to(document.querySelectorAll(".box"), { x: 100 }); Or even with jQuery: gsap.to($(".box"), { x: 100 }); Both of the above will work but could be simplified by passing a selector string in as the target; GSAP will automatically use .querySelectorAll() to get a list of all of the elements that match. So the above can be written simple as gsap.to(".box", { x: 100 }); You could also pass in a complex selector string like ".box, .card" and it will select all boxes and cards. Or use an Array of elements so long as they are of the same type (selector string, variable reference, generic object, etc.). Conclusion So how'd you do? Is your GSAP code clear of these common mistakes? Hopefully you learned a few things. As always, if you need any help, the GreenSock forums are a fantastic resource. We love to help people develop their animation superpowers. If you're looking for another great learning resource, read how to animate efficiently! Now go forth and tween responsibly!
  23. Hi everyone, I'm really newbie with gsap and I'm more than sure that I did some awful mistakes. Sorry in Advance if this was already asked / the answer is in documentation but I really couldn't find it and I managed to spend 8h trying to fix this ( deleting and remade-ing ) . So for short I found some really great examples and this one caught my eye: This one more precisely: https://codepen.io/osublake/pen/YrXdGZ -- I started to analyse it and I tried initially to migrate from gsap 2 to gsap 3 but unfortunately I managed to fail miserably. Afterwards I tried to recreate it from scratch to understand how it works where I failed but still ... I managed to get stuck. The main problem: I don't understand why in the demo this line: var animation = new TimelineMax({ repeat: -1, paused: true }) .add(baseTl.tweenFromTo(1, 2)) mainly starts the timeline in a great position and in my situation: _.animation = gsap.timeline({repeat: -1, paused: true}).add(_.timeline.tweenFromTo(1, 2)); it just stays in place. I also tried to reproduce Blake's example in localhost and it does the same thing ( after changing everything to gsap.timeline and gsap.to ). I'm thinking that I miss something or it's a bad thing on putting the timeline in 'this' object. In the end I just want to properly select the center object/objects and increase the scale . And I'm trying to implement a progressive scaling on each item like: 0.6-0.8-1-0.8-0.6
  24. Hi there! I have a question about how timelines are managed in GSAP 3. While a timeline's animation is running, in the js console I seem to be able to use: gsap.globalTimeline.restart(); If the animation has finished it ignores the restart completely. I can only get it to restart if call it while it's running. The project is a game, this is a particular scene, where I will need to restart the timeline and set a different player (between 1 and 4). Also as we're looking to use VUE.js as a single page application I expect will need a master timeline per scene. It's a bit complicated and a client/work related so I can't post it on codepen. If I can get this working and convince the team to use it then definitely interested in becoming a green sock member. There's nothing as powerful as GSAP for timeline management so definitely need to get this working. It's also worth mentioning during the script I can log the variables for the timelines I've created (tl) when the script runs, but not after it's finished running. Please ignore primarily what the animations are doing - as they're working well (it's a responsive scene of a player jumping over a bar then crying when they lose lol). It's mostly just being able to reset / rewind etc the main timeline and each other individual ones. As I can't seem to get either to work. $(document).ready(function () { var pCurrentPlayerNumber = 1; var currentplayer = ".player" + pCurrentPlayerNumber; var currentplayerwrapper = ".player" + pCurrentPlayerNumber + "-wrapper"; console.log(currentplayer); console.log(currentplayerwrapper); var tlSetStage = gsap.timeline(); tlSetStage.set(currentplayer, {className: "+=visible"}) .set(currentplayerwrapper, {className: "+=centercenter"}) .set(".currentplayername", {className: "+=p" + pCurrentPlayerNumber + "-bg"}) .set(currentplayerwrapper, {transform: "translateZ(200px)"}) .set(".highjump-set.fg", {transform: "translateZ(400px)"}) .set(".highjump-set", {className: "+=centercenter"}) .set(".highjump-set", {xPercent: 300}); var tl = gsap.timeline(); tl.set(currentplayerwrapper, {xPercent: -300, yPercent:-50}) .set(".highjump-set", {xPercent: 300}) .set(currentplayer, {className: "+=stancePlayerRunFast"}) .to(currentplayerwrapper, {xPercent: "+=200", yPercent:-50, duration: 1, delay:1}) .to(".highjump-set", {xPercent: "-=280", yPercent:-50, duration: 1, delay:0},1) .set(currentplayer, {className: "-=stancePlayerRunFast"}) .set(currentplayer, {className: "+=stancePlayerJump"}) .to(currentplayerwrapper, {xPercent: "+=50", rotationY:-180, yPercent:-50, duration: 0.5}) .to(".highjump-set", {xPercent: "-=10", yPercent:-50, duration: 1, delay:0},2) .set(currentplayer, {className: "+=aniPlayerPaused"}) .to(currentplayerwrapper, {xPercent: "+=10", rotationY:-180, yPercent: -80, rotationZ: 50, ease: "power4.Out", duration: 0.5}) .to(".highjump-set", {xPercent: "-=20", yPercent:-50, duration: 1, delay:0},3) .to(".highjump-pole-hoz", {xPercent: "+=70", yPercent:"+=330", duration: 0.5, delay:0},3) .to(".highjump-pole-hoz", {yPercent:"-=190", duration: 0.5, delay:0},3.5) .to(".highjump-pole-hoz", {xPercent: "+=20", yPercent:"+=220", duration: 0.5, delay:0},4) .to(currentplayerwrapper, {xPercent: "+=20", rotationY:-180, yPercent: -20, rotationZ: 100, ease: "power4.Out", duration: 0.5},4) .to(".highjump-set", {xPercent: "-=20", yPercent:-50, duration: 1, delay:0},4) .to(currentplayerwrapper, {xPercent: "+=20", rotationY:-180, duration: 2}) .set(currentplayer, {className: "-=stancePlayerJump"}) .to(currentplayerwrapper, {xPercent: "+=20", rotationY:-180, rotationZ: 0, duration: 0.5}) .set(currentplayer, {className: "-=aniPlayerPaused"}) .set(currentplayer, {className: "+=stancePlayerCry"}) .to(currentplayerwrapper, {rotationY:-180, rotationZ: 0, duration: 2}); console.log(tl); }); If I try to restart them using the below command I get a not defined error. Should I be doing each timeline as a function? tl.restart(); or tlSetStage.restart(); Ideally if I can at least just get the master timeline to reset at this stage it would be a win. Being able to reset individual timelines would also be great. Any help very much appreciated!
  25. Hi there! I'm trying to make this horizontal section to "stick" or "snap" the next or prev slide based on the scroll wheel event, but i'm unable to do so. The main goal is, no matter how long the scroll event lasts, it should simple move/scroll to the next or prev slide. Am taking the wrong approach for that (using scrollTrigger and end())? https://codepen.io/jimmyadaro/pen/jOWaZZV I've tried copying this Codepen since it achieves what i'm looking for, but had no success with that. https://codepen.io/mikeK/pen/eoyrWK?editors=0010
×