Jump to content
Search Community

Chromium

Members
  • Posts

    74
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Chromium's Achievements

  1. I'd give you the benefit of the doubt @Cassie but my complaint is a bit more broad, it isn't directed at just one instance. I elaborate more on my experience on this forum in my last response. That should give you a better picture of what I'm describing, you might have missed it because you posted your response at the same time as mine. EDIT: To be clear, I do think it's very likely that you guys don't intend to insult/shame anyone, but it comes off that way sometimes, and that just makes it all the more sad. Because I guarantee you that if I'm left feeling that way after most of our interactions, a lot of people posting on your forums probably feel the same way. Because I'm not an odd case, I don't feel this way about most other places where I seek support. EDIT2: Even in your last response, this is a bit dismissive to my concerns. Especially after this in my previous response: Again, I'm not hating on anyone on here, I love you guys. This is just a bit of tough love from me. I know you're trying your best, thanks for all your hard work! And I know that that is not how you see it from your perspective, but that is exactly why I'm sharing another perspective with you guys.
  2. I'm sorry for a 2nd response on this, but it's left a bitter taste in my mouth about this whole experience. I'mma be real with you guys for a bit. This response AFTER a solution was reached, is just unnecessary. Like what would insulting/shaming anyone/everyone who's worked on reaching a solution achieve after the fact? Is it really worth it? And I'm not blaming you Cassie, I'm pretty sure, you're instructed to do this, I mean after all, you've got a whole page dedicated to it. The only reason I'm commenting on this, is because you guys have done the exact same thing to me a year or 2 ago, which means somebody has to let you guys know about it. Even in this very thread, I've found myself having to constantly defend myself nearly every response and it's really mentally exhausting, EVEN IF you guys don't intentionally do it. Like I don't need you guys to let me know every other response that my question, topic, response, logic, etc is incoherently formatted and dumb. Like I know it is, but that's the whole point of a support forum, isn't it? To ask the dumb questions? Like you guys gotta be on the same page with me on this, because just putting yourself out there and posting something on the support forum at the risk of sounding dumb already takes a huge amount of courage without the constant shaming or somebody calling your logic flawed, incoherent, lacking, overly-complicated, and the list goes on. And please don't underestimate the weight of my complaint here. And don't reduce my examples above to just the specific synonyms I've given there, because off the top of my head at least 3 other instances in this very thread alone come to mind. And no, they don't come from Cassie. But I'm not going to name names or quote quotes. Please understand that if I didn't love your library, I simply wouldn't care to share this feedback with you guys, I'd simply just avoid using your support forum at the cost of heavily reducing my usage/reliance on your library. Unless I'm not using your support forum for what it is intended for, then in that case, ignore my entire complaint.
  3. Hahaha yes that was it! I know how to 'fork', but your CodePen had no 'fork' button to press or I would have, so I had to manually copy paste the code then copy the settings/scripts from your CodePen. This is also one of my biggest pet peeves with your guys' CodePens, they're so helpful and make it extremely easy to replicate/debug, but half of your shared CodePens have no 'fork' button for some reason which defeats the entire purpose in my opinion. I'm not familiar with keyframes in tweens, so today I definitely learned something (and I might just go on an abusive streak with this, and it's all your fault)! Thanks Your solution is exactly what I'm trying to achieve!! And in hindsight, it seems so simple now that my motionPath solution becomes overly complex/trivial for what I needed... in fact, I'm now confused as to when I'd ever use a motionPath lol I'm sorry, but if this is directed at me, then I think you're wrong. Perhaps this is intended for your team internally? Because this is just not true in this case, here's a quote of exactly what I typed in my very first post here: And here's, literally, the very first 3 lines in my next reply: Never did anyone at any point make a suggestion of "Oh hey, if you just want to add a cuve on the X-axis with a FLIP, have you tried this...?". I'm sorry if this seems harsh, but your criticism, if directed at me, seems quite harsh, so I'm forced to defend myself. Again, if your criticism is directed at me, then it sounds like to me that you're saying that I provided more information than necessary in my initial post? If so, in my entire years of debugging code/logic problems, I was taught that this is a good problem to have, you guys would be the first to say otherwise. Additionally, the very first response to that, deviated into something about FLIP.fit() which I thought was very unrelated to what I was seeking. Up until your response, at no point ever, was a question posed or a suggestion made with something along the lines of "did you just want to add a curve to a FLIP animation?". Boy oh boy tell me about it, it sent me down a rabbit hole that I didn't need to go down to. Though it's not entirely alone at fault for this, it's something I've always struggled with in GSAP and I don't know how you guys deal with it given how frequently you probably use GSAP; sometimes you get laser focused on solving something one way you simply can't find another way... even worse (and this may very well just be a me problem but it happens a LOT), sometimes when the code is not flowing synchronously, you just can't wrap your head around it, let alone come up with an asynchronous solution like the one you just came up with. Like in this instance, in my head, the FLIP animation is just DONE, after the FLIP animation is done, there's no tweaking its animation asynchronously lol Sorry Rodrigo, but I think Cassie has earned the solution badge on this one! Haha
  4. Thanks for sharing that Cassie! It's amazing to see that such flexibility is a feature! Unfortunately though, it seems that's not applicable to my case because my X is not changing by default like in your animation. I cloned your example to this CodePen: https://codepen.io/fuad-zeyad-tareq/pen/wvZEPRx In the CodePen, I simply removed the left/right properties in .box.fixed to demonstrate something very close to my current FLIP animation. However, and this is why I don't do CodePens, god forbid I clone an already working CodePen and try to make that work, it's giving me a blank screen with no console errors or anything!!! GAH, I just don't have the patience nor the time for this. In any case, like I said, if I take out the left/right properties from your .box.fixed, which makes the FLIP into a simple Y animation... but I still want to add an X-curve to that, that simply seems not possible at the moment. Does that make sense? So let's say the animation goes from (0, 0) to (0, 500) currently, I don't need the X to be different at the start or finish, but I do want it to curve during the FLIP animation. Perhaps your solution to this would be to temporarily change the X value during the FLIP animation? If so, this is where I was stumped, because it's hard to wrap my head around that. I'm comfortable with supplying a initial X, Y and final X, Y so I wouldn't know how to add an intermediary X, Y (or just X) to a FLIP animation. And the motionPath seemed to somewhat fit the bill for that, at least in my head.
  5. Yes, I kind of figured that that would be your response. And that's fine. That is why my entire post is an idea/request for consideration. So regardless of any other issues that you mention, at the end of the day, I kind of have to say, yes but please consider allowing my request to work! Haha As my last attempt to summarize my request in a clear and concise manner, I will use a real-life analogy to more correctly convey my thought process of how FLIP/MotionPath integration would work: I take a taxi to go from Point A to point B (that is the FLIP animation). I don't know how to get there myself, so I tell the driver to get me there however it takes but let's take a scenery detour, or pass by Walmart on the way there, etc (that is the motionPath). My job is to deliver my use case/idea in a cohesive and understandable manner... which I hope I have now delivered, even if it wasn't in the most efficient of ways. Your job is to make that 4% into a 140% or discard my idea altogether if it is invalid. It sounds to me like you're leaning towards the latter for now, and that's fine, sad, but fine, you're the expert! But that won't stop me from pretending that my idea is praised as revolutionary in an alternate dimension! Lol Thanks for your time! Great job on keeping the plugin smooth and performant!
  6. I'm definitely missing your point. Because it seems that, when I'm giving you a definite use case where this WORKS, you're focusing on the ones that don't... and I don't get why you are. Additionally, it seems you're asking me to debug every other use case that I'm not asking for... and since I don't work at GSAP, this seems hardly a fair request lol I'm not asking you to make every use case work, just to allow mine to work? It should be irrelevant whether 98/99 use cases won't work if we can have the flexibility to allow 1 more use case to work seamlessly without any additional overload, KB, performance, etc. And yes, I say without any additional anything because all the data needed to get my use case to work is already there! FLIP already saves the initial state (X, Y, height, width) and I'm simply saying to make that available to motionPath as well when used in a FLIP... that's literally it. That would immediately allow my use case to work. Granted, I do think that there's room to do a lot more but for the sake of simplicity, let's say that's all that is needed. What is the issue in allowing this?
  7. Man, this seemed extremely simple of a request in my head... but things like this never are simple, are they? Good question, I mean the specifics of how this will function can be planned later on when you guys decide to implement this... but if I had to chime in now on this specific scenario, I'd say there are more than one option: 1) This will do nothing. Because a motionPath in the context of a FLIP, serves only to overwrite an existing animation... so if a Y animation isn't part of the FLIP, then the motionPath will do nothing. OR 2) If it's used in the same way I used my motionPath, it adds a little detour/curve, but the starting point and ending point is still the same. And I love that about FLIP. To give a helpful analogy like @Rodrigo did earlier, I love the fact that I can just let FLIP take the wheel and take me to my destination. But that doesn't mean I don't want to, as the passenger, ask FLIP to sometimes take a different path than the one it chooses long as the path leads to the same destination. I hope this clarifies my request/idea.
  8. Not seamlessly, motionPath should simply override the FLIP animation's calculations in this case. I'm saying any time motionPath is specified on a FLIP animation, it means I'd like to override whatever that part of the FLIP animation is. So if all the FLIP animation is doing is animating the X value like you're saying, then motionPath now takes precedence, period. On the other hand, if the FLIP is animating multiple properties such as the X, scale, Y, etc among other things, motionPath simply overrides the X animation part of the FLIP. Thank you for giving a clear example in simple terms. I hope the above clarifies what I meant... sorry if I didn't make it clearer before, but I've been trying to say that motionPath simply should take priority over whatever is animating.
  9. I appreciate your detailed response and that is why I marked it as a solution. I fully appreciate the performance and KB side of the equation, and if there is no way to deliver what I am asking without sacrificing on that, then you have me there. That being said, I do think that there are ways to go about delivering what I am seeking without sacrificing any performance or KB, simply put, I am asking for an optional setting on the FLIP animation that only people like me would choose to enable... so it should have no impact on the performance or KB when that option is not enabled? Essentially, the bottomline of my disagreement is here. I don't see it how you see it, I see motionPath as more of a utility whose sole purpose is to edit the animation path of an existing animation... whether that's a tween, FLIP, or a penguin walking down the street. Now if that is not at all the intention of the motionPath plugin and I have misunderstood it, then I rest my case and I forgo my argument haha. But if that is the purpose of a motionPath, then in my opinion, it is not doing its job well when it comes to a FLIP animation, that's it. It seems like a matter of perspective to me, I understand motionPath as a utility that should work with all tweens/plugins/animations, you see it as a separate plugin that shouldn't synergize with a FLIP animation.
  10. So if I understand correctly, you're saying that there's no confusion that the user wants full/partial control over the FLIP animation, but it's just impossible to give the user any control over the FLIP animation using motionPathbecause CSS doesn't allow it? I guess why I'm still struggling to understand this is because I feel like what I'm asking for is still a JS problem. Why can't your FLIP plugin recognize that motionPath is specified and override any of its styles with the given styles from the motionPath? There should be no fight/race here for control as when motionPath is specified, it's always given priority, as to me it seems obvious that the user wants to override something in that case. And since all of these settings are specified prior to any animation occurring, then the setup above can be adjusted on the JS side prior to any CSS being injected?
  11. Hmm let me try one more crack at posing my question more clearly. 1. My FLIP animation works perfectly fine on its own... it's just animating the Y value of an element (after the element is moved from one parent to another). I wanted to add some pizzazz to this vertical FLIP animation... a curve on the X-axis came to mind. 2. I used motionPath on the FLIP animation to add an X-axis curve. Keep in mind the starting X and ending X value for the FLIP animation is 0. 3. I did get this working in the end like I said. So I don't have any CodePen to share. But it did feel like it was more effort to get it working than it should have been, so I wanted to share feedback on my experience with you guys... because I can only assume my usage to be another niche case scenario, haha. But I got it to work! Haha. The only thing I had to fight with to achieve this (which made it very un-intuitive) is that the motionPath was receiving the final state of the FLIP animation instead of the initial state/positioning of elements. Let me try to explain this with an example: If I'm moving an element in the DOM and use FLIP to animate that, I'd: 1) Get the initial state of the element. 2) Do the append. 3) Run the FLIP animation. Right? Now let me ask you a question, if I ran motionPath inside that FLIP animation, what do you think it gets as its X/Y positioning of said element? Would it be the X/Y positioning after the append or before the append? Currently, it's after. The intuitive behaviour here is that it should get the X/Y positioning of the element before it was appended; in other words, what was recorded in the initial state of the FLIP animation. If this is still unclear, what I mean by X/Y positioning before and after, is that before the element is moved, when it is under say parent 1, the X/Y positioning will be completely different than when the element is later moved to parent 2. When the element is under parent 1, I consider this the initial state (before the FLIP animation is executed) in my example. I understand that this might be the current implementation... but this is the essence of my post, is that they should be made more synergistic with each other. I like that the FLIP handles the X/Y/width/height for me to achieve the cool automatic animations it does on its own... but what if: 1) I like 75% of its animation or wanted to add an additional animation to it? 2) What if I didn't fully like the path it takes and/or wanted to add a horizontal curving to its vertical animation (my scenario)? Unless there's a better way/tool to achieve what I did here, then I see no reason why the 2 plugins shouldn't gel well with each other in the future. In fact, even if there was another way/tool to achieve what I'm after; whether it's with regular tweens or other plugins, I feel like having more than one way to achieve the same thing is a net benefit to GSAP, so I still think the synergy between the two plugins is worth improving on. I hope all of this somewhat makes sense? If not, then don't worry about it haha. I've solved my problem after all so I will be okay. I just hoped to make this process a little easier for others (including myself) in the future if motionPath was a bit more seamless/intuitively integrated with FLIP.
  12. I love the FLIP plugin and I love the fact that we can use the motionPath plugin inside of a FLIP animation inside of a timeline!!! The flexibility is awesome! Today was my first time using your motionPath plugin... and it was for doing this: t1.add(Flip.from(state, { duration: .3, ease: 'power1.inOut', absolute: true, targets: _npClone[0], // Using motion path plugin to create a subtle arc. motionPath: curveMotionPath(pos, 0) }), 0); If we comment out the motionPath: curveMotionPath(pos, 0), this FLIP animation works perfectly, believe me. I've slowed down the animation to a crawl and it gets from point A to B with 0 problems. I've even console logged the position.top() of point A and point B to ensure that was the case. Heck, I even highlighted the starting and ending points of said animation by inserting a position: absolute div on the page to ensure they were correct. So I wanted to add some pizzazz to this FLIP animation and ChatGPT suggested to use motionPath to add a nice little curve to the animation to make it a bit more realistic... I thought, this sounds fantastic! Seems simple as well, almost like adding a border to a div... boy was I wrong. I ended up spending the better part of a day to get this working! This is the content of curveMotionPath: curveMotionPath: function(startY, endY, maxDeviationX = 30) { let y1 = startY + (endY - startY) / 4, y2 = startY + 3 * (endY - startY) / 4, deviationX = -Math.min(Math.abs(endY - startY) / 2, maxDeviationX); return { path: [ {x: 0, y: startY}, {x: deviationX, y: y1}, {x: deviationX, y: y2}, {x: 0, y: endY} ], type: 'cubic', curviness: 2, //align: 'self' }; } I did not even want to modify the starting or finishing positions, surely this is easy to do, I thought it was gonna be a plug and play. Alas, imagine my surprise, when adding the motionPath into that already working animation, broke the starting position of the animating element! I gave it the correct startY, the correct endY, the FLIP animation already had the correct start and ending positions... I thought how could I have possibly screwed this up? And yes I tried the magical keyword align: 'self' or aligning to specific DOM elements. When I added align: 'self', that seemed to fix the startY but then the endY became incorrect. Fun fact: this was the main reason I was able to understand what was happening below as it posed the question in my head... if align: 'self' fixed the startY, what was it aligning to before? Well after hours of debugging, it finally occurred to me... the motionPath was NOT using the initial state of the FLIP animation like the FLIP was, it was using the final state of the DOM. Once I made that revelation, it was rather easy to come up with a solution... mind you, I said easy, but not intuitive. I can't possibly imagine this was intentional by design? I might be wrong, but I feel like this may have been overlooked due to how niche of a use-case this is... as my search results on the topic yielded nada. I feel like the default and intuitive behaviour in this case should be to use the FLIP animation's initial state and not final state. In my head, it makes the most sense that the animation is from initial state to final state, so if I'm changing the path of said animation, I expect to be accessing x and y of initial state as the start of the motionPath, and the end is the final state of said motionPath. As I am attempting to alter the path of the FLIP animation, there can't possibly be another explanation to this? Why would I want to alter the path AFTER the FLIP animation is complete?! I understand if this is just the default behaviour of a motionPath with a regular tween and it works well enough for that job... no need to change that. But for a FLIP animation, I think what I said above is most intuitive unless I'm missing something? If somehow there's a use-case more appropriate that makes the current behaviour as the intentional default for a motionPath with a FLIP animation, then perhaps GSAP should add a setting somewhere to allow the behaviour above as an option? TL;DR: What I'm saying is that the motionPath should be using the FLIP animation's initial state values (specifically, positioning) instead of the final state/DOM values/positioning by default as it is more intuitive. This was using GSAP v3.12.5.
  13. Ah... I am a little annoyed now. Right after I posted my last reply, I just caught something... that there's a .reverse() and a .revert() for timelines!!! This whole time I've been thinking they were one and the same. I've actually only used .reverse() on a timeline! I think .revert() is a very powerful tool that I've been missing! Mind elaborating on the difference between the two? Is it just that .revert() also resets the inline styles? Also, .revert() probably also causes an animation jump, right? Is .revert() the only timeline method (out of .reverse, .progress, .kill, .time, .clear(), .restart(), etc) that also resets inline styles? However (and correct me if I'm wrong), I imagine that .revert() is not sufficient on its own for something like this CodePen:https://codepen.io/GreenSock/pen/wvxbvjg Specifically, I'm referring to this line in the JS: text.appendChild(cursor) Because the original DOM state looks something like this: <span id="text"></span> <span id="cursor">|</span> And when that JS line executes, it will move the #cursor node inside of the #text node. So I don't imagine .revert() will undo that? Will there need to be some additional code logic to run after .revert() to undo that as well? I assume this might be a use case for gsap.context() because reverting the context would also revert the DOM structure?
  14. Exactly! One of the things I wasn't sure about for example is whether .kill() also got rid of the inline styles or not. And whether .revert() did that or not. But the main thing I've learned about .kill() is that it essentially leaves the animation playhead exactly where it's killed, and thus leaves the inline styles on the elements as well. Knowing this, once put to practice, I believe should significantly help me in figuring out exactly which method to choose when handling the spam clicking on my next GSAP task. This does bring to mind though, does .progress(0) also undo the inline styles added by the timeine? Correct. However, as far as production code goes, I can assure you that that's probably one of the simplest edge cases for me. ? But I definitely feel much better equipped to handle those other edge cases now. I mean that there probably isn't any shortcuts when it comes to handling spam clicking for many of the edge cases that I've ran into the past few months. See below for examples of what I mean. This one is probably the cleanest but I believe it only works if the content inside the tweens doesn't change, right? Annoyingly, the majority of my GSAP tasks involve dynamic content that changes on subsequent clicks. So this method wouldn't work with my earlier example for instance; the typewriter animation that pulls a different TextPlugin value through AJAX on each button click. To give you a brief idea of what I mean, let's say I'm running the following tween in a timeline on the press of a button: t1.to(_text, { text: { value: answer }, delay: 1, duration: 5, ease: 'none', stagger: .5, onUpdate: () => _text[0].appendChild(_cursor[0]), }); The tween here pulls an answer variable through AJAX and then animates "typing" the answer value for a duration of 5 seconds. The problem here, is that on subsequent clicks (spam or not), I simply wouldn't want to reverse this tween because it would take 5 seconds to reverse. Additionally, I also cannot use .restart here because it simply will not pull the fresh new value for answer (as expected). So this leaves me with no option but to .kill() the timeline, re-initialize its variable, and then add some other tween to maybe animate the _text node's parent to a height of 0 (over the span of 0.2s) for subsequent/spam clicks instead and then re-add the above tween (but with a fresh new value for the answer). I also do not think gsap.context() would handle this particular problem any better. Haha, that's the thing, I am not sure that there's one. I think for my edge cases (such as the one above), I'd just have no choice but to handle the problem as I described above. Unless maybe there was a way to fast forward the .reverse() call to the timeline? If I could maybe control the speed of how fast the .reverse() executes... I'm just spitballing though here haha. I hope the example above kinda gives you an idea of what I'm dealing with though. That being said, that tween is only half my problem in production code, I have another tween that has to be handled separately anyway. So if the SplitText CodePen I showed you was an edge case, then this is the edge case's overlord ?
  15. I was thinking that on subsequent clicks, I can revert parts of the timeline, kill the timeline, and then re-initialize it with brand new tweens... but maybe this is over-complicating things rather than making them simpler haha. Because the demo that I posted was a random demo that I picked up just to portray the .kill() on the timeline not working for me haha. But the one I was using in production code was the typewriter animation (that was also giving me trouble with killing the timeline on spam clicks). It just so happens that this one also manipulates the DOM... as it appends a cursor div to the end of another div in the onUpdate() of the tween. Call me Mr. Edge Case lol Ironically, that is literally why I started this post... because I felt like GSAP should be so easy to use, but it's giving me such a hard time nearly every time I've had to deal with spam clicks, so I must be doing something very wrong or missing something. Instead (and what I've learned today) is that it seems like I've just been working on edge case after edge case after edge case... which I'm not really surprised to learn because in this job it seems I've been working on edge cases with pretty much 70% of the plugins I've used. Thank you for your patience with me, Jack. I do believe it was well worth it. As at the very least, I've solidified my core understanding on how tweens work (whether that's with inline-styles, timeline/tween kills/reverts, etc). As for spam click handling, I'd hoped to find some shortcuts, but while I didn't really find any, I do think that my strengthened understanding of timeline/tween handling learned today should come in handy for the next GSAP task that involves any spam click handling. I look forward to the next GSAP task! And in spite of these issues, GSAP is still a joy to use and one of the greatest things to exist since sliced bread! Keep up the great work!
×
×
  • Create New...