Jump to content


  • Posts

  • Joined

  • Last visited

About Jure

Profile Information

  • Gender
    Not Telling

Recent Profile Visitors

1,889 profile views

Jure's Achievements

  1. Yes, what I meant by my first sentence is that I still left the scripts on top of the HTML (due to CMS being used) but switching the order (ScrollTrigger first, gsap second) solved my problem. I just meant this might be worth fixing for people who have this running in production and link to latest CDN and might not see this thread.
  2. Thanks for the suggestion to put ScrollTrigger *before* gsap while loading scripts, that helped solve my problem. The solution to put scripts at the bottom of HTML isn't practical for a CMS where it's not known in advance which blocks and when will need gsap functionality so I need to load and register things on top - also if people just link to CDN (without hardcoding a version) and their scripts are on top, this will still be an issue I think.
  3. I've prepared a minimal example with "save as HTML" and some JS files in a subfolder. If I drag this html directly into the browser (`file:///C:/breaks-demo-minimal/breaks.html`), I still get the same error reported. breaks-demo-minimal.zip
  4. I simply updated my old scripts (3.9.1) to the new version like this: <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.1/gsap.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.1/ScrollTrigger.js"></script> <script>gsap.registerPlugin(ScrollTrigger);</script> But I get this error in the console (Chrome 100) every time, with 3.10.0 and 3.10.1. I used the non-minified version to get a clearer error, but the same happens with the minified version. I'm running on localhost (http). I also tried downloading the js files and loading them from disk, same error. When I try to load the same scripts in Codepen, I don't get the error. ScrollTrigger.js:205 Uncaught TypeError: Cannot use 'in' operator to search for 'onpointerenter' in null at Function._initCore [as register] (ScrollTrigger.js:205:39) at _createPlugin (gsap.js:987:31) at gsap.js:3517:16 at Array.forEach (<anonymous>) at Object.registerPlugin (gsap.js:3516:12) at ScrollTrigger.js:599:22 at ScrollTrigger.js:4:29 at ScrollTrigger.js:5:2 _initCore @ ScrollTrigger.js:205 _createPlugin @ gsap.js:987 (anonymous) @ gsap.js:3517 registerPlugin @ gsap.js:3516 (anonymous) @ ScrollTrigger.js:599 (anonymous) @ ScrollTrigger.js:4 (anonymous) @ ScrollTrigger.js:5 parallax-tester:67 Uncaught ReferenceError: ScrollTrigger is not defined at parallax-tester:67:29 If I click through to the error, this is the line in ScrollTrigger causing it. As soon as I change the version to 3.9.1 everything works again. Any ideas what could be causing this? Thanks.
  5. Yes, this all makes absolute sense, thanks so much for the in-depth explanation! I know that I can't count on the user waiting there without interrupting the animation, I was just curious how it would work and you've really cleared up how immediateRender works on competing ScrollTriggers. Just as reference for other people reading this - I remember watching a tutorial on how to block the user from scrolling before the initial animation has run on Creative Coding Club - https://www.creativecodingclub.com/courses/take/scrolltrigger-express/texts/15589254-prevent-scroll-on-fullscreen-intro This approach hides all content below the initial header (so there's nothing to scroll and use ScrollTrigger) and then enabling the content after the first timeline has finished (onComplete). (not sure if that tutorial is subscription only, but I can vouch the subscription is 100% worth it)
  6. Hi Blake, thanks so much - I can solve it by adding more wrapper elements. Just curious - I understand that both timelines compete for animating the same elements, but the first timeline (intro) has had enough time to fully complete before I start animating (by scrolling) the second timeline - so I don't understand why the second timeline would not just pick up where the current DOM state is. Is there some GSAP caching involved? Is there a standard approach for solving this without using wrapper elements? Perhaps to run the first (intro) timeline first, then enable the ScrollTrigger (or second timeline) via a callback? If this is too complex, I can let it go and just use wrapper elements.
  7. I'm building a full height header where I first animate some text in and then fade it out using ScrollTrigger. gsap.registerPlugin(ScrollTrigger); // let intro = gsap.timeline(); // intro // .from(".t1", {lazy: false, y: "-3vh", opacity: 0, duration: 0.6}) // .from(".t2", {lazy: false, y: "-2.5vh", opacity: 0, duration: 0.6}, 0.3) // .from(".t3", {lazy: false, y: "-2vh", opacity: 0, duration: 0.6}, 0.6); let outro = gsap.timeline({ scrollTrigger: { trigger: ".hero", start: "top top", scrub: 0.3, pin: true, markers: true, } }); outro .to(".t1", {lazy: false, y:"-50vh", scale: 0.96, opacity: 0, duration: 0.3}) .to(".t2", {lazy: false, y:"-49vh", scale: 0.95, opacity: 0, duration: 0.3}, 0) .to(".t3", {lazy: false, y:"-48vh", scale: 0.94, opacity: 0, duration: 0.3}, 0); If I disable the first timeline (intro), the second one (outro) works fine. If I have both timelines enabled, the second timeline text just jumps to opacity 0 immediately. I've build a Codepen example showing the problem exactly. Thanks for any tips on what I'm doing wrong.
  8. These are great examples for what I need, thanks.
  9. The transform values are very useful, thanks. The type of animations I'm using in UI are just general "slide-and-fade-in", "shake", "do a few things on rollover" - things that make it easier to direct the user's attention. I use forced transformations to make sure animations reset properly. Right now I'm thinking about using regular TweenLite calls like this: TweenLite.to(element, 2, { translateY: [20, 0], visibility: "visible", delay: 1, onComplete: someCallback }); TweenLite.to(element, 2, { translateY: -20, visibility: "hidden", delay: 1, onComplete: someCallback }); ... to fade in and slide in an element from the top. I'm wondering about best practices because this might be better achieved with a stored TimelineLite (animations might get more involved and have steps - shake for example) or maybe I can just use reverse instead of the second call?
  10. Thanks for the suggestions - OSUblake, your "playEffect" function is similar to what I was looking for, I was just wondering is this kind of functionality is already built in without the need to create my own processing function. Might be an idea for the future to include this in GSAP. To answer your question about value - such an approach is very practical when building a lot of small UI animations that need to be hand-tweaked at first but then reused. TimelineLite seems a bit overkill for this, but it's a valid approach too. What about the second part of my question - is there a best practice for "fade in and slide from top" type animations - in a way that doesn't permanently change the element's position and can be stopped/called during another animation without issues? Thanks!
  11. Thank you for the links, Diaco, but I didn't find the answer to my question. I think this is the closest: http://greensock.com/forums/topic/12040-replace-target-in-animation-instance/#entry49402 var referenceTween = TweenLite.to("#mydiv1", 1, {x:100, opacity:0.5, rotation:600}) function anim(elem, tween){ return TweenLite.to(elem, tween.duration(), tween.vars) }; var tween1 = anim('#mydiv2', referenceTween); var tween1 = anim('#mydiv3', referenceTween); But here you need to create an initial tween for the others to be able to copy its animation. I would like to create simple abstract animations that can be applied to any object anywhere. Similar to creating a class in OOP - I don't want to start with an instance. Is that possible with TweenLite?
  12. Is there a way to create reusable animations in GSAP similar to what Velocity.js does in the UI pack? This is a quick code example of how it works there: First, you set up a custom animation template: $.Velocity.RegisterEffect("callout.pulse", { defaultDuration: 900, calls: [ [ { scaleX: 1.1 }, 0.50 ], [ { scaleX: 1 }, 0.50 ] ] }); And then you use it in a simple call: $element.velocity("callout.pulse"); I'm trying to make some UI animations and keep them as DRY as possible. I have a couple of elements that start with visibility: "hidden" (I need them to keep position and not collapse on hiding) and I want to fade them in + slide them in/out from up/down (and use a type-in effect for others - I'll try the SplitText plugin for that). Since I'm using these calls from various sources I need them to always remember their original position even if the animation should be interrupted by quick switching of views. I cannot animate anything that would affect the document flow (margin, padding etc.) but I'm fine with "translateY". If I use "+=20px" type animations it's hard to keep track of position. Is there a best practice for such simple UI animations in GSAP? Thanks.