Jump to content

GreenSock last won the day on July 24 2019

GreenSock had the most liked content!


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by GreenSock

  1. Definitely avoid #2 because that'd keep appending tweens to a timeline, so they'd stack up and not get released for garbage collection (unless you set autoRemoveChildren to true). Your timeline would keep getting longer and longer. And depending on where the playhead of that timeline is when you append the tweens, they may not happen for a while (because they get added to the end of the timeline by default). All of those things could be controlled, of course, but my point is that it just seems kinda messy. Technically approach #3 is probably the most efficient. However, that bakes in all the tweens from the beginning which is great for performance but not so good if you need things to be dynamic. For example, let's take a simple scenario - you have three buttons that tween a box's color to red, blue, and green. All tweens are 1 second long. What if the user clicks red, then blue, then halfway through that tween they click green? If you dynamically create your animations on-the-fly with each click, it'll work beautifully because a to() tween grabs whatever the current value is and uses it for the "from" value. So if it's halfway between blue and red, and then they click green, it'll be totally smooth. But if you try pre-baking everything, that can't work. See what I mean? I noticed your tweens are all fromTo(), so you're forcing the "from" every time. That may be perfect, but beware that it'll cause a jump if the element is partially tweened when that one fires. Make sense? And again, if you're only putting one tween into a timeline, just use a tween instead. In other words: //NOT AS GOOD: function show1(){ return new TimelineLite().fromTo("div1", 1, {autoAlpha:0}, {autoAlpha:1}); } //BETTER: function show1(){ return TweenMax.fromTo("div1", 1, {autoAlpha:0}, {autoAlpha:1}); } Those tweens can still be added to a master timeline, of course, just like a TimelineLite could. No difference at all. Does that help?
  2. There are two issues I see: There's a space at the end of each word (otherwise, all the words would collapse) and the browser actually renders that space when everything is wrapped in inline-block <div>'s. When it's just plain/unwrapped text, the browser can be like "oh, I'll ignore that space on the end of the line when it wraps". The solution: tell SplitText to split based on lines too (so in your case, type:"chars,words,lines"). The other issue is purely a Safari thing regarding how it handles kerning. It's trying to be "helpful" by applying all that kerning when certain letters are next to each other, but of course that won't work if they're wrapped in <div>'s. As far as I know, it's simply impossible. And even when I set font-kerning:none, it didn't always solve things. Improved, yes, but I still noticed slight shifting with certain characters. I have researched that and I cannot find any way to tell Safari to knock it off. Sorry
  3. Sorry, that's not something we really support. I'm not a React guy, and the "react-gsap" project isn't in any way associated with GreenSock (apparently they're using our code, but we didn't author that project). Perhaps you could ask the author? It looks like there are some errors being thrown in the console regarding exports not being defined. Perhaps it's a configuration issue(?) If you have any GSAP-related questions, we'd be happy to help.
  4. Yep, nesting a bunch of timelines is totally fine. I doubt you'd ever notice a performance hit. If your child timeline only contains one tween, though, I'd say there's no point in wrapping it in a timeline. Only use timelines when you've got groups of tweens that you want to control or nest.
  5. I think unpkg.com does stuff like that. So, for example: https://unpkg.com/react-gsap@1.2.0/dist/index.js (It's not minified, though).
  6. You can TweenMax.killTweensOf("#yourSelector") to kill all the tweens of a particular object. Also keep in mind that GSAP internally records information about which animations go with which element so that it can perform lookups super fast, and it only dumps those references about once every 2 seconds or so. If you're doing your recording without waiting for that amount of time, it'd make sense why it would look like references are being held...but just wait a little longer and I bet you'll see that they're freed up (unless you have references in your own code). You can control the interval between the auto-sleep checks with TweenLite.autoSleep = 120; (or whatever - this is the number of ticks between checks).
  7. Yep, but if you need to call more than one function, you could just nest them. animation.eventCallback("onUpdate", function() { yourFunc1(); yourFunc2(); });
  8. GreenSock


    Yep, I'd do it the way @PointC suggested. As far as sensing if/when it goes beyond the edge of the browser, there is a hitTest() method that MIGHT be useful. https://greensock.com/docs/Utilities/Draggable/static.hitTest() Like...you could use the threshold of "100%" so that if any part of it goes outside the document, you know. For example, in your onDrag it could look like: onDrag:function() { if (!this.hitTest(document.documentElement, "100%")) { //or you could probably use "body" as a selector. console.log("hit the edge!") } } But you could also go the "pure" route of using getBoundingClientRect() and compare it to the window's size to sense when it hits the edge. And like @PointC said, you'd need to figure out the logic for scaling it in whatever way you want, based on the location. That doesn't sound trivial to me, but I'm sure it's doable. Good luck!
  9. Correct, we don't have plans to do that at this point but it shouldn't be terribly difficult to take the UMD version and make it into an ES module. You've been "Shockingly Green" since 2017, which we sure appreciate, so let me know if you'd like me to convert that for you and I can send it to you privately.
  10. Yeah, there isn't an ES Module file for that plugin, nor is it exported from "gsap/all". That's probably the cause of the problem. But the way you're loading it is perfectly acceptable, plus you benefit from wider caching
  11. Sorry about any confusion there - Raphael is quite old and doesn't appear to have been maintained for quite a few years (2016), so we phased that plugin out. I just checked, though, and it looks like there was a bug-fix release last March, but it doesn't really seem like it's something that many people use these days. I could be wrong. I'm curious - what are you using Raphael for these days?
  12. Hey @ZachSaucier! Nice to see you around the neighborhood again. Sorry about my tardy response, but I think I got the Flu today and it completely wiped me out. Anyway, I might be misunderstanding your description of the problem, but from what I can tell it's working as I'd expect. You set it up to drag-scroll .scroll-container, but that doesn't have any scrolling at all. What you're seeing is the main page's (<body>) scroll bar. So dragging on .scroll-container shouldn't actually scroll the page. See what I mean? That's also why it worked if you set a height that's smaller than its natural height (thus, making it scrollable). Pardon my foggy brain, though, if I missed something obvious in my Flu-induced stupor.
  13. Ha! Thats great, @PointC! Congrats. Love the demo.
  14. That's pretty strange indeed - have you asked the Angular folks? This doesn't seem like a GSAP issue. Try adding your gsapStuff as a property of your actual class. I wonder if maybe it sees that gsapStuff is never referenced anywhere, so it dumps it (tree shaking). Just a guess.
  15. Welcome to the forums, @AslanGoi. Don't worry about being a beginner - everyone is welcome here. It might help if you tried to strip things down to just the bare essentials and start building up from there because there are a bunch of problems I see with the codepen you provided and I'm worried it'll be overwhelming to understand them all. You were adding new "click" event listeners inside of an onComplete...which is inside of a staggerFromTo(), so that means that if you have 4 slides it'll add 2 new listeners every...single...time any of those animations complete. That'll cause a lot of problems as things keep stacking on top of each other. Your methods will get called a crazy number of times. You have 4 slides, and your "lastSlide" is set to the total number of slides...but arrays are zero-based, so slides[4] doesn't exist. The last slide would have an index of 3. This is what's causing your "cannot tween a null target" error - you're animating slides[lastSlide] (which is undefined). There was a bunch of odd logic in those prevSlide() and nextSlide() methods that seemed like it might be overcomplicating things but I don't have time at the moment to pull it all apart and try to rebuild something. Hopefully the previous few pointers help move you to a better place, though. Happy tweening!
  16. Ah yes, perhaps I misunderstood the question. The stroke-linecap:square would definitely cause it to be visible even when the line technically has no width. Good call, @mikel
  17. This looks like an immediateRender logic thing. By default, immediateRender is true for from() and fromTo() methods. See https://greensock.com/immediateRender Try just adding immediateRender:false to your second tween of each element: const tl = new TimelineMax({repeat: -1}); tl.fromTo(".line1", 1, {drawSVG: "50% 50%"}, {drawSVG: "100%"}); tl.fromTo(".line1", 1, {drawSVG: "100%"}, {drawSVG: "50% 50%", immediateRender:false}); tl.fromTo(".line2", 1, {drawSVG: "50% 50%"}, {drawSVG: "100%"}); tl.fromTo(".line2", 1, {drawSVG: "100%"}, {drawSVG: "50% 50%", immediateRender:false}); Or, if you want to simplify your code, you could do this: TweenMax.set(".line1, .line2", {drawSVG:"50% 50%"}); const tl = new TimelineMax({repeat: -1}); tl.to(".line1", 1, {drawSVG: "100%", yoyo:true, repeat:1}) .to(".line2", 1, {drawSVG: "100%", yoyo:true, repeat:1}); Does that help?
  18. Yeah, CSS doesn't work very well cross-browser on SVGs, especially with transform-related values. That's why we strongly recommend setting values directly through GSAP instead, because it works around various browser inconsistencies/bugs. Glad you got it working. Happy tweening!
  19. Yeah, I guess I'm struggling to see the problem. As far as I can tell, it's behaving as expected. If you want to animate from the element's center, you could just add transformOrigin:"50% 50%" to your tween. Worked great for me. Otherwise, the default origin for SVG elements is always the top left. Maybe I'm missing something?
  20. Welcome to the forums, @Bobby Ballard. And thanks for being a Club GreenSock member! GSAP is super flexible - I wouldn't say there are any rules but typically it's wise to load the GreenSock files at the end of your <body> tag, and make sure you run your actual code after that too so the DOM is fully loaded and elements can be accessed. Other than that, just have fun!
  21. Nah, you shouldn't have to disable your build optimizer. Did you try referencing CSSPlugin, TweenMax, and TimelineLite somewhere in your code?
  22. I'm not familiar with Animate CC, sorry. Maybe ask in the Adobe forums?
  23. Welcome to the forums, @gargara1. It looks like there must be something off in the way you're calculating things, but there's too much going on here for me to dissect at the moment. I'd strongly recommend creating the most reduced case possible (literally, like one box that animates to the center...no other assets at all) to isolate things and post that here. A codepen is best. This doesn't really seem like a GSAP-related question, but if we can help we'll try (once you've got a more reduced test case). FYI, it looks like there are errors being thrown regarding nominalBounds.
  24. TweenMax includes TweenLite Are you waiting at least 120 ticks (about 2 seconds) before you're doing your measurements? It's super difficult to troubleshoot blind. I wish I had more to offer.