Jump to content
GreenSock

Leaderboard

Popular Content

Showing content with the highest reputation since 09/01/2022 in all areas

  1. @webflow.be welcome to the forum! Creating a clean SVG is half the work when working with SVGs. I have no idea where your SVG came from, but it was a mess for such a simple file (some programs will do that ). I've cleaned it up a bit, so that it is just the 6 letters in the SVG. You could run your SVGs through SVGGO to help clean it up automatically, but I did it by hand and then loaded it in Figma to modify it visually. What I've coded is giving all the letters a transform on the x axis to the middle of the SVG. This looks like complicated code, but it is just getting the width of the SVG and the X offset of all the letters. If you then do a .from() tween they will animate from that position to their original position. From your slides I think you want only the two letters E's to be visible at on page load, but I'll leave that to you. I would suggest giving all the letters a class to indicate if they need to be visible or not and then add another tween that makes these letters visible, you can play with the position parameter (take a look at the docs) to have all the tween start at the same time. If you are stuck be sure to post back here, but nobody learns from copy and pasting code , so I challenge you to see how far you can come! https://codepen.io/mvaneijgen/pen/yLjMeEJ Veel geluk en succes!
    5 points
  2. Speaking as someone who is also relatively new to GSAP, I really recommend the courses @Carl runs at creativecodingclub.com. Having already gone through many, many hours of the content on there I can tell you there's some really good, clear information on the difference between from, to, and fromTo tweens as well as the "flicker" you mentioned and how to address it.
    5 points
  3. Just thought I'd say I've been tracking Carl's svg lessons knowing that I should do them at somepoint, but this first mini project I just got by email looks quality. That is all. (Well except Carl, is there any chance one of your projects involves zooming into svg backgrounds?) I swear he didn't pay me for this ๐Ÿ˜„, but I feel like this series is morphing into somthing I should do, and I *hate* svgs **Edit: creativecodingclub.com ๐Ÿ‘
    4 points
  4. thanks for the assist, @Cassie those are lovely illustrations. I'm currently working on showing folks how to fit a very tall and thin monster into a square or variable size viewport. Yes, the background-size metaphor is very helpful and I have a reference to it in there. Not sure where I heard it first but maybe it was you! Thanks so much! Carl
    4 points
  5. Welcome to the forums, @sarahholden! Congrats on stepping out and posting your first question (after lurking for a while). ๐Ÿ’š From what I can tell, the browser doesn't really honor the request to event.preventDefault() on wheel events when scrolling is in-progress, at least on some devices like my Mac. Very annoying, and I'd argue wildly incorrect behavior, but don't worry - we can work around it: let preventScroll = ScrollTrigger.observe({ preventDefault: true, type: "wheel,scroll", allowClicks: true, onEnable: self => self.savedScroll = self.scrollY(), // save the scroll position onChangeY: self => self.scrollY(self.savedScroll) // refuse to scroll }); preventScroll.disable(); Basically, we have to save the scroll position and revert it every time it tries to change. Here's the revised demo: https://codepen.io/GreenSock/pen/MWGVJYL?editors=0010 Does that help?
    4 points
  6. Hello @kovle I think that's a logic issue you are having - as you are hit-testing on a jQuery object that contains multiple elements, similar to an array/nodelist, it will probably only ever target/work on the first element in that list, so you will probably have to modify things to be targetting specific elements instead. Since you appear to want to have the hit-testing on each of your elements in the drop area, you could e.g. do that with an each-loop. I'm not sure how heavy this will be on the performance in the long run, as it will be happening for each of those elements on every drag-event, but this seems to work much more like what I understood you want to happen. onDrag: function(e){ const dragged = this drop_area.each(function(i,el) { if(dragged.hitTest(el, hit_detection)){ $(el).addClass("hit"); }else{ $(el).removeClass("hit"); } }) }, https://codepen.io/akapowl/pen/mdLXgqY Since it looks like you were mixing vanilla JS with jQuery a bit in that example of yours, I just wanted to mention that of course you could also do all that without jQuery involved - but that is up to you of course. Here is that example with the latest GSAP / Draggable in vanilla JS. https://codepen.io/akapowl/pen/GRdQaqo
    4 points
  7. Heads up that the elements don't scale in in chrome due to this newly introduced rendering bug (not a GSAP bug - a browser one ๐Ÿ›) https://bugs.chromium.org/p/chromium/issues/detail?id=1368232 If you add a small rotation to the group it fixes the issue https://codepen.io/GreenSock/pen/qBYxoyX?editors=0010
    4 points
  8. Hi @maipo89 and welcome to the GreenSock forums! Thanks for the simple demo, made it super easy! You have to use the Position Parameter in a timeline in order to alter the default order of execution. Normally, as you've already seen, tweens inside a timeline run in a regular sequential order. But you can play with that based on your project's requirements using the position parameter and labels as you can see in the documentation: https://greensock.com/docs/v3/GSAP/Timeline But for this particular case all you need is to add a less than sign on each text tween in order to make this work. const tl = gsap .timeline({ scrollTrigger: { trigger: ".quote", scrub: true, pin: true, markers: true, start: "50% 50%", end: "+=200%" } }) .from(".image", { scale: 0.5, ease: "none" }) .from(".title", { top: "150px", ease: "none" }, "<") .from(".subtitle", { top: "450px", ease: "none" }, "<"); That basically tells GSAP to start that tween when the last one starts, so that means both start at the same time. In the case of the second text (subtitle) is the same thing, start when the first text starts and, since the first text starts with the image tween, they all start at the same time. You can also use absolute positioning by replacing "<" with a 0: const tl = gsap .timeline({ scrollTrigger: { trigger: ".quote", scrub: true, pin: true, markers: true, start: "50% 50%", end: "+=200%" } }) .from(".image", { scale: 0.5, ease: "none" }) .from(".title", { top: "150px", ease: "none" }, 0) .from(".subtitle", { top: "450px", ease: "none" }, 0); Since your timeline is rather simple and has just those three instances that should start at the same time, using zero as position works as well. Here is a live example: https://codepen.io/GreenSock/pen/XWqVPxP Happy Tweening!
    4 points
  9. All the animations start at the same time, but the once from the left start at -100 that is 100% to the left of the browser eg they are not visible. So I think you like to stay between 0 ,100 instead of -100, 100. That is not randomly. If you do random they could all come from the same direction. I would build a more elaborate wrap so that you have the control you want. const wrap = gsap.utils.wrap([-100, 100, 70, -20, -50, 70, -20, 50, 0, 40]) you can add as much numbers as you want, just play with these until you find something that works for you. https://codepen.io/mvaneijgen/pen/zYjpPjw
    4 points
  10. Yep, @Carl is a living legend in GreenSock land, a great influence for most of us around here and an excellent teacher. Since we are doing requests: Carl can the Unfortunate Chicken ๐Ÿ” make it into the lessons, or is still recovering from the bomb and brick incidents?
    4 points
  11. If I understand correctly what it is you want to do, transformOrigin will not be helpful here, @amit95 Instead, you might want to use the stagger as an object, so you can define its settings in more detail. I changed the stagger of your closing tween to this e.g. // old stagger: .2 // new stagger: { each: .2, from: 'end' } So, did you mean like this? https://codepen.io/akapowl/pen/gOzxPgx
    4 points
  12. Hi @div138, What worked for me was: 1. renaming the file ScrollSmoother.min.js to ScrollSmoother.min.txt 2. Upload the .txt file to Webflow 3. Then find the URL of the uploaded .txt file - should look something like this <script src="https://uploads-ssl.webflow.com/62e3acd626f7sd0ac59653c2/6we913e507820a453df444d7_ScrollSmoother.min.txt"></script> 4. It will still be able to read the js inside the .txt file. Hope that helps
    4 points
  13. Hi, You can use the Snap Plugin for that: https://greensock.com/docs/v3/GSAP/CorePlugins/SnapPlugin It should be as simple as: gsap.to(myFilter, { size: 80, snap: "size", duration: 5 }); This is a core plugin so you don't need to include any other file, import or register the plugin. Let us know how it works. Happy Tweening!!!
    4 points
  14. Hi Martin! You have multiples ways to do that. First, you can simply add an "onComplete" function to trigger when your SVG is completely draw. .from(".path-1", {drawSVG: 0, onComplete: () => { console.log('Completed'); }}, 0) In an other hand, you can done your scrolltrigger inner a timeline and call your border-color change after like you do now, but like that: main.from(".path-1", {drawSVG: 0}, 0) main.to(".path-1", {stroke: '#ff0000'}); (For the example I change the stroke color of your SVG, but feel free to change it for do your stuff with the .box) Or, in your actual scrolltrigger code, you can use onLeave, onEnterBack function. Best regards! Sam
    4 points
  15. Hey @raana, Your codesandbox sample doesn't have any scroll on the main container, so making this adjustment creates a scroll to test how ScrollTrigger is working: <div style={{ height: "100vh" }}></div> <div className="index-module--container--J02ig"> <!-- REST OF YOUR JSX --> </div> <div style={{ height: "200vh" }}></div> As for running a ScrollTrigger animation (or a part of it) when the page loads, you'll have to tinker with the start position of the ScrollTrigger instance to play part of the animation after the content is loaded. Happy Tweening!!!
    4 points
  16. Hi and welcome to the GreenSock forums. Why not create the particles in the SVG? it doesn't seem to create a performance issue: https://codepen.io/rhernando/pen/ExLPWxJ?editors=0010 Trying to line-up correctly the SVG and the DIV with the particles could become a bit complicated, so I'd try to exhaust every possibility of using just SVG for this. Happy Tweening!!!
    4 points
  17. Hey Andrew, have a look at my solution here: I had some issues with a client's weird Windows/mouse setup, but on other machines it works just fine.
    4 points
  18. Yeah, I think some browsers just don't render transforms on textPath or textSpan elements because they're considered "inline" (same for <span> elements). It's totally unrelated to GSAP. With the newer SVG2 spec, it seems some browsers are shifting to support it. https://lists.w3.org/Archives/Public/www-svg/2016Jan/0010.html In short, I wouldn't recommend doing it if you want 100% browser support. Do what Carl showed. Or wrap it in a <g>. ๐Ÿ‘
    4 points
  19. it may be as simple as calling gsap.globalTimeline.progress(1) https://greensock.com/docs/v3/GSAP/gsap.globalTimeline if that doesn't work or causes issues with gameplay try exportRoot() var tl = gsap.exportRoot(); tl.progress(1) https://greensock.com/docs/v3/GSAP/gsap.exportRoot()
    4 points
  20. Hello, You can use the onEnter and onEnterBack callbacks from ScrollTrigger to set/unset the active class on the links elements. Check this codepen to see how it works: https://codepen.io/GreenSock/pen/bGVjLwG Happy Tweening!!!
    4 points
  21. that's a pretty cool effect. thanks for the demo. Inside the first loop you have access to the index of the text button so you can use that to target its respective digit. https://codepen.io/snorkltv/pen/MWGVmqq?editors=1010
    3 points
  22. Thanks so much Carl! That article is amazing and now bookmarked. SVG Origin is what I wanted but failed to find, thank you. Yep my quickly put together SVG is not centered in the viewbox. Fixed and working here: https://codepen.io/kabocreative/pen/rNvpZMY Thanks for showing how to work with awkward alternatives though in the second example, also super useful!
    3 points
  23. hi Penni, you can use the svgOrigin https://codepen.io/snorkltv/pen/dyeJrVJ I don't think your dashed circle is perfectly centered which is why using the center of the svg doesn't look exactly right. learn more about svgOrigin or you can modify the transformOrigin so that it lines up with the center of the dashed path kind of like... https://codepen.io/snorkltv/pen/gOzoEGB?editors=1010
    3 points
  24. This is because the actual scroll direction is vertical, so it's not picking up on those animations. What you are looking for is using Container animations: Demo here: https://codepen.io/GreenSock/pen/WNjaxKp
    3 points
  25. Welcome to the GrenSock forum! There's lots of ways to do that - and depending on what exactly you want to do, one is suited better than another. You will probably best want to look into either timelines or callbacks (everything starting with on... in the Special Properties section of the docs). https://codepen.io/akapowl/pen/KKRXYXo
    3 points
  26. To my knowledge, you should avoid combining ScrollTrigger and scroll-behavior: smooth. The reason is that you don't want the two fighting over what the true scroll behavior is, and when you use scroll-behavior smooth, it is handled by CSS and not accessible in the same way to GSAP. Is there a reason you need scroll-behavior smooth?
    3 points
  27. @Geoff Dawes and @___wtem___, Thanks a lot for contributing to this thread ๐Ÿฅณ We really appreciate your help and input! Happy Tweening!!!
    3 points
  28. Hi, It is actually working, we just can't see it The issue is that it starts from the first image that is at the bottom of the stack of images. But lucky for us GSAP has advanced staggers that help you with this: el.addEventListener("mouseover", (e) => { gsap.to(".first", { scale: 0.5, duration: 0.6, stagger: { each: 0.1, from: "end" } }); }); https://codepen.io/GreenSock/pen/gOzxvGQ Happy Tweening!!!
    3 points
  29. Hi @hanifrev and welcome to the GreenSock forums! This is a simple example of creating a ScrollTrigger in a React app: https://codepen.io/GreenSock/pen/zYjdoNo Happy Tweening!!!
    3 points
  30. Hello everyone! I wanted to let you know that I created a vscode extension called "Gsap GreenSock Snippets", it already has more than 40 different snippets and I am planning to eventually add more. I hope you can give it a try and find it useful. Happy tweening! Max.
    3 points
  31. That should be resolved in the next release which you can preview at https://assets.codepen.io/16327/gsap-latest-beta.min.js It is actually rather annoying that browsers are now trying to do something GSAP has been able to do for almost 10 years, and they're still not even close to parity. It forces us to apply workarounds because some browsers merge them with transforms and some don't. We have to merge them ourselves and then set translate/scale/rotate to "none" to prevent contamination. And without GSAP, you still can't independently control "x" and "y" (they're merged in translate for the browser). And there's no skew. Same thing about breaking apart scaleX and scaleY. But yeah, we've already implemented forced merging of that data into the normal "transform" that GSAP applies. I'm with @mvaneijgen - I wouldn't personally use any of the new scale/translate/rotate CSS properties due to compatibility issues and other limitations. I'd just go directly through GSAP. Or if you need to set something up in its initial state, you could use CSS "transform" which is universally compatible.
    3 points
  32. As you can see in the DevTools GSAP is transforming the `transform: scale(2, 2)` property and you are targeting the `scale:` property directly. This is a bit of a new feature in CSS and targeting it directly has less support by browsers. It is really interesting that we're in a transition phase now with these properties and I'm also interested in what @GreenSock thinks of this. Personally I'm sticking with `transform: scale()` for now, but I do have to admit that targeting the properties directly is much more intuitive. https://codepen.io/mvaneijgen/pen/JjvEQzb
    3 points
  33. I think Safari requires your SVG with the moving elements to have a width and height in the CSS. I popped width: 100%; height: 100%; into inspect and it showed up.
    3 points
  34. When we say that the core includes CSSPlugin, we're talking about the gsap.min.js file that you'd load via a <script> tag as well as the file you'd get when you import from "gsap" in a module environment like this: import gsap from "gsap"; You, however, appear to be trying to tap into the file in a very different way - directly via the gsap-core.js file in the src folder which is very different. For development, we separated out CSSPlugin from the core GSAP code and then stitch them together for the exports. So the gsap-core.js file does NOT include CSSPlugin. This was also strategic so that if a savvy developer was using GSAP only to animate non-DOM stuff (like <canvas> objects), they could cut out some file size by only using the gsap-core.js source file. Is there a particular reason you're trying to access the gsap-core.js file directly instead of the esm/gsap.js file? I mean it's fine if you want to do that I guess - just make sure you also load (and register) CSSPlugin if you're doing anything with the DOM/CSS.
    3 points
  35. I've added the height of the element to the endTriggers height which makes it that it stops at the end of the section. https://codepen.io/mvaneijgen/pen/oNdYoVE?editors=0010 you can also do this dynamically by getting the hight of the element with JS https://codepen.io/mvaneijgen/pen/BaxQmEE?editors=0010 btw `TimelineMax` is really old syntax from GSAP 2, see the migration guide to update to the new syntax
    3 points
  36. Is this what you're looking for? https://codepen.io/DDI-Web-Team/pen/wvjzNEm/d87d5a5aa0dddcde12ddc5d7deb87404?editors=1111 const stats = document.querySelectorAll('div > h3 > span'); for (const stat of stats){ gsap.to(stat, {innerText: stat.dataset.value, snap:{innerText:stat.dataset.interval}, duration:3}) }
    3 points
  37. Sure - then you'll need a vertical scrollTrigger for that one, same deal, just not using containerAnimation! https://codepen.io/GreenSock/pen/JjvXMWQ?editors=0010
    3 points
  38. These where my edits, so please ignore these @Denis Gonchar
    3 points
  39. So... Invalidation resolved the issue. timeline.pause(0).invalidate().play(0); The question now: if I have a paused timeline (at arbitrary time) is it right method to .invalidate() to keep the things at their initial positions? const totalTime = timeline.totalTime(); // .pause() at 0 to .invalidate() at "initial" values timeline.pause(0).invalidate().pause(totalTime);
    3 points
  40. There is no automatically, you're the developer so you need to implement it as you see fit. I would look in to the new gsap.matchMedia() function, seems like the perfect use case for it. https://youtu.be/9gipsKpWozE
    3 points
  41. Hi, You can definitely use GSAP and Bootstrap without any issue. GSAP is 100% agnostic in order to maximize compatibility with your preferred tools. For this you can set up your Bootstrap image grid using Flexbox and let the Flip plugin do the rest for you: https://greensock.com/docs/v3/Plugins/Flip This codepen example from the GreenSock collection shows how simple it is: https://codepen.io/GreenSock/pen/zYqLjre Happy Tweening!!!
    3 points
  42. Welcome! It's tough to diagnose without a minimal demo (like a CodePen), but I assume this is what you need: And yes, Carl's resources are fantastic. ๐Ÿ‘
    3 points
  43. Right, I see, you've copied my example and tried to adapt it to using SplitText. You are using an outdated syntax and are missing a few little bits. Have a look at the SplitText docs as well. You will see there is already a ton of functionality there. I recommend you also read the get started section in the site here so you can be familiar with the current GSAP syntax. Finally, below is your code refactored to achieve a pleasant animation. The key points there are: Add a class to each split letter, creating a "dictionary" of tweens, storing an "index" reference of the dictionary entry on each letter as a data-attribute and checking to see if the element hovered over has said dictionary reference and if the tween is playing new SplitText(".wtg", {charsClass: "letter"}); const element = document.querySelector('.wtg'); const letters = gsap.utils.toArray(".letter"); const tweens = {}; element.addEventListener('mouseover', onMouseOver); letters.forEach((letter, index) => { tweens[index] = gsap.to(letter, {yPercent: -50, yoyo:true, repeat:1, paused: true}); letter.dataset.tween = index; }) function onMouseOver(event) { const trg = event.target; if(trg.dataset.tween) { tween = tweens[trg.dataset.tween]; if (!gsap.isTweening(trg)) { tween.play(0); } } }
    3 points
  44. It was a bit! I thought I'd have a look around for any good podcasts now I plan on getting into GSAP, and came across Egghead dev chats from 2018! Old, but still good
    3 points
  45. Here's an idea for how you can approach this @Ficus Media Set up a ScrollTrigger that starts at the top of the page and ends the height of your headline/logo after that. Over that distance scrub a tween, transforming each of the letters upwards by a certain amount multiplied by a certain value you wish for its 'speed', stored in e.g. a data-speed attribute of each letter. I chose the height of the title itself in this demo as the 'base value' for the y transform and multiply it by that data-speed attribute of each letter - the higher the value you choose as your basis, the faster it will move up of course. Maybe this can get you started. If you have still have any questions, it would be best to create a new topic and add a minimal demo, that makes it easier to help. Happy tweening! https://codepen.io/akapowl/pen/abGOebz
    3 points
  46. Sorry it took a while to get there - I just got back from holiday so my brain's not really in gear yet.
    3 points
  47. Hey Ivan, I have forked your demo and changed a little bit. Please, check it. https://codepen.io/anastasiya33/pen/BaxNqxN?editors=0010
    3 points
  48. start here. https://mgearon.com/css/css-background-clip-text/ here is a stripped down demo i had showing the text shrink https://codepen.io/snorkltv/pen/NWMqzGW google "css clip mask text" for more. not really sure how to handle video. you may have to use canvas.
    3 points
  49. Hi and welcome to the GreenSock forums!! I believe you are on the right track with your approach. Just a few pointers. No need to add an onComplete or onUpdate callback in a timeline instance that is going to trigger a new GSAP instance, just replace the onComplete with another .to(), .from() or .fromTo() instance (depending on what you intend to do) after the instance, and replace the onUpdate with, again, a .to(), .from() or .fromTo() instance using the less than sign "<" as the position parameter and give it the same duration. I'm not sure if this code does what you're after: TL_items .to(".item-description-2", { opacity: 1, }) .to(".item-description-2", { autoAlpha: 0 }) .to(".item-2", { x: "23vw", //slide in from left - out of view into view }) .to(".item-1", { x: "55vw", // slide to the right of screen - but not out of view ease: "power2.out", }) .to(".item-description-1", { autoAlpha: 1 // fade in description when centre stage }) .to(".item-2", { x: "0vw", // slide to centre }) .to(".item-description-2", { autoAlpha: 1 // fade in description when centre stage }) .to(".item-1", { x: "0vw", // slide to the right of screen ease: "power2.out", }) .to(".item-description-1", { autoAlpha: 0 // fade out description when not centre stage }, "<") .to(".item-2", { x: "-43vw", // slide to centre }) .to(".item-description-2", { autoAlpha: 0 // fade out description when not centre stage }) .to(".item-3", { x: "-55vw", // slide in from out of view ease: "power2.out", }) .to(".item-description-3", { autoAlpha: 1 // fade in description when centre stage }) .to(".item-2", { x: "-75vw", // slide in from out of view ease: "power2.out" }) .to(".item-3", { x: "-75vw", // slide in from out of view ease: "power2.out", }) .to(".item-description-3", { autoAlpha: 1 // fade in description when centre stage }) .to(".item-3", { x: "-175vw", // slide in from out of view ease: "power2.out", }) .to(".item-description-3", { autoAlpha: 0 // fade out description when not centre stage }, "<-=0.25"); But as you can see is far simpler to follow than the usage of onComplete and onUpdate. Finally take a look at the docs for the GSAP Timeline's position parameter: And take a look at the documentation regarding easing as well, to ensure that you're using the correct syntax: https://greensock.com/docs/v3/Eases Happy Tweening!!!
    3 points
  50. That's because you forgot to define the targets. Remember, when you just feed in a state object, it'll use the targets that were captured in that state by default but in your example, those elements were completely removed from the DOM and there are entirely new ones that got rendered, hence the need to tell the Flip "use these new targets and search the state object for the IDs that match..." // BAD Flip.from(state, { duration: 1 }); // GOOD Flip.from(state, { targets: ".box", // <-- BINGO duration: 1 }); Does that clear things up?
    3 points
ร—