Jump to content

RolandSoos last won the day on January 18

RolandSoos had the most liked content!

RolandSoos

BusinessGreen
  • Content Count

    162
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by RolandSoos

  1. Thanks @GreenSock! And there is no chance that this._propLookup is array and GSAP reaches ._kill with that array right? I assume that this._propLookup was originally an array, which holds a lookup table for every animated elements in that tween. So if the same tween contains multiple path, the _proplookup looks like: [0: {... lookup table for element 1...}, 1: {... lookup table for element 2...}, ...], but there is an optimization when the tween contains only one element, then the array become object and holds the lookup table only for that element: {... lookup table for element 1...}. So probably every other usage of the lookup table gets only the object for a single element. Which means there would be no issue Ps.: For code maintaining purpose, maybe it would be better to make a single element to behave like there are multiple targets. That would free up several if statements, but on the other side you would get some loops if there is only one element. But it would help to reduce the codebase. I tried to simulate that situation, but there were no error with the latest beta version, so it seems fine with multiple targets too: https://codepen.io/mm00/pen/KLyLLv?editors=0010
  2. Thanks @Dipscom, well, Joomla is not really related. The only thing which is related the Mootools changes the prototype of the Array. So placing the following before GSAP should be able to trigger this behavior. Array.prototype.test = function(){ } Well, finally I was able to reproduce it in Codepen https://codepen.io/mm00/pen/zQPBwQ?editors=0010 When the invalidate() call removed, the example works as expected. I need to call the invalidate() as in my example that timeline reinserted into new timelines all the time. @GreenSock: I changed the following in TweenLite: this._propLookup = []; To: this._propLookup = {}; and this._propLookup = (this._targets) ? {} : []; To: this._propLookup = {}; Everything seems to works normally. Also I tracked and this._propLookup only used as array when you loop through this._targets array, in those loops you use the this._targets.length, so the this._propLookup can be accessed in the object just fine.
  3. Hi! Sadly, Joomla users still use Mootools 1.4.5 and there is a compatibility issue with GSAP. Mootools add functions to the prototype of the array, for example: Array.prototype.test = function(){ } var myArray = [1]; for(var k in myArray){ console.log(k) } /* Output: - 0 - test To get the proper output: */ for(var k in myArray){ if(myArray.hasOwnProperty(k)){ console.log(k) } } /* Output: - 0 */ So I was not able to reproduce this issue in Codepen as there should be something in my system which triggers the error, but here are the clues. The vars variable hold the array which looped through with for ... in. Probably vars should be object and you can safely use for ... in. Call stack: https://i.imgur.com/UwMyhlG.png ._kill https://i.imgur.com/p6zEyfg.png ._applyOverwrite: https://i.imgur.com/CXRmShX.png .initProps: https://i.imgur.com/OZakdII.png ._init: https://i.imgur.com/hnTSmnt.png vars holds the value of the this._propLookup which inited as array in .invalidate() and in TweenLite constructor.
  4. I think this is what you need. Just move the container to the direction what you want and the inner part to the opposite direction with the same amount.
  5. One more interesting fact. Math.round(v.toFixed(1)) is very slow compared to: Math.round(v) But The following gives the same result as Math.round(v.toFixed(1)) and runs as fast as Math.round() Math.round(((v * 10) | 0) / 10) https://jsbench.me/cajtgubfls/1
  6. @GreenSock one extra question if you do not mind. What do you think why this rounding issue only happened with the drag interaction (Setting progress multiple time on a paused timeline and then play) and does not ever happened with with simple play of the timeline? Is there any rare correlation what you can think of? Is it possible for example that click event happens exactly at a tick while mousemove and the mouseup not snapped to the tick?
  7. Finally the solution With modifiers plugin, I was able to achieve the desired result with: { x: 0, modifiers: { x: function (x) { return Math.round(x.toFixed(1)); } } }
  8. Yeah, it would be worst by turning roundProps off. There would be lines between every boxes. (Probably I had that floating point conversation few months ago which you remember: https://greensock.com/forums/topic/19625-addpause-the-behavior-is-unexpected/?tab=comments#comment-91640) Here my further findings. 1-3 boxes pt.c = -1200 v = 0.18125000000000002 pt.s = 1200 = 982.5 rounded -> 983 3-6 boxes pt.c = -1200 v = 0.18125000000000002 pt.s = 0 = -217.50000000000003 rounded -> -218
  9. Well, It happens on my FHD and also on the WQHD monitor. I was not able to test it on HiDPI. My computer is pretty fast, latest I7 and there is no FPS drop when it happens. I wouldn't think it is sub pixel misalignment as I use GSAP roundProps, so the x values always integers. I created a timestamp for the performance record which displays the X values get written by GSAP: I think the problem lies here. The first three bar is the X value for the first 3 box and the last 3 bar is for the last 3 box. The sum of any first box and any last box should give 1200px in every frame. In frame before the frame with the vertical line, the math does not work. GSAP calculates 829 and 372 which gives 1201 so there was a miscalculation and this cause the gap between those two.
  10. Thanks @Dipscom! Yeah, I'm sorry I know it is really hard to tell anything with that complex code. Yes, I only adjust the .progress() of the timeline. Also the strange thing, it happens few frame after you release the mouse button. Do you feel too that it happens a little bit later? Also Something there is multiple vertical lines as the timeline plays. I was able to catch the issue with Chrome profiler and the vertical line is visible on the screenshot what Chrome made. The vertical line appears in this example three mousemove events later than the mouse button released. The Javascript happens around that line is a GSAP call "wake"
  11. Hi! I'm sorry, but I was unable to reproduce the following issue in CodePen, but maybe you could give me an idea what is going on. The issue happens in Chrome, Edge and also Firefox, so it is probably not a browser bug. Also this rendering issue happens on the first animation only and not all the time. Reproduce the issue: Open https://smartslider3.com/bugs/chrome/carousel1/ Mouse down on one of the blue box and drag your mouse to the left and then release it. While you drag your mouse, my code adjust the progress of the timeline and when you release the mouse, the timeline will .play() The vertical lines appears after you release the mouse and the timeline is playing between the c and d boxes Refresh the browser to try it again The artifact visible on the following video: https://www.youtube.com/watch?v=0f6OU16NlqM 0:13 0:18 0:27 0:49 0:50 The issue is not appear when: The animation started with the click on the right arrow If the animation plays 2nd, 3rd etc... The issue do not appear if you drag to the other direction Interesting facts: The drag use the same timeline what the arrow click does. The only difference that when you start a drag: the timeline paused until and the progress adjusted manually and when you release the pointer the timeline plays. The pane size is 1200px, the box size is 400px and the boxes moved with x: -1200px, so there should not be rounding issues I use round props plugin roundProps: "x", so the x values on all boxes should be fine all the time. It happens only between the c and d boxes I tried to reproduce it on Codepen with a basic structure, but nothing like that happens: https://codepen.io/mm00/pen/aMjKOO Ps.: Setting the background of the container to blue is not an option.
  12. Well, it seems like the example which does not have the "IE fix" works as expected in Edge 18. Do you know what could be the oldest Edge version where it got fixed?
  13. Hi Guys! Well, in the past I got a suggestion to use transform:perspective(2000px) in IE when I need 3D perspective. Now I checked one of my example in Edge 44 - EdgeHTML 18 and there is something wrong with the perspective. The gaps between the three image should be equal, but in Edge the right gap is smaller and it is related to the perspective. Do you have any suggestion? The example works as expected in Chrome, Firefox and even IE11.
  14. Yeah, my issues solved. And I'm pretty sure it would not be a good idea to change the current implementation. It was just very time consuming and frustrating to understand what happens and why. As you saw in the past weeks I had several edge cases and sometimes I was not sure what is the problem. There was code failures on my end or I had misconception or GSAP had a bug and it was really hard to say which was true (And it takes a lot of time to simplify a complex problem into a simple pen.) I think ALL my issues solved (knock knock) and I hope nothing comes up in the next weeks Thank you for you and your team for the quick and accurate help! I really appreciate it! :)
  15. Yeah, I think I still have confusion with immediateRender. The following two examples shows where my confusion comes: #1 opacity gets the 0 value at create, but on replay it waits until the set position reached. nestedTl.set("#div2", { opacity: 0, immediateRender: true }); https://codepen.io/mm00/pen/MZMKdK?editors=0010 #2 opacity gets the 0 value on the main timeline start for every replay too TweenLite.set("#div2", { opacity: 0 }); nestedTl.set("#div2", { opacity: 0, immediateRender: false }); https://codepen.io/mm00/pen/KJavXQ?editors=0010 I had the wrong conception for imediateRender. As when the immediateRender is true it renders the properties instantly. Like a simple .set() would do. So I used to spare a call with immediateRender:true. But when the timeline plays again, it does not behave like when I set the values in a different call (#2). Probably my confusion with immediateRender comes from the fact, that the immediateRender:true on from* based tweens work like I need and .set with immediateRender:true differs. #3 opacity gets the 0 value on the main timeline start for every replay too nestedTl.fromTo("#div2", 0.0001, {opacity:0}, { opacity: 0, immediateRender: true }); https://codepen.io/mm00/pen/BMpdGw?editors=0010 So if I want proper result for my scenario, I have to stick with the #2 solution and that will give good result combined with invalidate() like in this topic: var t = timeline.time(); //store the current time in a variable timeline.time(0); // seek back to position 0 which allow invalidate to read the proper values timeline.invalidate().time(t); //set it back to that time immediately. --------------------------------------------------------------- Sorry, I don't really understand the question. Can you clarify a bit? I want to help - I'm just fuzzy about what you're asking 🤨 This question was related to: Here is an example from* based example: https://codepen.io/mm00/pen/BMpdGw?editors=0010 You told that immediateRender in this example does not mean that the start value will be properly rendered when the parent timeline rewinds to position 0. But I do not see how your thought affect this example's rewind. Everytime I rewind the parent, Hello World gets opacity 0 no matter what.
  16. @GreenSock Thanks, seems fine Are you sure that there is no chance that it results in error if the timeline is not in paused state (playing currently) and .paused(false); gets called?
  17. Well done @GreenSock! It seems like the fix eliminated the issue. BTW, What do you think what was the reason that it happened for you and for @Dipscom less frequently? In Win 10 Latest Chrome and MacBook Air latest Safari, I was able to reproduce with 30% chance in 20 seconds.
  18. Thanks @GreenSock! Well, fixing this issue is not important for me, I will fix double fires on my own without touching the source of GSAP. I just needed to know the reason of this bug to be able to produce proper solution for my usecase.
  19. Well, I got my first issue related this bug, so I debug deeper. Values are from the Chrome debugger. 4.624-0.001 = 4.622999999999999 // Note: Lost the precision. In a perfect world, it should be 4.623 4.622999999999999-4.6129999999999995 = 0.009999999999999787 0.009999999999999787-0.01 = -2.1337098754514727e-16 and then GSAP end up thinking its a reverseComplete I tried the following code and solved this issue: Line 1766 var renderTime = time - tween._startTime; if(renderTime < _tinyNum && renderTime > -_tinyNum){ renderTime = 0 } if (!tween._reversed) { tween.render(renderTime * tween._timeScale, suppressEvents, force); } else { tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - (renderTime * tween._timeScale), suppressEvents, force); } In my real world scenario this bug caused trouble. I had an addPause callback at some position. To prevent another issue I mentioned in the forum earlier, my addPause callback seeks back the timeline to the real position: var pausePosition; timeline.addPause(function(){ timeline.seek(pausePosition); }); pausePosition = timeline.recent().startTime(); It pauses the timeline properly. Then in the future, when I play this timeline, because of this rounding issue the addPause callback gets fired again as rounding messed up the time and GSAP indentifies that we are in the past and calls the pause again. (It is rare, but happened several times.) Update #1: This float problem is not only related to my small position (0.01s) what I use in my examples. The same can happen with real world values: https://codepen.io/mm00/pen/jdWVGL?editors=0011
  20. There might be one other change needed, but I'm not sure. Checking if the value not equal with the current _paused property. Timeline p.paused = function (value) { if (arguments.length && !value && value != this._paused) { //if there's a pause directly at the spot from where we're unpausing, skip it. var tween = this._first, time = this._time; while (tween) { if (tween._startTime === time && tween.data === "isPause") { tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire. } tween = tween._next; } } return Animation.prototype.paused.apply(this, arguments); };
  21. While debugging my code I used the timeline.paused() method without parameters to get if the timeline paused or not. I have strange results when the playhead was paused at the exact position of an addPause callback, so I checked GSAP source code and I think I found the cause. Timeline p.paused = function (value) { if (!value) { //if there's a pause directly at the spot from where we're unpausing, skip it. var tween = this._first, time = this._time; while (tween) { if (tween._startTime === time && tween.data === "isPause") { tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire. } tween = tween._next; } } return Animation.prototype.paused.apply(this, arguments); }; Animation p.paused = function (value) { if (!arguments.length) { return this._paused; } var tl = this._timeline, raw, elapsed; if (value != this._paused) if (tl) { if (!_tickerActive && !value) { _ticker.wake(); } raw = tl.rawTime(); var raw2 = raw; elapsed = raw - this._pauseTime; if (!value && tl.smoothChildTiming) { if (this._totalDuration === 3.203) { //console.log('elapsed', raw, this._pauseTime); console.error('new start time', this._startTime, 'Ez OK:',this._pauseTime); } this._startTime += elapsed; this._uncache(false); } this._pauseTime = value ? raw : null; this._paused = value; this._active = this.isActive(); if (!value && elapsed !== 0 && this._initted && this.duration()) { raw = tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale; if (this._totalDuration === 3.203) { console.log('start1', this._startTime, 'ticker time', raw2, 'Raw = _totalTime', raw,); window.abcd = true; } this.render(raw, (raw === this._totalTime), true); //in case the target's properties changed via some other tween or manual update by the user, we should force a render. } } if (this._gc && !value) { this._enabled(true, false); } return this; }; When I call timeline.paused() without arguments, the value will be undefined, which evaluates as false, so it goes into the if statement. Your comment says: //if there's a pause directly at the spot from where we're unpausing, skip it. So based on the comment, it should run when it is called with value:false. So probably it should be: Timeline p.paused = function (value) { if (arguments.length && !value) { //if there's a pause directly at the spot from where we're unpausing, skip it. var tween = this._first, time = this._time; while (tween) { if (tween._startTime === time && tween.data === "isPause") { tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire. } tween = tween._next; } } return Animation.prototype.paused.apply(this, arguments); }; Ps.: Sorry, I currently do not have time to create a CodePen which illustrates the bug I had.
  22. @GreenSock, I have a problem related to this solution. I know we talked about tweens in the original conversation, but since then I started to invalidate the whole timeline. When I have a .set() on the invalidated timeline, the original value will be lost if the timeline gets invalidated after the .set() happened. Example: https://codepen.io/mm00/pen/gqaEze?editors=0010 The red box will stay visibility:hidden after the invalidate happens at second turn. I know the logic behind this. Invalidate will force GSAP to read the values again, like it would for a .to() tween. So when the invalidate happens GSAP reads visibility: hidden and it will set that when the timeline restarts. So, as I know the cause, probably I can solve that. I just need to seek back the timeline to the starting position and then invalidate the timeline. var t = timeline.time(); //store the current time in a variable timeline.time(0); // seek back to position 0 which allow invalidate to read the proper values timeline.invalidate().time(t); //set it back to that time immediately. Updated codepen: https://codepen.io/mm00/pen/yZYrRg?editors=0010 So the question: what do you think, is it fail safe?
  23. Yes, it seems like the fix solved the issue. Thank you! Old: New: I'm not sure if you are interested in another hard to noticeable bug to fix in addPause There might happen that a condition already met when I reach addPause. First though, simply tl.play() in the addPause callback and I will be fine. But, as the addPause happens earlier than tweens and the pause cancels the rendering of that frame. It results if you instantly resume the tween, you will notice a skipped frame if you watch closely. On my example watch the middle of the animation. Hard to notice but you will see the result of the one missing frame: https://codepen.io/mm00/pen/xMKgMm?editors=0011 I know, I could use removePause, but that would take too much effort as I would need to place that back on the onComplete event of the timeline also I need that callback. As a temporary solution I get the tween created with addPause and I play with the data property: // If I allow pause tween['data'] = 'isPause'; // If I want to skip the pause tween['data'] = '';
  24. https://codepen.io/mm00/pen/MZMKdK?editors=0010 This is the example what I needed to solve with a very short duration fromTo tween instead of the .set(). I'm not sure how it would be possible to solve if the parent timeline is not accessible for the code which creates the nested timeline. Also I'm curious about the exception what you described. How would an example look like when a from* based tween with immediateRender: true does not render its values after the first render?
  25. Thanks @GreenShock! I will be able to check this on Monday.