Jump to content

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

GreenSock last won the day on July 6

GreenSock had the most liked content!


  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by GreenSock

  1. Yeah, I wish we could see a reduced test case that would allow us to recreate the issue on our end. Without that, it's almost impossible for us to troubleshoot. Nobody else has reported any similar issues, and like you said it did work fine on CodePen so it must be something else in your setup. If you'd still like some help, feel free to post a reduced test case that'd let us reproduce the issue. Sorry to hear about the hassles. Happy tweening!
  2. Hm, I have a feeling I'm missing something obvious, @ashthornton, but I followed your instructions with the CodePen you provided and it seemed to work exactly as expected. Are you saying that it behaves totally differently for you if it's in a timeline vs. in a singular tween? Any tips on replicating that behavior?
  3. This is officially in 3.4.0 which is out now.
  4. Can you elaborate? I have a feeling I may be misunderstanding, but one of the main purposes of applying a ScrollTrigger to an animation is so that the ScrollTrigger would control the animation (play, pause, scrub, whatever). It automatically pauses it initially. So why would it matter if you also paused it first? Like...how exactly are you wanting it to behave in an ideal world? If ScrollTrigger sees that you pause the tween on the outside, you want it to refuse to play/restart/scrub/whatever? It'd need to "watch" the tween to sense when you call play() and then...take control in which case it may or may not actually play depending on the scroll position? If so, that seems pretty odd to me (to call play() on an animation and it refuses to play). Seems to work fine for me - am I missing something? let tween = gsap.to(".box", { x: 1000, scrollTrigger: { trigger: ".box-1", start: "top top", end: "+=500", scrub: true, pin: true } }); tween.scrollTrigger.disable(); // simulate a delay (like waiting for a loader to finish) gsap.delayedCall(2, () => tween.scrollTrigger.enable());
  5. You actually have to opt-in to the "toss" behavior, and you even need a bonus plugin to do it I'm not sure which version you're using, but just make sure that you DON'T have throwProps: true or inertia: true.
  6. Maybe this is a simpler way of explaining it... Let's say I've got a timeline that happens to have your suggested "keyframes: true" set. It's 10-seconds long. Then later, I do this: tl.add(otherTween, 5); // inserting it at exactly 5-seconds (halfway in) And then I do this: tl.time(5); // where's the playhead? At 5-seconds? What if the timeline has an ease applied? Would that start playing at the very start of otherTween? What if the timeline has a keyframesEase of "power3"? Would setting the time() to 5 actually make the playhead act like it's at 9.375? If so, isn't that kinda weird?
  7. All rendering is based on where the playhead is. There's various logic internally (and probably other people run external logic based on this too) that's based on this, like for example: function globalTime(animation, rawTime) { let time = rawTime || rawTime === 0 ? rawTime : animation.rawTime(); while (animation) { time = animation.startTime() + time / (animation.timeScale() || 1); animation = animation.parent; } return time; } That won't work if we decouple a timeline's playhead from its actual time. Of course I could introduce a new "ratio" value that serves this purpose sorta like it does in tweens, so I'm not saying it's impossible but it's definitely not a simple tweak. And if anyone else has logic baked into their code that assumes the playhead actually reflects the "time", it'd break that too. See what I mean?
  8. I see. I think it'd help if I saw more pseudo code - like a comparison between what it is now and what it would look like in the "improved" version. In the example you provided, @OSUblake, is the only difference that setting keyframes: true would force all of the child tweens to use an ease of "none" (identical to defaults: {ease: "none"}) AND the virtual playhead would move in a non-standard way that wouldn't conform to the current logic? In other words, if you set keyframesEase: "power3" on a timeline that has 4 one-second sequenced tweens (keyframes), and then you move the playhead to 2 seconds (halfway through, progress: 0.5), the child tweens would get rendered as if the playhead was at a time of 3.75 (progress: 0.9375)? If so, that could be rather problematic because suddenly a timeline's virtual playhead no longer corresponds to its position on its parent timeline, etc. It rips a hole in the time-space continuum Does the helper function I provided already address the desire to simplify things (without introducing the inconsistencies I mention above)? I'm not opposed to simplifying things for sure. In all my years doing this I haven't heard much of a complaint about the current API not making it easy enough to animate multiple things or create keyframe-like animations, but then again my memory is getting worse as I get older. And sometimes even though people haven't expressed a need for something, if we deliver it they may say "how did I ever live without this!" So again, I'm open to improvements, but I want to be very careful about not inadvertently introducing logic inconsistencies or bloating the file size for the sake of a very few people who'd use it (not saying only a few people would...I'm just saying that IF only a few people would, I don't like adding kb for something that's already totally doable with the current API).
  9. GreenSock

    smooth page scroll

    Check this out - just released today: https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.scrollerProxy()
  10. Are you saying that code doesn't work currently? I just tried it and it seems to work okay, so I must be missing something.
  11. I'm struggling to understand what you mean here. Can you provide an example (pseudo code)? Again, I'm probably missing something obvious but why do we need any of this? Doesn't the current API already make this possible? For example, here's a helper function that'd let you pass in an Array of keyframe objects: function keyframes(data, {defaults, ease}) { let tl = gsap.timeline({paused: true, defaults: defaults}), targets, tweenVars, p; data.forEach(keyframe => { targets = keyframe.targets || targets; tweenVars = {}; for (p in keyframe) { p !== "targets" && (tweenVars[p] = keyframe[p]); } tweenVars.ease = keyframe.ease || "none"; console.log("ease:", tweenVars.ease, tweenVars); tl.to(targets, tweenVars); }); return gsap.to(tl, {progress: 1, ease: ease || "none", duration: tl.duration()}); } // USAGE: keyframes([ {targets: ".box", y: 100}, {targets: ".box-1, .box-2", x: 100}, {targets: ".box-3", rotation: 360} ], { ease: "power3", // <-- ease applies to the whole timeline defaults: {duration: 2} }); You can skip defining "targets" in subsequent keyframes and it'll just use the same one as the previous keyframe. And you could define an ease for any individual keyframe. It's the same thing as a "vars" object for a typical tween, but it also has a "targets" property. Does that help at all? I guess I'm struggling to see the value of all this, especially since the existing API is easy to string things together like .to(...).to(...) with multiple targets. In other words, how is that any different than this keyframe stuff (other than a tiny bit of extra code that makes the default ease "none", wraps things in a timeline and animates the progress)?
  12. Sorry about the confusion there - the problem was that by default GSAP's core will automatically find function-based values and swap in the values accordingly. So it found your "render" value as a function, called it, and used the RESULT as the actual value to feed in to MorphSVGPlugin. I just had to set a flag on the plugin itself to prevent that. The latest version should have it resolved. Please give it a shot and let us know if it works well for you.
  13. Insider tip: If you want to go from the end, you can actually just use a NEGATIVE stagger value
  14. Hm, it sounds like maybe you forgot to gsap.registerPlugin(ScrollTrigger) or you did so when the window was undefined(?) Did you check to see if there were any warnings in the console? And what version of ScrollTrigger/GSAP were you using?
  15. Congratulations, @PointC! Very well done. You're a huge asset to this community. I'm so glad that years ago you worked up the courage to post for the first time...and that it was so rewarding. You've come a long way!
  16. I assume you meant "opacity", right? Perhaps you're from the Flash days when it was "alpha"?
  17. Ready to get your pixels movin'? Motion Tricks is home to web animation tutorials with an emphasis on real world projects powered by GSAP.
  18. I wasn't quite sure - are you saying that you got it solved now or do you still need help?
  19. Yes, like Zach said a demo is necessary for us to troubleshoot. The error message seems (to me at least) to indicate that the target of whatever you're doing with GSAP/ScrollTrigger is undefined/null. Probably the scroller (which is the window by default). I bet your code is executing before the window is defined or you forgot to gsap.registerPlugin(ScrollTrigger) after the window exists. Just a guess.