Jump to content
Search Community

Leaderboard

Popular Content

Showing content with the highest reputation on 02/22/2024 in all areas

  1. Hi @Mumm-Ra. Thanks for the suggestion - are you basically asking us to make GSDevTools "frame-based" instead of "time-based"? The problem with that is GSAP is inherently resolution-independent in terms of timing, and that's a GOOD thing. In the old days, a lot of systems were frame-based, so for example you might make an animation that linearly travels 600px between frame 10 and frame 70, so 10px per frame. Seems fine initially, but what if you run that animation at a timeScale of 0.25 (quarter-speed)? Since that animation was frame-based, it's resolution-dependent, meaning it only has 60 frames worth of motion and if we now slow the playback speed, it looks a lot more jerky. GSAP, on the other hand, is resolution-independent in terms of time, so if you timeScale(0.25), it'll adjust perfectly and the motion will be totally smooth. It's not locked to moving 10px per frame like in the frames-based animation. And remember that even if requestAnimationFrame() is supposed to run 60 times per second, sometimes it doesn't. The system could be temporarily bogged down. In a frames-based system, that would mean the entire animation would take longer to finish. For example, if the system was working really hard and the frame rate dropped to 30fps, that 60-frame animation would take 2 full seconds to complete! But with GSAP, it'd still honor the 1-second duration; it'd just move a longer distance on each frame. All that to say that I do not believe it would be a good idea to make GSDevTools frame-based. It may give the false impression that GSAP works that way. A developer might intricately build out an animation such that a particular element starts moving in exactly frame 62...but then in the real-world browser on a system that's much less powerful, it may actually end up firing on tick 41 instead because the frame rate dropped. Why do you need things to be frame-based? What is difficult for you about using time (seconds)?
    3 points
  2. something like? i created a setInterval and it fires every 2s you can play with the duration and ease to get the effect you want https://codepen.io/ahmed-attia/pen/KKELGWz?editors=0010
    3 points
  3. No worries, that is what the forum is for! Happy to help. But yeah there is just so much already thought of for you in GSAP, it really pays to grap your favourite beverage on a rainy day and just start reading some of the documentation. You'll be surprised what tools you'll find that you didn't know you needed. Again welcome and happy tweening!
    2 points
  4. Hi @ohiosveryown welcome to the forum! Would setting the snap of x to 6 solve your issue? Some more info on the docs if you're interested https://gsap.com/docs/v3/GSAP/CorePlugins/Snap?_highlight=snap https://codepen.io/mvaneijgen/pen/abMrREY?editors=0010
    2 points
  5. You have to make sure that everything you want to pin is inside a container that you use as the pin container. Then all your code works as expected. (I've also set clamp() around your start, so that it only starts when the visitor starts scrolling. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/GReaQNL
    2 points
  6. Thank you @Cassie. I'm a MGFX video guru (After Effects) first and a coder (distant) last-place. I had something of an existential crisis momentarily upon realizing that viewBox acts as a virtual camera while viewPort acts as the wildly varying screen size... not because it isn't awesome, THAT it truly is... however, it was because I wrote my entire app as though that did not exist. The chart and whatever plots are generated to match viewPort size. I really appreciate you and @Rodrigo causing me to realize that the <g> is inheriting from ` M ` command in the path, and that was where I was really unaware. Perhaps I was most confused because developing locally on Laravel's Herd, everything worked as I expected. But immediately on uploading to a remote server, the offset appeared. I don't have time to figure out what the heck that was all about, but I'm thanking God for you two. My mild existential crisis bore some fruit too. I added viewBox which eliminated the need for window resize calculations and re-drawing, then added a few lines to my code that created a virtual camera so that I can focus a user's attention somewhere more like a videographer would than a coder would. I found an SVG editor on github and used it to re-craft my svg so that the origin 0,0 is at the fingertip. Learned a lot about SVG today! What do you guys use to create SVG's? I was hoping Illustrator would be more useful to me... but seems to not be the right tool. Thoughts? Up and running as expected now, thanks to your help. Cheers!
    2 points
  7. Hi @Gravitas welcome to the forum and thanks for being a club member! I've installed the ScrollTo plugin and add some labels to your timeline and then we can use .labelToScroll() ( https://gsap.com/docs/v3/Plugins/ScrollTrigger/labelToScroll()/) to tell it to scroll to that point in the timeline, you of course want to tweak the timings a bit, but hope this illustrates a solution. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/KKELYqY?editors=0011
    1 point
  8. Hi, The issue is that you're pinning an element that is not the outmost element in the DOM, you have to pin the <div> tag that wraps everything in your component: <div> <section className="scroll-section-outer"> <div ref={triggerRef}> <!-- YOU'RE PINNING THIS --> </div> </section> </div> If you pin the outmost element in the HTML there it works as expected: https://stackblitz.com/edit/stackblitz-starters-hyyftg?file=src%2FApp.js Hopefully this helps. Happy Tweening!
    1 point
  9. Ah! This is great to hear. Glad it helped a little. So, i use either affinity, boxy or illustrator - personally illustrator's my fave but that's down to years of muscle memory. I usually recommend boxy to people for light tweaking and affinity as a cheaper illustrator alternative. What issues were you having with illustrator? (The top left corner of your artboard is [0,0] so usually I just use that as a rough starting point) A v helpful hack is to use relative paths too, relative paths draw each point relative to the first M command. That means you can change the x and y of the M command to anything and the rest of the path will move along with it. Easy hand-editing for SVG path positions! 🥳 Most editors spit out a mix of absolute and relative path points, so if you try to change the M command you just distort the path 🫠 Affinity allows you to choose relative paths as an export setting which is great. Failing that - this is a helpful tool for adjusting your paths here. https://lea.verou.me/blog/2019/05/utility-convert-svg-path-to-all-relative-or-all-absolute-commands/ Good luck with it all!
    1 point
  10. If you want things to have the blur on page load, yes. Right now the animation only triggers if the green and red markers touch. Another way of going about it would be to blur everything on page load and change animation to un-blur something if ScrollTrigger onEnter fires. But that is up to you and what is the best fit for your project. Hope it helps and happy tweening!
    1 point
  11. h1 @DW92 maybe something like 🤔 this one without any functions https://codepen.io/ahmed-attia/pen/PoLvaKM?editors=1010 in your demo, you didn't load gsap so this code won't work in a million years 😂 here is how you load gsap or just fork this demo it contains all the plugins https://codepen.io/GreenSock/pen/OPqpRJ
    1 point
  12. Actually I've found what the issue seems to be. Previously I implemented a ScrollTrigger.refresh() for lazy loaded images. I believe as the project card images were loading (on horizontal scroll) it was calling this and thus causing a slight jump briefly, I've just disabled this refresh only on these images and it seems to have fixed it. Please mark this as resolved.
    1 point
  13. Yeah, a minimal demo would be super duper helpful. But this sounds like a great case for gsap.matchMedia()! https://gsap.com/docs/v3/GSAP/gsap.matchMedia() And since you're using React, definitely check out https://gsap.com/react
    1 point
  14. Working backwards from this question you can add all the code you want to happen in the onComplete callback, right now you just add a class, but your can do what ever you like here. This is sometimes called async, defer, lazy loading and this is not a simple task and can become really technical really fast, this is usually something the tool with which you build your website helps with and not something GSAP can do for you Yeah the tool with which you set this up could give you a value and you then could feed that to the progress value. Instead of window.onload .play you would then call .onWhatEverIsUpdatingTheLoading .progress(valueYouGetFromThatTool) Just set transformOrigin: "center center", then it grows from the center Hope it helps and happy tweening!
    1 point
  15. You had a typo: // bad start: 'bottm bottom' // good start: 'bottom bottom' You also were loading the GSAP/ScrollTrigger/React files from the CDN as UMD files **AND** importing them as ES Modules which you definitely shouldn't do. That's a bunch of redundancies. You also were defining "class" attributes in JSX which is invalid - you've gotta use className. That has nothing to do with GSAP; it's a React thing. And you can round the values with snap: https://codepen.io/GreenSock/pen/abMryMW?editors=0010 Does that help?
    1 point
  16. Hi @jklue and welcome to the GSAP Forums! Thanks for being a GSAP Club member and supporting GSAP! 💚 I think this demo does what you're looking for: https://codepen.io/GreenSock/pen/qBawMGb Hopefully this helps. Happy Tweening!
    1 point
  17. That's totally possible, but it's a bit beyond the scope of help we can provide in these free forums. The basic approach I'd personally take is to get the seamless looper helper function to create the timeline, pause it, and then create a baseline variable like "velocity" representing the speed of the playhead. Then, in a tick event handler (gsap.ticker.add(() => {...})) I'd update the timeline's playhead accordingly so that it moves at a normal pace (whatever you decide that to be). Then use an Observer to listen for scroll, pointer, and touch events such that it alters the velocity according to the deltaX/deltaY, and tween that value back to the baseline with a gsap.quickTo() so that it decelerates. So your velocity variable goes up and down based on the various events/interactions, but always goes back to the baseline. Good luck! We do offer paid consulting services if you need more assistance. You're welcome to post in the Jobs & Freelance forum too.
    1 point
  18. Do you have minimal demo we could take a look at? This feels like a scoping issue. I don't use jQuery so this is pseudo code. GSAP has a helper utility to scope the query selecting of an element only to an specific element https://gsap.com/docs/v3/GSAP/UtilityMethods/selector() so below some code that would get ..bc-projects__heading inside the current loop of .bc-middle-main__heading. But we could explain this a lot better if you could post a minimal demo in which we could modify the code. Hope it helps and happy tweening! // const projectTitle = document.getElementById('bc-projects__heading'); // There should only be one ID on a page. $(".bc-middle-main__heading").each(function() { let q = gsap.utils.selector(this); const newerText = new function(q('.bc-projects__heading')), { // Get elment insite current .bc-projects__heading timeOffset: 25, callback: () => { console.log('working') } }); function starterFx() { newerText.start(); console.log('stillworking') } ScrollTrigger.create({ trigger: $(this), onEnter: starterFx, }) }); https://codepen.io/GreenSock/pen/aYYOdN
    1 point
  19. Yep, I've learned a few tricks with smart SVG folks like you, @PointC, @OSUblake and @Carl around, that make me look competent enough 😂
    1 point
  20. Ohh I see @Cassie is working some SVG magic here ✨, so probably you should pay more attention to Her answer 😃
    1 point
  21. Great to hear you've solved your issue. Give it time, this was me 10 years ago. Wouldn't have it any other way now, combining the design with the development skills is amazing, you'll find that one day you can build what ever you design! Good luck with the project and happy tweening!
    1 point
  22. hi @lizettevanboom I moved the styling for the div-2 inside the CSS to collect it all in one place also i used 1 scrolltrigger to pin div-1 with pinSpacing false and another trigger for the div-2 to animate it , ofc @mvaneijgen solution is more professional and organized 🫡 but I wanted to give another quick lazy solution https://codepen.io/ahmed-attia/pen/oNVOrxN?editors=0110
    1 point
  23. Hi @lizettevanboom That is where timelines come in! Personally I find the best thing to do when working with ScrollTrigger is to remove it! This seems counter intuitive, but ScrollTrigger is just animating something on scroll, so just focus on the animation at first and only when you're happy with the animation add ScrollTrigger back in. This way you can focus on one part at a time and it will save a lot of headache when debugging. So here is your demo with ScrollTrigger disabled for now, so that we can just focus on the animation. I like to add empty tweens to a timeline when working with ScrollTrigger that just do nothing for x amount of seconds. Here it does nothing for 1 second and your animation tween also has a duration of 1 second. Normally in GSAP things work with durations, but when working with ScrollTriggers with a scrub value these durations get converted to distance. It might be hard to wrap your head around, but maybe this example helps. Let's say we have four tweens that all take 1 second to animate and the total ScrollTrigger distance is 400px each tween will then take up 100px. If we remove one tween and make the last tween take 2 seconds the first two tweens will take still 100px, but the last tween will get stretched over the remaining 200px. I’ve placed some comments in your JS to better explain things, please be sure to read through them! Als je nog vragen hebt horen wij het graag en hoop dat het help! Happy tweening! https://codepen.io/mvaneijgen/pen/XWGQLrx?editors=0011
    1 point
  24. Nice. That worked a treat. As you added that I also found another post here that demo'd a great way to calc vh/vw to then use as variables: const vh = (coef) => window.innerHeight * (coef/100); const vw = (coef) => window.innerWidth * (coef/100); Which can be used like: ScrollTrigger.create({ trigger: '.my_elem', start: vw(10) + ' top', end: vw(10) + ' top', onEnter: enterFunc, onLeaveBack: leaveFunc }); Thanks for the pointer
    1 point
  25. Mhh... Ok this is a bit different from the original question. I thought this was about just controlling a timeline in different components, but this is a different territory. Yeah this situations can be a pain in the neck actually because, while is ideal to keep components as small/simple as possible, some times we run into this issues where we need a specific DOM element in a grand parent component with the purpose of creating an animation or doing something else. In this case I wouldn't use the context API at all for such purpose and try to tailor a solution for your specific scenario. If your component tree has three levels (as you mentioned in your first post): I'll assume that the entire timeline is being created and started in the Layout or Header component. What I would do is to use a method in the Layout component in order to access the DOM elements and add them to the timeline, and Forwarding Refs in Component1 to get the refs from Component2, because (as you already found out ) sharing things between sibling components can be a bit tricky. In the layout component it would look a bit like this: import { useRef } from "react"; import Header from "./components/Header"; import Component1 from "./components/Component1"; const Layout = () => { const getChildTweens (tween) => { // In here run some code to add the GSAP instances // in the main timeline }; return (<div> <Header getChildTweens={getChildTweens} /> <Component1 getChildTweens={getChildTweens} /> </div>); }; In the header component import { useRef, useEffect } from "react"; import gsap from "gsap"; const Header = ({ getChildTweens }) => { const headerTween = useRef(null); useEffect(() => { headerTween.current = gsap.to(/* Header Animation */); // You can add other parameters to include labels, etc. // Now you sent the header tween to the layout component getChildTweens(headerTween.current); }, []); return(/* JSX in here */); }; In Component 1: import { useRef, useEffect } from "react"; import Component2 from "./Component2"; import Component3 from "./Component3"; const Component1 = ({ getChildTweens }) => { const component3Tween = useRef(null); const component3Ref = useRef(null); useEffect(() => { component3Tween.current = gsap.to(/* Header Animation */); // You can add other parameters to include labels, etc. // Now you sent the header tween to the layout component getChildTweens(component3Tween.current); }, []); return(<div> <Component2 /> <Component3 ref={component3Ref} /> </div>); }; Finally in Component 3 import React, { forwardRef } from "react"; const Component3 = forwardRef( ({ ref }) => { return( // Here you use the ref passed from the parent component // where you need it <div ref={ref}></div> ); }); That is actually the 100% React Way of doing this and is not exactly super simple and easy to follow, but not all that complicated Another alternative would be to use redux (or a custom store object) to store references to each GSAP instance and access them in the layout component in order to create the main timeline in the layout component and run it there. To be completely honest I've never tried something like that, but it should work. Happy Tweening!!!
    1 point
  26. Hey Jeff. You should be able to have SplitText wait until your fonts are loaded by using document.fonts.ready.then(function () { // Your code here }); Keep in mind that the above won't work in IE due to browser support.
    1 point
  27. Diaco's demo was missing something... You Spin me Round Hint: turn on your speakers http://codepen.io/osublake/pen/epLjrG/
    1 point
×
×
  • Create New...