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

Everything posted by RolandSoos

  1. Thank you for the detailed explanation! That isn't true actually. The transform property contains data for ALL of the following: x, y, z, rotation, rotationX, rotationY, scaleX, scaleY, skewX, skewY, plus it has to handle the transform-origin ... I expressed myself badly, I know GSAP handles all of those. I wanted to tell that in my usage I know every property which is animated and they are set in the same tween, also I know that their pre-tween value is on specs default. This is why I could build a startValue cache with those values to prevent .getComputedStyle(). I know this is not the use case for most of the people and I do understand that it is enough for the most if the timeline is working as expected. Lighthouse has a total blocking time metrics which increases if a processing takes more than 50ms. Google measures this value on mobile (I use 4x cpu slow down for emulation) and building my timelines takes around 250ms. One .fromTo() takes between 8-20ms which is more than one frame in 60fps and I'm animating around 20 elements. It takes around 100ms for the .getTransform(). (Yes, I know it is not too much, I try to catch as many optimization as I can.) Based on https://web.dev/, Google tries to points developers into the right direction to be able to create speedy websites. Key points are to minimalize recalculate style and layout. For example in the past I used .getBoundingClientRect().{width;height} to tell if an element is visible or not. This might result a layout which takes time. So my solution was to store the media queries on the HTML element when the element is not visible -> so I can test the state with Window.matchMedia() without accessing .getBoundingClientRect() or .getComputedStyle() This was really just an example, but I think it shows how to prevent layout calculations. Maybe this will be the future for GSAP too. We could prefill the element's transform/style cache, so GSAP wouldn't need to read those values. If there is no cache or the property does not exists, then usual GSAP behavior. Non working example: https://codepen.io/mm00/pen/gOwzWJq I do understand that this is not the most wanted feature
  2. Yes, this happens only on the first change. But if you have an animation on page load, it is important to be performant and there is no space for not-needed processing. It is good to know that .fromTo() is slower than .to(). I had an assumption that .fromTo() should be faster as GSAP do not need to read anything from the element itself. All the data available locally. The following code contains the suggested gsap.set() before tweening. As you mentioned it will still cause a _parseTransform(). Well, it is really seems unnecessary to parse the previous transform as it will get completely cleared. Does GSAP need this to be able to clearProps the transform property? If I replace the x property with opacity, that will cause a .getComputedStyle() to read the opacity's original value. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CodePen - GSAP Basic fromTo Tween</title> <style> .box { width: 200px; height: 200px; background: red; } </style> </head> <body> <div class="box"></div> <script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-latest-beta.min.js'></script> <script> setTimeout(function () { const el = document.querySelector('.box'); el.style.left = '10px'; // Force recalculate style console.time("Set"); gsap.set(el, {transform: 'none'}); console.timeEnd("Set"); setTimeout(function () { el.style.left = '20px'; // Force recalculate style console.time("FromTo"); gsap.fromTo(el, {x: 0}, {duration: 5, x: 500}); console.timeEnd("FromTo"); }, 1000); }, 1000); </script> </body> </html> Does any of that make sense? I could imagine a tween flag which would force GSAP to skip reading and store the from parameters into the cache or a new method to init the style cache with preset values on an element. I see a flag something like that in the latest-beta which is not in the stable release: e.parseTransform, but it might not related: (g=t._gsap).renderTransform&&!e.parseTransform||We(t,e.parseTransform)
  3. I'm trying to optimize things in my application. I use the tool in Chrome Dev tools -> Performance -> Record What I see that I have a fromTo GSAP animation which animates only one property for example "x". At the start of the animations GSAP reads the previously applied transform probably to maintain other at the original value, but this cause a recalculate style in special circumstances. I would like to tell GSAP that it does not need to read the previously set transforms, just overwrite every transform value with the one set in this tween. Do you have any suggestion what I could use? Here is an example what I used: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CodePen - GSAP Basic fromTo Tween</title> <style> .box { width: 200px; height: 200px; background: red; } </style> </head> <body> <div class="box"></div> <script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-latest-beta.min.js'></script> <script> setTimeout(function () { const el = document.querySelector('.box'); el.style.left = '10px'; // Force recalculate style console.time("FromTo"); gsap.fromTo( el, { x: 0 }, { duration: 5, x: 500 } ); console.timeEnd("FromTo"); }, 2000); </script> </body> </html> This is how it looks in dev tools: In my real world application these recalculations affect the measured performance highly. If I would be able to prevent getComputedStyle() when fromTo tweens are used, I would be able to reduce the time spent with animation initializing about 50%
  4. I think I was able to find the right solution in the forum:
  5. Hi, I would like to migrate my custom GSAP V2 plugins to V3. Do you have documentation about plugin structure for V3? Could you point me in the right direction? I used overwriteProps in V2 to define custom properties. Here is how my plugin looked like for V2: var _div = document.createElement("div"), _filterProp = /Edge\/\d./i.test(navigator.userAgent) ? false : (_div.style.filter !== undefined) ? "filter" : (_div.style.webkitFilter !== undefined) ? "webkitFilter" : false, _filterCSSProp = _filterProp ? (_filterProp == 'filter' ? _filterProp : '-' + _filterProp.replace(/([A-Z])/g, "-$1").toLowerCase()) : ""; GSAP._gsDefine.plugin({ propName: "myblur", API: 2, version: "1.1.0", overwriteProps: ["myblur"], init: function (target, value, tween, index) { if (!_filterProp) { //browser doesn't support filters return true; } if (typeof (value) === "function") { //accommodate function-based values value = value(index, target); } var start = "blur(0px)", end = "blur(" + value + "px)"; this._style = target.style; this._remove = !value; if (start !== end) { this._addTween(target.style, _filterProp, start, end, "myblur"); } return true; }, set: function (ratio) { this._super.setRatio.call(this, ratio); if (ratio === 1 && this._remove) { this._style.removeProperty(_filterCSSProp); } } }); GSAP._gsDefine.plugin({ propName: "myAutoAlpha", API: 2, version: "1.0.1", overwriteProps: ["myAutoAlpha"], init: function (target, value, tween, index) { var start = target.style.opacity || 1; this._target = target; this._style = target.style; this._tween = this._addTween(target.style, "opacity", start, value, "myAutoAlpha"); if (!this._tween) { this._opacity = start; } return true; }, set: function (ratio) { this._super.setRatio.call(this, ratio); if (!this._tween && this._opacity !== this._style.opacity) { this._style.opacity = this._opacity; } if (this._style.opacity === "0") { (this._target.relatedLayer || this._target).setAttribute('data-force-hidden', ''); } else { (this._target.relatedLayer || this._target).removeAttribute('data-force-hidden'); } } });
  6. As a sidenote to this story: All users who had this issue host their site at SiteGround. We contacted with the hosting provider and it turned out that they have an option Site Tools -> External Links Rewrite which rewrites urls in JavaScript files too. Site owners just need to switch it off and everything should work fine. They promised that they will try to fix these false replacements.
  7. Try this: https://codepen.io/mm00/pen/qBWRWKY
  8. @GreenSock, I just checked the latest version (2.1.3) and I have some suggestions. In the CSS plugin: _createSVG = function (type, container, attributes) { var element = _doc.createElementNS("http://www.w3.org/2000/svg", type), reg = /([a-z])([A-Z])/g, p; for (p in attributes) { element.setAttributeNS(null, p.replace(reg, "$1-$2").toLowerCase(), attributes[p]); } container.appendChild(element); return element; }, It should be: _createSVG = function (type, container, attributes) { var element = _createElement(type, "http://www.w3.org/2000/svg"), reg = /([a-z])([A-Z])/g, p; for (p in attributes) { element.setAttributeNS(null, p.replace(reg, "$1-$2").toLowerCase(), attributes[p]); } container.appendChild(element); return element; }, and the _createElement: _createElement = function (type, ns) { var e = _doc.createElementNS ? _doc.createElementNS(ns || "http://www.w3.org/1999/xhtml", type) : _doc.createElement(type); return e.style ? e : _doc.createElement(type); //some environments won't allow access to the element's style when created with a namespace in which case we default to the standard createElement() to work around the issue. Also note that when GSAP is embedded directly inside an SVG file, createElement() won't allow access to the style object in Firefox (see https://greensock.com/forums/topic/20215-problem-using-tweenmax-in-standalone-self-containing-svg-file-err-cannot-set-property-csstext-of-undefined/). }, could be (if we presume, that this was the cause for others) : _createElement = function (type, ns) { return _doc.createElementNS ? _doc.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, 'http'), type) : _doc.createElement(type); //Rarely servers replace the http:// into https:// which is not a proper namespace so we have to fix that. },
  9. Well, I think I found something. Look: https://jsfiddle.net/wk3nyu8m/1/ For me in Chrome and Firefox there is the error in the console. The .style property is undefined (Do you see the same?) Then look at this: https://jsfiddle.net/wk3nyu8m/2/ It works for me just fine. Do you see the difference? https:// vs http:// in the namespace. The proper is http:// but on these servers, the server rewrote the http:// in the JS files to https:// (Might be a hosting provider setting...) Update: Yeah, this was the cause for both of our users. One was a Joomla and two was WordPress and they were nginx server.
  10. Thanks, yeah it is weird. We use this version since a year and it was the third time in this month when we saw this error. (All of them were different WordPress or Joomla site.) Might be a Chrome only bug? If we would be able to find the cause, we might be able to report it to their developers. Several times in the past I experienced new "bugs" when I updated to newer version. Well, they were not bugs exactly, but what worked in the last version might produce error in the next It is not GSAP fault! I think the cause is that GSAP allows you to do a lot of things, even advanced, not documented things and 60fps and our eye might hinder bugs what we should see. When you you are dancing on the border bugs might happen. So, it takes several days of testing before I can safely upgrade GSAP (and under safely, I mean 90%, As I think you know it is really hard to test animations in the async environment (dropping framerate might cause bugs, etc...)). If I push out an update, that affects thousands of website in the first 24 hour, so the my responsibility is very high. Better to be safe than sorry.
  11. We do not use the latest GSAP in our stable software. We use version 2.0.2. Several of our users reported that there is a JavaScript error in our application. The error was: TypeError: Cannot set property 'transformOrigin' of undefined We narrowed the problem to this: var Ja = O.documentElement || {}, Ka = function () { var a, b, c, d = p || /Android/i.test(T) && !_gsScope.chrome; return O.createElementNS && !d && (a = Ia("svg", Ja), b = Ia("rect", a, { width: 100, height: 50, x: 100 }), c = b.getBoundingClientRect().width, b.style[Ea] = "50% 50%", b.style[Ca] = "scaleX(0.5)", d = c === b.getBoundingClientRect().width && !(n && Fa), Ja.removeChild(a)), d }() I was able to find a GitHub ticket which probably related to this issue: https://github.com/greensock/GreenSock-JS/issues/288 @GreenSock So my real question is, that were you able to find why this issue happens on one website and why not on others? Do you know the real cause what goes wrong when you use .createElementNS why the style property is not accessible? If we would know, the we could reproduce the issue on our local test sites and we could verify if the latest GSAP works fine in that environment.
  12. 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
  13. 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.
  14. 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.
  15. 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.
  16. 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
  17. @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?
  18. 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)); } } }
  19. 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
  20. 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.
  21. 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"
  22. 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.
  23. 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?
  24. 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.
  25. 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! :)
×
×
  • Create New...