Jump to content
Search Community

RolandSoos last won the day on January 18 2019

RolandSoos had the most liked content!

RolandSoos

Members
  • Posts

    200
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by RolandSoos

  1. Thanks @Dipscom!

     

    My current system use tiny timelines and manages their statuses and such. There is no real problem with it, but with a single timeline, I would be able to achieve better result in the following areas. Single timeline would allow to

    • use the same timeline as linear or event based mode. I would be able to simply change progress based on scroll for example.
    • when the canvas in my system changes,  I could simply invalidate the timeline without errors. Currently I have to invalidate all timelines in the right order as their happen on the same element/props also I must restart the animations from the start point. With a single timeline I could invalidate and just "resume" from the current point.
    • not care for immediateRender. As the current system animates the same element's prop in different timelines, I must use the proper tween and it results in lot of testing.
    • use timeScale easily.
    • throw out a lot of code related to timeline managing.

    Probably I would be able to solve all of these things with tiny timelines and a custom timeline manager implementation. But, why would I write a new timeline controller if GSAP's might be able to solve this issue, right? :)

     

    BTW: I near to the finish with my single timeline and it looks and works great. I haven't seen any bug related to this double firing, probably because I still manage statuses and my callbacks verify if the actual status is the right one. So it is not so important for me, it would be just nice to know if this bug could result any other anomalies.

  2. I have 3 boxes animated with scale on this Codepen.

    #1 has a parent with overflow hidden -> the scale flicking during the scale animation

    #2 has a parent with overflow hidden and the parent has a parent with perspective -> the scale animation is fine

    #3 has a parent with overflow hidden and perspective -> the scale animation is fine

     

    Is adding perspective to the overflow:hidden element is the right solution or is there a better way to fix this?

     

    Tested with Chrome 71. Firefox seems fine.

    See the Pen BvPPyj by anon (@anon) on CodePen

  3. Well, I can reproduce it in every 3-5 Codepen run, it happens after 5-7 iteration. Also The window was focused all the time, so I do not think it is relevant.

     

    In my old system I have 3 simple timelines and they contain tweens for the very same element. The system manages to play, pause, seek etc... all of them. The timelines play only when their dependency met.

    Here is an example (events are optional in the system)

    TL #1 Plays when user clicked a button and if this is the first time when TL #1 plays

    TL #2 Plays when TL #1 completed and this timeline repeats itself until the user clicks another button. If the button clicked TL #2 plays until onComplete

    TL #3 Plays when TL #2 completed

     

    When I add them to a single timeline, it gets a little complex, but I think it is possible with GSAP. This is why I experience with these edge cases and examples :)

    1. addLabel -> 'TL1' -> Position 0
    2. addCallback -> Position +=0.001 -> Pause the timeline if TL #1 dependency not met (Also play the timeline in the future when dependency met). Position offset added so when I seek to TL1 label in the future I do not need suppressEvents:false
    3. add TL1 tweens
    4. addCallback -> Notify system that TL1 completed
    5. addLabel -> 'INITIAL' -> Position +=0.001
    6. addLabel -> 'TL2' -> Position +=0.001
    7. addCallback -> Position +=0.001 -> Pause the timeline if TL #2 dependency not met (Also play the timeline in the future when dependency met).
    8. addLabel -> 'LOOP' -> Position +=0.001
    9. add TL2 tweens
    10. addCallback -> Position +=0.001 -> if the dependency not met seek back to loop label all the time. .seek('LOOP')
    11. addCallback -> Position +=0.001 -> Notify system that TL2 completed
    12. addLabel -> 'TL3' -> Position +=0.001
    13. addCallback -> Position +=0.001 -> Pause the timeline if TL #3 dependency not met (Also play the timeline in the future when dependency met).
    14. add TL3 tweens
    15. addCallback -> Position +=0.001 -> Notify system that TL3 completed. Based on the options, might .seek('TL1')

    Public actions allowed on this timeline are:

    • play
    • pause
    • seek('TL1')
    • seek('INITIAL')
  4. Thanks @Dipscom!

     

    I started to work with your suggestion. Well, if I assume 60fps 1/60=~0.01666, the offset should be smaller than that number. So the suggested 0.01 should be fine, but I tried it with 0.0001. I'm not sure if the following error related to float rounding or something wrong with my code. I might need to add multiple labels/callback at the "same" offset position, so I would like to go 0.001 as that would give 16 extra spaces for a tick at 60fps.

     

    See the Pen vvdqEm by anon (@anon) on CodePen

     

    Normal console output would be:

    Start

    pause at IN

    pause at Complete

    pause at IN

    pause at Complete

    pause at IN

    pause at Complete

    pause at IN

    pause at Complete

     

    But sometimes I get the following:

    image.png.0567f13ffc334a9371589279f6931621.png

     

    If it is really a float rounding issue, is there any chance that it happens when the small offset is 0.01 or 0.001?

  5. Thanks @Dipscom!

     

    Problem #1: Well, I was not aware the if I seek backward all in-between events are fired. I thought the .seek(0, false) only fires events which happens at 0 position. I think it is a good to remember thing...

     

    Problem #2: I thought their are linear in the original add tween order. So If if my addPause stops the timeline, the timeline does not render other tween at the very same position which added after the addPause. If the timeline resumed, then it would continue at the same tick with the next tween after the current pause. Yeah, I see, it is too complicated to manage properly :)

     

    As you mentioned, other problems are all based on this two misunderstanding. Probably my use case is to specific and I see I won't be able to solve it with in-built addPause and labels. Probably I will use addCallback strictly one at one position to prevent problems and I will manage the label transitions in these functions.

     

  6. Hi @mikel,

    thanks for your thoughts. In my addPause callbacks, I placed a simple play calls. I think that was a mistake on my side, but if I would add a promise for everyone of them that would add a lot of unnecessary codes. 

     

    Here is a simple example with promise. When the promise resolved, the timeline can continue from from pause1 state. If the promise resolved during the first tween, then the timeline simply continues. If it is resolved after reached addPause callback, the timeline will wait until the promise gets resolved and continues to play.

     

    See the Pen pqprJe?editors=0011 by anon (@anon) on CodePen

     

    Update: I edited the examples in my first comment. Now the every play action depends on a promise.

     

  7. I know my example is silly and there is no real reason in these examples to use addPause. 

     

    I'm writing an algorithm which will create timeline based on a specific data structure. There are multiple animation stages -> Incoming, Loop, Outgoing and some of them might be empty and they might pause the timeline at a specific label.

    var tl = new TimelineLite({
      onComplete: function() {
        tl.play("incoming");
      }
    });
    tl.addLabel("incoming");
    tl.addPause("incoming", function() {
      // Resume the timeline if the related Promise resolved
    });
    // Add the incoming animations if any
    
    tl.addLabel("loop-incoming");
    tl.addPause("loop-incoming", function() {
      // Resume the timeline if the related Promise resolved
    });
    
    // Add the loop-incoming animations if any
    
    tl.addLabel("loop");
    // Add the loop animations if any
    
    tl.addLabel("loop-outgoing");
    tl.addPause("loop-outgoing", function() {
      // If loop set for multiple iterations -> Jump back to the "loop" label and play
      // Resume the timeline if the related Promise resolved
    });
    // Add the loop-outgoing animations if any
    
    tl.addLabel("outgoing");
    tl.addPause("outgoing", function() {
      // Resume the timeline if the related Promise resolved
    });
    // Add the outgoing animations if any

     

     

    For example if there is no incoming animations, then the addPause for the "incoming" label will be at the same time as the "addPause" for the loop-incoming label.

     

    The documentation states that addPause is a null tween with a pause at the onComplete event. So In my pens I set the suppressEvents to false.

     

    Problem #1: 

    See the Pen PXEpYY?editors=0011 by anon (@anon) on CodePen

    The console output should be Pause 1 -> Pause 3 -> Pause 1 -> Pause 3 etc...

    The actual output is: Pause 1 -> Pause 3 -> Pause 1 -> Pause 1 -> Pause 3 -> Pause 1 -> Pause 1 -> Pause 3

     

    Problem #2: 

    See the Pen KbZaEM?editors=0011 by anon (@anon) on CodePen

    Pause 2 should come instantly after Pause 1, but it happens after pause 3. I'm not sure why.

     

    Problem #3: 

    See the Pen wRpJBK?editors=0011 by anon (@anon) on CodePen

    There is no way to play the timeline if the addPause placed at the 0 position. I tried with and without supressEvents.

     

    Problem #4: 

    See the Pen YdYZOP?editors=0011 by anon (@anon) on CodePen

    If the timeline plays from a label, then  addPause fired, but it does not pause the timeline. It reports in the addPause callback that the timeline state is paused, so there is no way to force pause the timeline. Probably the solution for this is to use seek instead of play and play the timeline from the addPause callback when the promise fulfilled: 

    See the Pen KbZWbQ?editors=0011 by anon (@anon) on CodePen

     

    Problem #5: 

    See the Pen MZrmwP?editors=0011 by anon (@anon) on CodePen

    Tried to solve Problem #4 with seek, but stuck again. If I seek to a new label inside the original play call stack, even Pause 2 skipped and the timeline plays.

    Then I tried to "escape" from the play's call stack with setTimeout, but the result is even more unexpected, the first tween continues to play and the seek does not happen: 

    See the Pen dwJWOM?editors=0011 by anon (@anon) on CodePen

     

     

  8. The customised invalidate method didn't end up well. Probably there is a good reason why it renders at position 0. Probably it does not know about its timeline position and the previous tweens on the same element which cause conflicts. I'm not sure if its allowed to use the undocumented render method, but it works fine after the invalidate.

    tl.render(tl.time(), null, true);

     

    If you do not suggest to use that method, probably I will go with @OSUblake solution, but I think the forced rendering of the current time is more elegant. Also I'm not sure, but increasing the time, might result in rare situations like skipping label or a pause. For example if user drags the browser window which would fire hundreds of resize events... what do you think?

    tl.time(tl.time() + 0.00001);

     

  9. I checked the source code of GSAP and it turned out that the _time property is set back to 0 on invalidate and when immediateRender is true, it renders the tween's starting point. 

     

    Animation.prorotype.invalidate = function() {
      this._time = this._totalTime = 0;
      this._initted = this._gc = false;
      this._rawPrevTime = -1;
      if (this._gc || !this.timeline) {
        this._enabled(true);
      }
      return this;
    };
    
    
    TweenLite.prototype.invalidate = function() {
      if (this._notifyPluginsOfEnabled) {
        TweenLite._onPluginEvent("_onDisable", this);
      }
      this._firstPT = this._overwrittenProps = this._startAt = this._onUpdate = null;
      this._notifyPluginsOfEnabled = this._active = this._lazy = false;
      this._propLookup = (this._targets) ? {} : [];
      Animation.prototype.invalidate.call(this);
      if (this.vars.immediateRender) {
        this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render)
        this.render(Math.min(0, -this._delay)); //in case delay is negative.
      }
      return this;
    };

     

    Just for a quick try, I slightly modified the invalidate method to force render the tween at the current playHead when invalidate. 

    See the Pen EGWwbe?editors=0011 by anon (@anon) on CodePen

     

    • Like 1
  10. Thanks @OSUblake, probably you are right. But in that case it should not render anything on invalidate. Here is a simple example:

    See the Pen QzpMyR?editors=0010 by anon (@anon) on CodePen

     

     

    First x is 100 and it will jump to progress 0.5, so the rendered x is 50. If you click, x will be 200 and it should jump to x:100 as we are the middle of the timeline, but it jumps to 200, to the elements initial value. 

     

    Also you are right, changing the playhead position fixes the issue. Maybe it is a feature request, to render the proper value according to the current playhead instead of the initial value. Or create a method which can force the rendering without changing the currently playhead even a little. 

     

  11. Well, first of all I'm sorry that I always have edge cases :)

     

    So, I started to experience with invalidate and try to animate properties based on the current responsive ratio. My initial test was great and it worked as expected. 

    When you play the Codepen, the code records the current width of the window and on resize it calculates a ratio based on the new value and invalidates the the tweens which need to get invalidated. So the red box will move on a path of a triangle.

    See the Pen OrpRXr?editors=0010 by anon (@anon) on CodePen

    When the ratio is 1.0 => x:300,y0 -> x:0,y:0 -> x:300,y300 -> x:300,y0

     

    When the ratio is 0.5 => x:150,y0 -> x:0,y:0 -> x:150,y150 -> x:150,y0

    I was not able to break this example with resize, so I think it works fine :)

     

    Example when it fails: I have the same timeline, but the outgoing part will wait for a click event. The timeline is paused until the body receives a click event and then resumed. 

    See the Pen wRJzeb?editors=0010 by anon (@anon) on CodePen

     

     

    Reproduce the issue: Do not click on the pen, wait until the red box reached the x:0,y:0 position. Currently it waits for the click to happen. Resize the window and the red box will jump on the x axis. Click and the animation continues from the right position.

     

  12. Thanks Carl! Well, GSAP is too smart for me :) Sometimes in the past when I animated the same element on multiple timelines (not at once, but premade timelines) I stumbled into this. I didn't know that .set() which added to the start of the timeline is immediateRender:true and when it is added any other position immediateRender:false. I will keep it in my mind, thanks! :) 

    • Like 1
  13. Thanks Mikel, but no. The outgoing part should play when the loop ended. So you click somewhere, notify loop to play until the current repeat ends and then play the outgoing part.

     

    Red box: move from x:100 to x:0 -> spins around ..... click happen ->keeps spinning around until it reaches 360 deg -> move to x: 100

     

    What it does with the current codepen:

    move from x:100 to x:0 -> spins around ..... click happen ->keeps spinning around until it reaches 360 deg
                           -> after first spin -> move to x: 100

     

  14. Thanks Jack for the details. Well, I think my use case is very rare. I have to maintain 3 timeline for every element. Incoming -> Loop -> Outgoing timelines. Loop might take forever and events can stop it and jump to the outgoing timeline. Then also based on a condition, the while timelines are repeated. I think I would be able to make the tree timelines into one if I would add labels where incoming, loop and outgoing part comes. The only problem what it would cause that I'm not sure if I would be able to change the loop part from forever to stop after next turn and continue with outgoing.

     

    I tried to create something like that, but I'm not sure if it is possible with GSAP: 

    See the Pen ZVLJRK?editors=0010 by anon (@anon) on CodePen

     

    Outgoing should wait until the loop timeline ended. Loop timeline will stop repeating if you click on the body. Currently the Outgoing will play after the first.

    Then I tried to pause the main timeline after the first iteration of loop and resume it when the loop timeline completed, but unfortunately it pauses the loop timeline too: 

    See the Pen ZVLJPX by anon (@anon) on CodePen

     

     

  15. Well Jack, here I go again with an another possible bug. :)

     

    Working example: I have a single timeline and one transform origin change at position 0 and one at position 2. Also I have a percent variable to be able to write to console log. When the timeline completes, it will be played again from 0.5 position. So it skips the initial transform origin and percent set at position 0, but in real world it renders it properly. I think this is good behavior.

    See the Pen wRggjY by anon (@anon) on CodePen

     

    Two timelines: Each timeline contains a transform origin change. When the first timeline completes, it starts the second timeline from position 0. When the second timeline completes, it starts the first timeline from position 0.5. The problem here that on second turn the first timelines transform origin and percent change is skipped. 

    See the Pen PXWWdB?editors=0010 by anon (@anon) on CodePen

    Same pen with 2.0.3 beta: 

    See the Pen OrWWaB?editors=0010 by anon (@anon) on CodePen

     

     

    As a temporary fix I placed a duplicated transform origin and percent set at the end of the first timeline. It solved the issue with transform origin, but the percent value still not updated. 

    See the Pen EGZZqZ?editors=0010 by anon (@anon) on CodePen

     

     

     

     

  16. Thanks Jack, will try it when I have some free time :)

     

    I just check the sourcecode diff and there is an encoding issue:

    // allows a node process to exit even if the timeout’s callback hasn't been invoked. Without it, the node process could hang as this function is called every two seconds.

     

×
×
  • Create New...