Jump to content
Search Community

GreenSock last won the day on April 21

GreenSock had the most liked content!

GreenSock

Administrators
  • Posts

    23,151
  • Joined

  • Last visited

  • Days Won

    817

Everything posted by GreenSock

  1. Hi Martin. Sorry to hear about the challenges. Like Jonathan said, Adobe Animate only uses canvas which is kinda like a big blob of pixels to the browser, so it's a completely different beast than "regular" text in the browser. SplitText is made for typical text in the browser. If you purchased your Club GreenSock membership solely for SplitText (thinking it could be used in canvas text), we'd be happy to issue a full refund. We're passionate about having happy customers around here. Just shoot me a request if you'd like to cancel your membership and get a refund. No problem at all. Happy tweening!
  2. @kateriouis, did you see the video posted above? CustomEase is in JS We haven't done the broad announcement/release yet, but it's coming. Club members already have access to it.
  3. Yeah, that's probably the best way of doing it (loading as external files right into your HTML). I'm a little confused about why you'd need to instantiate a DrawSVGPlugin object or something. It's just a plugin that adds functionality to the core GSAP files. So you simply load it and BOOM, you can now define drawSVG:{} stuff in your tweens. See what I mean? It's not like you need to somehow have an import statement at the top and call DrawSVGPlugin itself. Can you just omit that stuff? Does ESLint really not allow you to load an external resource without yelling at you? Seems odd.
  4. It's a little more tricky when you've gotta loop back to the beginning and have the end and start transition seamlessly, but it's totally doable. Here's one approach: var images = $('img'), showDuration = 2, transitionDuration = 0.5, timeline = new TimelineMax({repeat:-1}); //set everything to invisible initially except the first one TweenLite.set(images, {autoAlpha:0}); TweenLite.set(images[0], {autoAlpha:1}); //now loop through the images and transition each one (and once the top one has faded in, set the bottom one back to invisible to improve performance) for (var i = 1; i < images.length; i++) { timeline.to(images[i], transitionDuration, {autoAlpha:1}, (showDuration + transitionDuration) * i - transitionDuration); timeline.to(images[i-1], 0.01, {autoAlpha:0}, (showDuration + transitionDuration) * i); } timeline.add("end", "+=" + showDuration); timeline.set(images[0], {autoAlpha:1}, "end"); //the first image should be fully opaque/visible so that when we fade the last image out, the first one is revealed. timeline.to(images[images.length-1], transitionDuration, {autoAlpha:0}, "end"); Is that what you're looking for?
  5. Hm, I just tried it on two iOS devices and it seemed to work fine (both iOS 10). I couldn't detect any problems at all. Any particular instructions for how to reproduce the problem?
  6. Yep, most browsers don't GPU-accelerate SVG, probably because of the resolution-independent nature of it (meaning pixels aren't locked-in; they can be fabricated based on many factors). If you're going to have a bunch of animations happening simultaneously and many pixels changing on each tick, I suspect you'll get better performance with canvas (especially a library like PixiJS since it can leverage WebGL). Yes, it is indeed more complex and can be trickier to make "responsive" size-wise and it's harder to debug/inspect, but if performance is your primary concern I'd be willing to bet you'll see better frame rates with canvas/PixiJS. Then again, SVG is getting better all the time and I'm obviously a big fan. Many projects don't really require the extreme performance that a canvas solution delivers. SVG is perfectly adequate (in fact, better in my opinion) if you're not being aggressive animation-wise. Happy tweening!
  7. Sorry to hear about the trouble. Hm. It's kinda tough to troubleshoot blind - is there any way you could could zip up your whole working directory and post it here or something? It'd just be really helpful to be able to recreate exactly the issues you're running into so we can poke around a bit. Have you tried creating an alias for each GSAP class you need? (Not that you should NEED to, but just curious). (Note: to attach a file to a post here, make sure you zip it first and click the "more reply options" button below)
  8. First of all, thanks for providing an excellent reduced test case! I wish all questions were accompanied by those. It makes it so much faster to troubleshoot. The reason this is happening is that Draggable automatically turns on velocity-tracking for x/y properties (if you have ThrowPropsPlugin loaded). That's what allows it to so naturally respond to flicks/drags; when you release, it can instantly calculate the velocity based on the previous recordings (it's constantly tracking for the last few ticks and averaging those numbers, as that provides the most accurate, natural results). In your example, you set the velocity for both x and y to "auto" which basically means "I have turned on tracking, so grab the current velocity from there". But remember, you're doing that tween immediately after having set the x value all the way back from 100 to 0 which means it's got a pretty high velocity backwards! Therefore, it's taking that into account, and going backward a bit before moving forward again. It's doing exactly what it's supposed to, believe it or not You can turn off tracking right after you create your Draggable if you want: ThrowPropsPlugin.untrack($x, "x,y"); But that also means that it doesn't make a whole lot of sense to use "auto" for velocities in your ThrowPropsPlugin tween. The only reason that's kinda working right now is that you've set your maximum and minimum durations to exactly 0.5, thus it's forcing the tween to be 0.5 seconds long AND you're forcing the end value to be exactly 100, thus it's fitting that in there. I don't see any value in doing a ThrowPropsPlugin tween at all the way you're doing it in fact - why not just do a regular tween that lasts 0.5 seconds and goes to x:100? "auto" velocity is really nice when you need things to be reactive and totally dynamic based on user interaction, or sometimes even when you're doing a different tween and want to smoothly take over mid-tween and pick up whatever momentum there was previously, redirecting it somewhere else. Make more sense now?
  9. When I peeked at your actual site URL referenced above, it does look choppy in Safari but it's unrelated to GSAP as far as I can tell. For example, there are some huge "composite" times as well as anonymous function calls in base.js (oddly enough, at that spot it has logic mentioning "Shockwave Flash"). I wish we had time and resources to provide free consulting and general troubleshooting services for things like this, but we really try to keep these forums focused on only GSAP-specific questions. Feel free to show us any reduced test cases that indicate there may be a GSAP-related problem and we'd be happy to look into it. Happy tweening!
  10. Thanks for letting us know. Glad the issue isn't related to GSAP Let us know if you find any evidence that indicates otherwise. Happy tweening!
  11. I'm not sure I understand the difference. Adding a function to a timeline and calling a function within a timeline sound like the same thing to me. Perhaps you mean this: //option 1: var tl = new TimelineLite(); tl.add(callMyFunction, "start"); function callMyFunction() { //a bunch of tweens or timeline that get fired independently, not inserted into tl } //option 2: var tl = new TimelineLite(); tl.add( section1(), "start"); function section1() { var tl = new TimelineLite(); //add a bunch of animations... return tl; } If that's what you're asking, I would DEFINITELY say option 2 is almost always best because you're putting it into a master timeline that you can control. Moving the playhead of that master (like with seek() or reverse() or whatever) affects all of its nested animations. If you just fire off things in random functions that get called from timelines, it's fine in some cases, but you get limited control. For example, if you fire those off when the timeline is going forward, and then you reverse that master timeline, it won't make any of those animations go backward because they're not embedded in that master timeline at all. They just fire off, finish, and get garbage collected. Done. Make more sense now?
  12. Well, I'd say a qualified "not really" to all of those points actually The example wasn't about adding functions to a timeline at all. Notice I'm calling the function at the point of insertion, thus it's adding the RESULT (returned value) of the function. In this case, a TimelineLite instance. A longer-hand version would look like: var child = buildStart(); //<-- returns a TimelineLite master.add(child, "start"); //<-- put it into the master timeline at a label "start" No, adding tweens or timelines within another timeline is not dangerous at all. In fact, the whole GSAP system was specifically engineered to make this super easy and extremely powerful. The problematic thing you were doing was trying to add the SAME tween to MULTIPLE timelines (and also controlling it individually outside the timeline). Yes, you can assign a tween to a variable if you need to remove it later, like tween.kill() or timeline.remove(tween) but you could also use timeline.kill(null, yourTarget) or TweenLite.killTweensOf(yourTarget) if you want to kill the tweens of a particular target. Lots of options actually (I could list others, but I don't want to make this response too long) Keep playing with it and I'm confident the light bulb will go on and you'll feel empowered. Happy tweening!
  13. Great job, Blake! I figured you'd have something nifty up your sleeve
  14. I'm so sorry about the delayed response. Slipped through the cracks. The problem in the link you provided is unrelated to ScrollToPlugin - it's actually codepen. Here's the error being thrown: "Error while parsing the 'sandbox' attribute: 'allow-modals' is an invalid sandbox flag." I guess iOS doesn't like that. Weird. If you go to the "debug" version of that link so that there's no codepen iframe, it seems to work great. If you're still having trouble, though, please provide a reduced test case that we can peek at and we'd be happy to look into it. Oh, and I know that historically iOS has had bugs that caused it to mis-report the current scroll position and that'd trigger the autoKill in the tween (because it's acting like the user tried scrolling the page manually, so the tween releases control for better UX). In other words, when ScrollToPlugin sets the scroll position, on the very next tick it says "hey, are you still where I set you? If so, I'll proceed; if not, I'll kill that part of the tween". You can disable this feature by setting autoKill:false in your scrollTo vars like: TweenLite.to(window, 1, {scrollTo:{y:"#element", autoKill:false}});
  15. (I was typing my post when you were adding your other one...) The reason your code didn't work was that you were adding a bunch of tweens to one timeline, then (before anything played), you were reversing the SAME tweens and adding them to a different timeline (which removes them from the previous parent). Think of tweens like DOM nodes - they cannot have multiple parents. They must live somewhere (can't be two places at one time). Otherwise, imagine what would happen to their playhead if two different timelines were both fighting for control, one going forward, the other backward.
  16. I don't think it's wise to reuse a single instance in all those cases because it sounds like you'll have too many different pieces all trying to control the same playhead (and potentially conflicting). Well, you could do it by pressing other tweens into service for controlling the playheads, but I'm not sure you'd find it as intuitive. Example: homepageTL.to(tweenCTA, tweenCTA.duration(), {time:tweenCTA.duration(), ease:Linear.easeNone}, "start+=1.125") .to(tweenIconAll, tweenIconAll.duration(), {time:tweenIconAll.duration(), ease:Linear.easeNone}, "start+=2.25") ... Notice I'm literally using other tweens to animate the playhead of your "real" tweens. But if I were you, I'd probably take a more straightforward approach instead, and just tween to the values you need when you need them. Create new tweens - we've made the system extremely efficient, so you don't need to feel like you've gotta reuse instances to be efficient. So, for example, if you've got a button rollover that plays/reverses a tween, that's fine, but then for your timeline animation just create a new tween for that. Make sense? Also, whenever I see somebody adding a bunch of tweens using labels with relative times like "start+=1.125", "start+=2.25", "start+=2.25", etc., I want to make sure they know about the power of nested timelines because those could really help make your code more modular and easier to edit. For example: function buildStart() { var tl = new TimelineLite(); tl.add(playSplit) .add(tweenCTA, 1.125) .add(tweenIconAll, 2.25) .add(tweenSelector, 2.25) .add(tweenLogo, 2.25); return tl; } var master = new TimelineLite(); master.add(buildStart(), "start"); Then, you can create a function for each section of your animation, and just have that function spit back a timeline that you nest wherever you want into a master timeline. Once you do that a few times, it's a game-changer for your workflow. You can then take entire chunks and move them around, and isolate individual chunks in their own intuitively-named functions, etc.
  17. erikb, we really try to make everything "just work" in the most intuitive way across all our products but the behavior you anticipated here would have some negative consequences if we made that all "automatic", like: It would force a backwards dependency from ThrowPropsPlugin onto Draggable, but I think that's inappropriate. In other words, lots of people might want to use ThrowPropsPlugin on its own, completely detached from anything Draggable-related. But if we made ThrowPropsPlugin automagically check if the target is also Draggable and then reach into Draggable and enforce its logic, it suddenly creates that dependency and requires loading Draggable too (even if it's not necessary in their project). Doing so assumes that the user WANTS all that Draggable logic applied, but I don't think that's a solid assumption to always make. In other words, guys like Blake to all kinds of crazy innovative stuff with the tools and probably don't want to have their hands tied in that way - they should be able to create a ThrowPropsPlugin that isn't shackled by the logic that Draggable was imposing on manual dragging. It actually seems a little counter-intuitive in some ways, like you have a ThrowPropsPlugin tween that defines both "x" and "y" velocities (and bounds), but it sounds like you're expecting it to just completely ignore the "x" aspect. If it's defined in a tween, it'd probably feel weird to most people to have it ignored because there's some other Draggable instance somewhere that has different logic applied. We really try not to make too many assumptions about how people code their stuff. We don't want to overreach in the name of "convenience". It's a fine line to walk sometimes. We generally air on the side of caution because GSAP caters to advanced animators who do aggressive stuff and need robust, extremely flexible solutions. We definitely appreciate hearing suggestions, though. We're always striving to make things better and there's surely room to improve.
  18. A tween's playhead is always determined by its parent timeline's. In your codepen, you're reversing the tween while it's inside a timeline whose playhead is already at its end, thus when you reverse direction of the tween, it will immediately render at its starting state. That's exactly how it's supposed to work. Otherwise, the state of the timeline wouldn't be correct. I'm curious - why are you using a timeline at all? And why are you trying to reverse only 1 tween inside of a timeline instead of reversing the whole timeline? Perhaps if you help us understand your goal, we can offer some solutions.
  19. Sure, all animation classes share a common reverse() method (as well as most other basic methods for control, like pause(), resume(), timeScale(), seek(), etc.). var tween = TweenMax.to(...); //then later... tween.reverse(); Note that when you reverse(), it just makes the playhead go backward toward the start from wherever it is currently. So if you call reverse() when the tween has already played for 1.25 seconds, it will then take 1.25 seconds to reach the beginning again. If you want it to jump to the end and play backward, you can call tween.progress(1).reverse(). Does that help?
  20. Ah, I see what you're trying to do. Hm. That's totally possible but non-trivial. You have to calculate the lengths of all the segments, figure out which one the current progress lands on, then subdivide that segment at that particular progress point so that you can then do all your drawing of the segments accurately. That's not something BezierPlugin provides for you. Even if it gave you the current segment a, b, c, and d values, it doesn't really solve your problem. Blake might have something up his sleeve (he's always great at this stuff), but if not and you still need help, feel free to contact us about hiring us on a consulting basis. I've been neck-deep in this type of stuff lately for CustomEase: I really wish I had a super-easy solution for you. Oh, and by the way, I noticed you used MorphSVGPlugin.pathDataToBezier() and then fed that in as type:"thru" which won't really work properly (it should be type:"cubic"). Side note: if you want to get all the a/b/c/d values that result from the "thru", you can get those directly via BezierPlugin.bezierThrough(). http://greensock.com/docs/#/HTML5/GSAP/Plugins/BezierPlugin/bezierThrough/
  21. Sorry for being late for the party I took a peek and I see why it'd seem a little confusing but from what I can tell, everything is working exactly as expected. Let me explain... Like Carl said, the timeline has no idea what you intend to do inside of your onComplete callback - it just calls the function. You happen to be changing the x/left properties in there which is fine, but it isn't as if it then inserts those values into the timeline. When the playhead changes position in a timeline, it must make sure that all of its child tweens/animations are in the proper state. In your case, you've got a tween that animates x to 700. So when you resume() your timeline and the playhead starts moving again, it says "hey, tween, make sure you render at the end properly which means...x:700". If we didn't do that, the state in a timeline could get out-of-whack. When you overwrite:"all", it finds all of the other tweens of that same element and kills them. In your case, that means it'd find that x:700 tween and nuke it. Therefore, when the timeline starts moving again and renders its state, x won't get set to 700 because that tween was killed (overwritten). Make more sense now? If you have any suggestions for more intuitive behavior, I'm all ears. As far as I can tell, everything is working properly.
  22. I'm still a little fuzzy on what the problem is that you're describing (like exactly which two calls have a gap between them and how to reproduce that), but this is where the actual pause() occurs in TimelineLite (inside TweenMax): https://github.com/greensock/GreenSock-JS/blob/master/src/uncompressed/TweenMax.js#L1094 Is that what you're looking for? It happens right before that "tween" (pause) gets rendered which is when the callback would get fired. From what I can tell, it's exactly where it should be. Might the issue be related to a flaw in LG WebOS 2 and how/when it triggers the requestAnimationFrame()? (Just a guess). Or are you saying that you think there's a logic flaw in GSAP itself that's causing things to fire at the wrong time?
  23. Oh, and one more side note: there's a gap between the "paused" and "unpaused" logs in your codepen simply because you're logging "paused" immediately when you're adding the pause to the timeline rather than when it actually happens. So since you're placing it 1 second in the future, the callback won't get called until then. Seems to work as expected.
  24. Hi @NamelessGhoul. Welcome to the forums. Very happy to hear about the positive reputation of this community. Puts a smile on my face. Anyway, about your question, I'm also a bit confused because I'm not quite sure if you're saying that you think the callback that you've got in the actual addPause() method isn't getting called immediately, or that you're having trouble with your own code and ensuring that a different function is called on the very next requestAnimationFrame tick. Can you clarify? It looks like your code would wait for 2 requestAnimationFrame cycles, so perhaps that's the problem? In other words, inside your afterRepaint() function, you've got a requestAnimationFrame() that will wait for the NEXT time the browser refreshes the screen, at which time you've got ANOTHER requestAnimationFrame() inside _startRender() that will wait for another browser refresh, and finally call your callback. Perhaps you weren't aware that requestAnimationFrame() would wait for the next refresh (thus delay things)? Totally guessing here. I may have completely misunderstood what you're asking or what the perceived problem is. Oh, and minor note: your codepen demo is not using the latest version of GSAP. I'd recommend linking to the 1.19.0 version on the CDN directly (not the "latest" which, unfortunately, our CDN provider refused to update after 1.18.0).
  25. Welcome to the forums, martifenosa. Hm, it's difficult to troubleshot with all the other code in there on a live site, but I did notice that the site is using a much older version of GSAP (1.15.1). Have you tried updating to 1.19.0? Happy tweening!
×
×
  • Create New...