Jump to content
Search Community

Rodrigo last won the day on March 27

Rodrigo had the most liked content!

Rodrigo

Administrators
  • Posts

    6,318
  • Joined

  • Last visited

  • Days Won

    274

Everything posted by Rodrigo

  1. Hi, Here are some demos that should help: https://codepen.io/GreenSock/pen/xxmPjOv https://codepen.io/GreenSock/pen/oNQNrQx https://codepen.io/GreenSock/pen/wvYVjvb Happy Tweening!
  2. Hi, Just with CSS I'm not aware, but I'm far from being a CSS wiki so take my word with a giant grain of salt since most likely is possible, I'm just ignorant on the fact. But with GSAP is super easy though: gsap.set(slider, { width: slider.scrollWidth, }); Here is a demo: https://codepen.io/GreenSock/pen/bGJpOoQ Hopefully this helps. Happy Tweening!
  3. Hi, Here is another demo: https://codepen.io/GreenSock/pen/QWrmdxP It uses an actual video but the principle is basically the same. Hopefully this helps. Happy Tweening!
  4. Handling the mouse enter/leave on each menu element is a completely different thing and you shouldn't animate the background of the entire heading, just each element: https://codepen.io/GreenSock/pen/MWRomzq Hopefully this helps. Happy Tweening!
  5. Still on the phone so I can't check your demo, but based on your description maybe something like this with the scrollTo plugin https://codepen.io/GreenSock/pen/NWxNEwY Happy Tweening!
  6. Hi, I'm on my phone now so I can't have a good look at your demo, but this codepen should give you a good idea about how to proceed on this case: https://codepen.io/GreenSock/pen/mdVyPvK Instead of using a class toggling, use scrolltrigger toggleActions config, to play the animation in the onEnter part: toggleActions String - Determines how the linked animation is controlled at the 4 distinct toggle places - onEnter, onLeave, onEnterBack, and onLeaveBack, in that order. The default is play none none none. So toggleActions: "play pause resume reset" will play the animation when entering, pause it when leaving, resume it when entering again backwards, and reset (rewind back to the beginning) when scrolling all the way back past the beginning. You can use any of the following keywords for each action: "play", "pause", "resume", "reset", "restart", "complete", "reverse", and "none". Something like this but without reversing the animation https://codepen.io/GreenSock/pen/qBawMGb Hopefully this helps Happy Tweening!
  7. Hi, I’m not in front of my computer right now, but mainly the issue stems from when the gasp instances are created, in this case when the component is mounted so the elements are the ones present at that point. You should create a watcher and create the animations when the array is updated (you’re using a v-for directive so I’ll assume that an array is involved). https://vuejs.org/guide/essentials/watchers.html Hopefully this helps. Happy Tweening!
  8. Hi @Muc and welcome to the GSAP Forums! There is no rotation on the Y axis in SVG, just plain 2D rotation, nothing more. Is not a GSAP issue just the way things are with SVG. I'm afraid that your bee is just drawn in the wrong direction. I made a few tweaks to your demo and also added the pathEase helper function that Jack created to help in this cases: https://codepen.io/GreenSock/pen/wvZdpwL Is worth noticing that it would be better to avoid your path to have up and downs in it in order to avoid those sudden jumps in the animation as shown in this demo: https://codepen.io/GreenSock/pen/GRoXzYj Hopefully this helps. Happy Tweening!
  9. Hi, In the SrollTrigger config is markers (plural) not marker: // Wrong scrollTrigger: { marker: true, }, // Right scrollTrigger: { markers: true, }, Also once again you're making the same mistake. Sooner or later this will become a logical issue: const menuTimeline = gsap.timeline({ scrollTrigger: { trigger: "#pin-container-2", pin: "#pin-container-2", pinnedContainer: "#pin-container-2", start: "top top", // YOU HAVE SCRUB HERE scrub: true, markers: { indent: 140 }, id: "menu" } }); Then you have this: function selectEgg() { menuTimeline.reverse(); } function selectFish() { menuTimeline.reverse(); } Your menu timeline's playhead position is controlled by the scroll position when using scrub, then you want to reverse it using a button, which can be done, but as soon as the user scrolls ScrollTrigger will update the same timeline's playhead position based on the scroll position which will make the menu elements visible again and behave in an erratic fashion. You cannot have a scrubbed animation play/reverse using other event handlers unless you remove the ScrollTrigger instance associated with it, in which case you no longer will be able to scrub that GSAP instance. IMHO it should be like this: const menuTimeline = gsap.timeline({ scrollTrigger: { trigger: "#pin-container-2", pin: "#pin-container-2", pinnedContainer: "#pin-container-2", start: "top top", toggleActions: "play none none reverse", markers: { indent: 140 }, id: "menu" } }); Finally I think this is not a good approach as well: function selectEgg() { menuTimeline.reverse(); const eggTimeline = gsap.timeline({ scrollTrigger: { trigger: "#pin-container-2", pin: "#pin-container-2", pinnedContainer: "#pin-container-2", start: "top top", scrub: true, markers: { indent: 300 }, id: "btn" } }); eggTimeline .to("#besteck-2", { display: "block", x: "-20vw" }) .to("#egg-dish", { display: "block", x: "-60vw" }); } I wouldn't create a GSAP instance controlled by ScrollTrigger on an event handler. What happens if the user opens the menu and clicks on that button again? The same instance will be created again, but the previous one is already there and the same element is already pinned. Finally I think you are overcomplicating this quite a bit and because of that your app has several logic and architectural issues. I think the best approach right now is to decide what exactly you want to do and start by creating an HTML and CSS structure that looks the way you want. Then start adding animations one by one, go section by section and then also start adding complexity to this. It seems to me that you are a bit over your head right now, so that's why going back to basics should be a solid first step. Hopefully this helps. Happy Tweening!
  10. Hi, There is one issue in your code, but before that as an advice is always a better practice to give your files (CSS, JS, Images, etc.) a relative path, right now you have this: <link rel="stylesheet" href="style.css" /> <script src="script.js"></script> That basically tells the browser to look for those files at the root of the server, in some cases is better to use relative paths based on the current folder: <link rel="stylesheet" href="./style.css" /> <script src="./script.js"></script> Now onto the issue, you have a wrong tertiary operator in your code here: shuffledText += i < index ? originalText[i].Math.random().toString(36)[2]; You're missing the second part of that logical operator: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_operator Finally is worth noticing that porting this demo into a codepen minimal demo shouldn't be too hard and would've made the issue visible a long time ago without the need for all this: Hopefully this helps. Happy Tweening!
  11. In the case of the O letter, yeah those are two different paths most likely, so you'll have to start both of them at the same time and be sure that they start point is basically the same so the lines are animated in the same direction and end at the same time as well. I would recommend you to take a look at this tutorials by @PointC https://www.motiontricks.com/cut-your-path-start-points-in-adobe-illustrator/ https://www.motiontricks.com/better-svg-exports-make-animations-easier/ With the assets in the right way, the DrawSVG Plugin will create the animation you are looking for. It might take a a few tweaks here and there (every project is different and has it's own peculiarities) but it could definitely be done. Finally you can fork this codepen starter template in order to create a minimal demo that illustrates what you're trying to achieve: https://codepen.io/GreenSock/pen/aYYOdN Happy Tweening!
  12. Just use toggleActions in ScrollTrigger: https://codepen.io/GreenSock/pen/qBwmPxB Hopefully this helps. Happy Tweening!
  13. Yeah I'd just use GSAP for the whole thing. If you use a mix and then you want/need to do something on those same elements with GSAP, you'll have to refactor everything in order to accommodate that. Better get it done at the start of the project just in case. Sure enough the demo is using a class but my preference is to not go that route. At the end is mostly what works for you based on the requirements and constraints of your project, there is no just one right way to do things in this particular case. Happy Tweening!
  14. Hi, As well as Cassie I'm a bit confused about your approach. We have a codepen collection filled with ScrollTrigger demos that could be helpful: https://codepen.io/collection/AEbkkJ?cursor=eyJwYWdlIjoxMn0= Also, if I'm understanding correctly what you're trying to do, maybe some of these demos could help: https://codepen.io/GreenSock/pen/NWMZrbj https://codepen.io/GreenSock/pen/eYQYxJW https://codepen.io/GreenSock/pen/wvYVjvb Happy Tweening!
  15. Hi, One solution is to wrap the lotties section and the next one in a common parent and pin that one: https://codepen.io/GreenSock/pen/ExJmWdp The other solution is to create two ScrollTrigger instances to pin both sections at the same time for each lottie section and use pinSpacing false for the looties wrapper: https://codepen.io/GreenSock/pen/ZEZeLmL Hopefully this helps. Happy Tweening!
  16. Hi, That is super simple with GSAP and the DrawSVG Plugin: https://codepen.io/GreenSock/pen/jEEoyw https://gsap.com/docs/v3/Plugins/DrawSVGPlugin Happy Tweening!
  17. Hi, You can use live snap with your own custom logic and use that function to do what you're after: https://gsap.com/docs/v3/Plugins/Draggable/#as-a-function-with-custom-logic If you keep having issues, remember to post a minimal demo. Happy Tweening!
  18. Hi, I'm not a wordpress developer so I couldn't really tell you about this, but there are several issues reported with elementor and the transition: all 0.3s; style that it applies to the elements. That is bound to interfere with everything GSAP tries to animates on those elements as Jack explains here: Also you can achieve the same functionality with ScrollTrigger, which would be my approach TBH: https://codepen.io/GreenSock/pen/mdVyPvK Finally is super weird that you are using GSAP to just set styles values so the transition: all stuff animates them, I would definitely wouldn't do that as well. Happy Tweening!
  19. Hi, Try removing the lock file from your repo and pushing that again and see if the installation works. If that doesn't work you'll have to add your privjs token to the .npmrc file in order to install it for the first time, then you can remove the token from the .npmrc file and it should work for future deploys. Hopefully this is a private repo so your token doesn't get exposed. Hopefully this helps. Happy Tweening!
  20. No, is totally fine to keep everything in a single timeline if you're carefully. In this particular case is better to move some animations out of the timeline. Is not a rule carved in stone is a case-by-case thing. Every project has it's own peculiarities and you should plan and develop them as you go based on the requirements of the project. In this case you can keep your timeline with the scrub in it just, instead of adding the menu part at the end, remove it and make that a different timeline, then you can use the onLeave and onEnterBack callbacks to play/reverse that timeline and then you can also reverse that timeline when clicking the buttons as well in order to hide that menu: // Timeline just for the menu elements const menuTimeline = gsap.timeline({ paused: true, }); // Add animations to the menu and buttons timeline const tl2 = gsap.timeline({ scrollTrigger: { // other configs scrub: 1, // use callbacks to play/reverse the menu timeline onLeave: () => menuTimeline.play(), onEnterBack: () => menuTimeline.reverse(), markers: true // shows the markers } }); // Then in your menu buttons btn.addEventListener("click", () => { menuTimeline.reverse(); // Then create other animations as well }); From the ScrollTrigger docs: onLeave Function - A callback for when the scroll position moves forward past the "end" (typically when the trigger is scrolled out of view). onEnterBack Function - A callback for when the scroll position moves backward past the "end" (typically when the trigger is scrolled back into view). Right now I'm on my way out so I can't take a good look to your demo, but hopefully this helps. Happy Tweening!
  21. Hi @katling and welcome to the GSAP Forums! Sorry to hear about the frustrations, can relate that is no fun at all I believe the issues here are mostly logic-related ones. You have a timeline that is controlled by ScrollTrigger and that is scrubbed, that being said the playhead of the timeline is controlled by the progress of the ScrollTrigger instance based on the start and end points you pass to ScrollTrigger's configuration. Then in your buttons you have this: function selectEgg() { tl2 .fromTo("#menu-card", { x: "25vw" }, { x: "150vw" }) .fromTo(".menu-button", { opacity: 1 }, { opacity: 0 }) .fromTo("#menu-msg", { opacity: 1 }, { opacity: 0 }) .to("#menu-card", { display: "none" }) .to("#choose-menu", { display: "none" }) .fromTo( "#egg-dish", { display: "none", x: "100vw" }, { display: "block", x: "25vw" } ) .to("#egg-info", { display: "flex", opacity: 1 }); } function selectFish() { tl2 .fromTo("#menu-card", { x: "25vw" }, { x: "150vw" }) .fromTo(".menu-button", { opacity: 1 }, { opacity: 0 }) .fromTo("#menu-msg", { opacity: 1 }, { opacity: 0 }) .to("#menu-card", { display: "none" }) .to("#choose-menu", { display: "none" }) .fromTo( "#fish-dish", { x: "100vw", delay: 5 }, { display: "block", x: "25vw" } ) .to("#fish-info", { display: "flex", opacity: 1 }); } You are adding instances to the SAME timeline that is being controlled by ScrollTrigger, even further you're adding them once you have scrolled past the end trigger of the ScrollTrigger config (because your buttons are visible after that particular point). This spells trouble to me because you're extending a timeline whose playhead is already at the end or being tweened there (because you have a numeric value in your scrub config and a large one as well - more on that later). That of course is going to generate a jump and some erratic behaviour and you have to add to it the fact that you are using fromTo instances, which will change the current value of the property you're animating immediately to the value in the from configuration object and then tween it to the value in the to configuration object. You are animating the same elements that are being animated by the timeline controlled by ScrollTrigger with a scrub value in it. If for any reason the user scrolls while those animations are running, things can get really messed up because you'll have two instances battling for control over the same elements. Definitely don't do that. You have a very large value for scrub (10) that means that it takes 10 seconds for the timeline to catch up with the scroll position and the progress of the ScrollTrigger instance. Any particular reason for a value that big? The first thing you should do is avoid 1 and 2. Create completely different animations and don't animate the same elements that are being animated with the timeline that is controlled with ScrollTrigger. If you keep having issues, please change your demo so instead of images that are not loaded, use just colored divs to show what you're trying to do. Hopefully this helps. Happy Tweening!
  22. Sorry but I don't really understand what you mean with wonky, unfortunately vague descriptions like it's broken, doesn't work, wonky, etc. don't really tell us what the issue is 🤷‍♂️ Please be more specific about what is not working. Finally this doesn't look good: items.forEach((item1, i) => { let sections = gsap.utils.toArray('.object .image') as HTMLElement[]; const slide = item1.querySelector('.slide') as HTMLElement | null; const content = item1.querySelector('.content1') as HTMLElement | null; const hasChild = item1.dataset.hasChild; tlCards .to(item1, { height: 0 }) .to(items[i + 1], { height: 'auto' }, '<'); document.querySelectorAll('.slideItem').forEach((slideItem) => { const childItem = slideItem.querySelector('.item'); if (slide) { const hasChild = slide.dataset.hasChild; if (hasChild) { tlCards.fromTo( childItem, { x: slide.clientWidth - slide.clientHeight, opacity: 0, duration: 4, }, { opacity: 1, duration: 1 } ); } } }); }); Why are you nesting loops? Why are you doing a conditional check inside the second loop for the slide constant that is defined outside that loop? That all spells trouble to me. Once again (this is not the first time I recommended this to you) drop all the complex stuff and stay away from react and other frameworks and focus on making the most elemental part of this work first, then port it to react and add more functionality to it. Happy Tweening!
  23. As Jack mentions this is related to the way you're handling your layout here: gsap.set(".panel", { zIndex: (i, target, targets) => targets.length - i, position: "absolute", width: "100%", minHeight: "100%" }); Basically that removes every panel from the flow of it's parent element, then ScrollTrigger makes the calculations and sees that the element's height is zero. If you comment out the ScrollTrigger part from your demo you'll get the same result. So as mentioned before this has nothing to do with ScrollTrigger, just the way things work in HTML/CSS with positioning. That's because you're creating a single instance that handles all the sections with the same duration and stagger value. You need to factor the duration of each tween based on the height of each section and the smallest section you have. Something like this: const footerHeight = footer.offsetHeight; const panels = gsap.utils.toArray(".panel"); let min; let mainSectionSum = 0; const heights = panels.map((panel) => { const height = panel.offsetHeight; min = min ? (height < min ? height : min) : height; mainSectionSum += height; return height; }); const tl = gsap.timeline(); panels.forEach((panel, i) => { tl.to(panel, { yPercent: -100, ease: "none", duration: heights[i] / min }); }); Here is a fork of your demo: https://codepen.io/GreenSock/pen/rNbyyjJ Hopefully this helps. Happy Tweening!
  24. Rodrigo

    Vertical scroll

    Yeah that makes matters a bit more difficult for sure. Unfortunately because of the way pinning works there are not a lot of options here. The only solution I can think of is to pin both sections at the same time using different ScrollTriggers: https://codepen.io/GreenSock/pen/ZEZeLmL Hopefully this helps. Happy Tweening!
  25. Hi, I just tested the last two demos Blake shared and I don't see any issues neither in an Android phone nor an iPad 🤷‍♂️
×
×
  • Create New...