Jump to content
Search Community

Denis Gonchar

Members
  • Posts

    12
  • Joined

  • Last visited

Posts posted by Denis Gonchar

  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!

    • Like 2
  2. Here we are...

    See the Pen poVqNYX by charnog (@charnog) on CodePen

     

    To implement...

    1 hour ago, leet-ice said:

    Other thing would be is adding in randomization, like every few seconds, maybe the fish starts pulling harder, and meter is going faster to 0%? or it's swimming towards you and you don't need to reel in as fast?  

    ... you can use setTimeout() with random time values and adjust the .timeScale() of the timeline randomly.

    • Like 2
  3. @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.

    See the Pen GRdmZja by charnog (@charnog) on CodePen

     

    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’.

    • Like 1
  4. Just to keep things together decided not to create another topic. So...

    See the Pen GRdWror by charnog (@charnog) on CodePen

     

    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.

  5. 31 minutes ago, Carl said:

    I tried using the uncache() method but maybe I was using it wrong as I couldn't get it to help your latest demo.

    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.

     

    31 minutes ago, Carl said:

    Please stay tuned. Finding solutions for these types of issues can take some time to troubleshoot and test properly. 

    Yeap. I'm now using your workaround because it succinct and 'just works'. And trying to add as much issue-context as possible.

     

    31 minutes ago, Carl said:

    Sounds cool. Sign me up!

    Already! 🤘

    • Like 1
  6. On 9/12/2022 at 10:35 PM, Carl said:

    First, thanks for the super-clear AND reduced demo. Kind of rare that we get to work with demos like this :)

    You're are welcome, guys! It's my own interest to enhance GSAP as I use it as 'engine' for the project. 🤘

     

    On 9/12/2022 at 10:35 PM, Carl said:

    While we're all here, I'm curious what the use case is where you need to adjust the duration of a tween after it's in a timeline. 

    I'm guessing that maybe you are working on a sort of GUI where the user can build their own animations.

    You're totally right, it's a GUI web-app that allows users to create sequences and compose things together. Big plans there...

     

    On 9/12/2022 at 10:35 PM, Carl said:

    If yes, you may just want to rebuild the entire timeline every time an adjustment is made to a tween. 

    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).

     

    On 9/12/2022 at 10:35 PM, Carl said:

    For now, a valid workaround could be that you just re-add() the tween to the timeline AFTER you adjust it's duration.

    It works, but partially, and with side effects. A new CodePen has arrived. 😀 Take a look at JS section, I left comments there.

    See the Pen NWMRomL by charnog (@charnog) on CodePen

     

    On 9/12/2022 at 10:45 PM, GreenSock said:

    Indeed, your minimal demos make it much easier to troubleshoot so thank you.

    You're welcome!

     

    On 9/12/2022 at 10:45 PM, GreenSock said:

    Does that help? 

    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.

    • Like 1
  7. Thank you all for the fast replies! That is Support!

     

    On 9/11/2022 at 4:32 PM, mvaneijgen said:

    Have you seen the following tutorial?

    Nope, and thank you for this, now I know mooore.

     

    On 9/11/2022 at 9:50 PM, GreenSock said:

    Are you just trying to rewind everything to the start? It sounds like maybe you want to FLUSH those values out, right? If so, .invalidate() is what you're looking for, yes

    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:

    Quote

    Due to the fact that a timeline’s duration is dictated by its contents, using this method (.duration()) as a setter will simply cause the timeScale to be adjusted to fit the current contents into the specified duration, but the duration value itself will remain unchanged.

    That's totally fine, but what if contents' duration was changed?

     

    Steps to reproduce:

    1. Create a timeline
    2. Put a tween with 2 sec duration (which makes timeline duration eq 2 sec too)
    3. Play the timeline
    4. Change the duration of the tween to 4 sec
    5. Invalidate the timeline
    6. Play the timeline again
    7. 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.

    See the Pen gOzwboP by charnog (@charnog) on CodePen

    Why? And how to .invalidate()? How to workaround?

  8. 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);
    • Like 2
    • Thanks 1
  9. Please, see the CodePen.

     

    I created a timeline and put 2 tweens there:

    1. From initial to 100px
    2. Gap (1 sec)
    3. 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:

    1. From initial to 100px
    2. From previous (100px) to 300px // A new tween .to({ x: '300px', duration: 1 }, 2)
    3. From previous (300px) to 200px

     

    But it plays it in the following order:

    1. From initial to 100px
    2. From previous (100px) to 300px
    3. 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?

    See the Pen dyeXXBr?editors=0010 by charnog (@charnog) on CodePen

×
×
  • Create New...