Jump to content

Denis Gonchar

  • Posts

  • Joined

  • Last visited

Recent Profile Visitors

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

Denis Gonchar's Achievements

  1. Hello Everyone, I am excited to introduce Kompositor, a compositing extension for Google Chrome that I've been working on for the past year. My goal is simple yet ambitious: to make developing GSAP animations easier and more manageable for everyone. Kompositor allows you to design web animations within your browser and directly export your creations into JS code, ready to be brought to life via GSAP. Now, it is entering its "closed beta testing" phase. This means that a limited version of the extension will be accessible only to those who receive the link. I'd like to personally invite you to be one of these early testers and early adopters. Your task? Use it, test out its various features, and share your feedback with me. I'm eager to hear your thoughts, suggestions, and recommendations to help improve it for your needs. Keep in mind that this is a closed beta version, not the final release. There may be bugs and aspects that need fine-tuning. Rest assured that your constructive feedback will help me address these issues for the final version. The extension itself can be found here. Currently, it's available only for those who have the link and it cannot be found via the Chrome Web Store. For any support or questions, you can join my Discord server. Your insights and experiences at this stage will be instrumental in shaping the final product, and I'm looking forward to your feedback. Here is a demo video. Let's add some magic to the GreenSock Club page. Thank you for your time, interest, and support!
  2. https://codepen.io/charnog/pen/RwyExeP
  3. Here we are... https://codepen.io/charnog/pen/poVqNYX To implement... ... you can use setTimeout() with random time values and adjust the .timeScale() of the timeline randomly.
  4. @GreenSock Jack, thank you for the definitive answer! It’s incredible to receive that level of support! Sorry for the late response. I needed some time to play with it and validate it. To think about all the things. Regardless of the “to bug or not to bug” To answer the question, let me define the word. It is ‘something unexpected’. It was a bug at first glance, but if you say it is ‘intended’ then I will treat it as just ‘undocumented behavior’. And yes, given that it has the workaround, I agree it is "not so wise" to implement that kind of check on every tick. Just as a suggestion: maybe we need to prune the cache after the .startTime() was changed? Probably, it is more sophisticated than just 'prune the cache', but I tried to suggest it. 😎 Regardless “does that help?” question Let me tell a story. At the beginning of the story, I thought that it’s ‘ok’ to put two tweens on a timeline with identical .startTime() if the first tween is .set() tween (or .duration() === 0) and the second one is .to(). I took it as kinda hand-made .fromTo(). And it worked. I created a timeline, put some tweens on it, and got the expected behavior. Then I did some simple manipulations with their positions and durations, and after that, something was broken: random glitches of a target element ‘arrived’. So I decided to go deeper and find an answer to the ‘why?’ question. Take a look at the console of the pen. https://codepen.io/charnog/pen/GRdmZja So, I realized that putting two tweens on the same position is not a good idea, and it is necessary to use .fromTo(). I didn’t what that because it create several cases when I need to transform .to() to .fromTo() or .fromTo() to .to(). Whatever it was, I implemented all the ‘edge’-cases and was happy until… I put .fromTo() tween at the beginning of the timeline. The same ‘issue’ with caching appeared. The trick with .progress(1).progress(0) wasn’t working. I said ‘ok’ and went deeper. I tried everything I could, even deleting the internal DOMElement’s cache, without success. Currently, I realized that I over complicated everything and needed to revert the engine to the previous approach with .set() and .to(). Because in the case of .fromTo() there are much more edge cases when a user wants to use .set() (e.g. for display CSS prop). But what about that edge case with the internal linked list? For me, it is much easier to work around the 'issue' by putting the next .to() tween after .set() with the offset of 0.001 seconds so that the condition line will work as expected. Summary So... Does this help? Yes, definitely, and thanks again for that kind of reply. The current plan is to revamp it (my The Engine) via .set() .to() model and use .progress(1).progress(0) trick to handle the caching ‘issue’.
  5. Just to keep things together decided not to create another topic. So... https://codepen.io/charnog/pen/GRdWror Steps: 1. Create two tweens 2. Place the playhead between them 3. Move the first tween after the playhead 4. Invalidate the timeline 5. The initial values* will be taken from the first tween * The definition for the initial values: 'values that element has when there are no animations at all'. You can watch a video representation here. For example, if you had a div with x: 0 at 0 seconds after the steps it will have x: <value of first Tween> at 0 seconds. Is that an issue or maybe I'm doing something wrong? UPDATE (14 minutes later): As a workaround I'm using the following: 1. Save const totalTime = .totalTime() 2. Set .totalTime(0).pause() 3. Do manipulations 4. Restore .totalTime(totalTime).play() UPDATE (18 minutes later): Sad, but it fixes only the case described above. If I 'restore the previous state' after the .invalidate() call it works like a charm.
  6. No. My bad, I didn't mean 'take a look at this again', all is fine, both workarounds are working. Thanks! As I said before, I just tried to add more context to the issue when I found another steps to reproduce, I thought it would help.
  7. Same thing in my project to. It works for me only if I change the .startTime() or .duration() of the last tween and re-play the timeline. Yeap. I'm now using your workaround because it succinct and 'just works'. And trying to add as much issue-context as possible. Already! 🤘
  8. Updated the last CodePen. Found out that it reproducible even without .re-add()-ing the tween. @GreenSock can you take a look? P.S. Probably related to the previous issue, but it's a new one (I mean that it has other steps to reproduce). UPDATE (35 minutes later): Maybe it can help: the last issue happens only when the playhead is over the tween. Watch a related video here.
  9. You're are welcome, guys! It's my own interest to enhance GSAP as I use it as 'engine' for the project. 🤘 You're totally right, it's a GUI web-app that allows users to create sequences and compose things together. Big plans there... Yeap, the first version of an 'algorithm' was doing exactly this. Now imagine an animation that lasts for 3-5 minutes (I want to broaden our understanding what web-animations can be). To rebuild the timeline is 'ok' when there are few keyframes, but if there will be a lot of them then I want to do it in-place. Also, user can drag the keyframe along a timeline and number of events is huge (almost 60/sec; I'm going to throttle, anyways it will be around 20/sec). It works, but partially, and with side effects. A new CodePen has arrived. 😀 Take a look at JS section, I left comments there. https://codepen.io/charnog/pen/NWMRomL You're welcome! Yes, it works, thank you! One issue is still there and I'm trying to validate on which side it is (probably mine). I will post here, when I get it.
  10. Thank you all for the fast replies! That is Support! Nope, and thank you for this, now I know mooore. Exactly. In my project I have a playhead that can be "paused" and then I can update tween beneath the playhead. For my use case I selected the following one: const totalTime = timeline.totalTime(); timeline.totalTime(0, true).invalidate().totalTime(totalTime); To keep the playhead where it was: I save the totalTime(), then rewind it to zero point, then invalidate the timeline and then fast-forward it back. ---- A follow up question: how to invalidate the duration of a played timeline with a tween? Docs say: That's totally fine, but what if contents' duration was changed? Steps to reproduce: Create a timeline Put a tween with 2 sec duration (which makes timeline duration eq 2 sec too) Play the timeline Change the duration of the tween to 4 sec Invalidate the timeline Play the timeline again The tween will be played only to 2 sec Despite the duration of the tween was changed and timeline was invalidated the duration of the timeline will be still 2 sec. CodePen Why? And how to .invalidate()? How to workaround?
  11. So... Invalidation resolved the issue. timeline.pause(0).invalidate().play(0); The question now: if I have a paused timeline (at arbitrary time) is it right method to .invalidate() to keep the things at their initial positions? const totalTime = timeline.totalTime(); // .pause() at 0 to .invalidate() at "initial" values timeline.pause(0).invalidate().pause(totalTime);
  12. Please, see the CodePen. I created a timeline and put 2 tweens there: From initial to 100px Gap (1 sec) From previous (100px) to 200px Then I .play() the timeline and after it completed I added a new tween right after the first tween, now it looks as following: From initial to 100px From previous (100px) to 300px // A new tween .to({ x: '300px', duration: 1 }, 2) From previous (300px) to 200px But it plays it in the following order: From initial to 100px From previous (100px) to 300px From previous (100px) to 200px It looks like the .to({ x: '200px' }) tween cached "previous" value after the first play as 100px. And inserting a new tween doesn't uncache it. You can uncomment lines 6 and 16 and see that if it added right before .play() then it works as "intended". So, the question is: is it an "ok" behaviour or is it a bug? How to workaround?