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. I have a possible workaround, but it would be great to hear you thoughts. When _addTween does not return an object, there is no tween added for that property. So I create a custom object which I use to fake the tween data to the set function. The only thing what I do not like about that is that I need to set the opacity manually in the set function. https://codepen.io/anon/pen/yENWab
  2. Hi, Few months ago I needed a solution for a very special case. I needed to add custom class to the element with custom animated property which I can use everywhere. Related topic: So I ended up with the following plugin, which adds visibility hidden to the element when we reach opacity 0, and removes the visibility property when opacity is not 0. (No, I can not use GSAP inbuilt autoAlpha as that adds visibility visible, but my elements might be hidden with CSS selector) _gsScope._gsDefine.plugin({ propName: "n2AutoAlpha", API: 2, version: "1.0.0", overwriteProps: ["n2AutoAlpha"], init: function (target, value, tween, index) { var start = window.getComputedStyle(target)["opacity"]; if (typeof value === "function") { value = value(index, target); } this._tween = this._addTween(target.style, "opacity", start, value, "n2AutoAlpha"); return true; }, set: function (ratio) { this._super.setRatio.call(this, ratio); if (this._tween) { if (ratio === 0 && this._tween.s === 0) { this._tween.t.visibility = "hidden"; } else if (ratio === 1 && this._tween.s + this._tween.c === 0) { this._tween.t.visibility = "hidden"; } else if (this._tween.t.visibility === "hidden") { this._tween.t.removeProperty("visibility"); } } } }); It works like a charm in most cases. The following scenario is just the simplified version of the production code. The timelines and such are fixed and I can only change the GSAP plugin itself. I have two timelines and both can contain several tween and all tween applies to the same element. When tl1 ends, it starts to play tl2, when tl2 ends, it plays tl1 again. tl1 is an x animation, which also reset the opacity value to the original one. tl2 animates the opacity from 1 to 0 GSAP autoAlpha -> Everything works, expect the animated box do not get hidden when the browser is smaller than 600px. https://codepen.io/anon/pen/JZdzwK Custom plugin -> The visibility status does not change on when tl1 runs from the second time. https://codepen.io/anon/pen/dKorrv When tl2 ends with opacity 0, it sets the visibility to hidden, but somehow the custom plugin skipped in tl1 and visibility hidden is not removed and opacity is not set to 1. Solution would be that the plugin set opacity and adjust the visibility as the core autoAlpha works. How can I reach that in my plugin?
  3. Our software is a visual slider builder. Slider contains several slides. Slides has background image and layers. We have two animated groups at slide level: slide background transitions in the back and layers in the front. Simple example: https://smartslider3.com/free-image-slider/ Here is the real purpose why we need to separate slide backgrounds and layers: https://smartslider3.com/static/ .slide-layers are visibility:hidden while .slide-layer is visibility:visible which allows to right click and save the .slide-background image. (It needed for several user) .slide-layer are animated by the user, so autoAlpha does not work as inherit value for visibility gets the parent hidden value. Playing with z-index is not an option. User can change the z-index of the layers in the editor, I do not want to play with the defined z-index as it might result in overlay with an other layer which is not intended by the user. (Imagine my previous example with a third image which should overlay both the appearing image. ) Here is a very raw example about a slider structure: <div class="canvas" style="width:800px;height:600px;position:relative;"> <div class="slide-background-container"> <div class="slide-background slide-active" data-slide="1"></div> <div class="slide-background" data-slide="2"></div> <div class="slide-background" data-slide="3"></div> </div> <div class="slide-layers" data-slide="1"> <div class="slide-layer"></div> </div> <div class="slide-layers" data-slide="2"> <div class="slide-layer"></div> </div> <div class="slide-layers" data-slide="2"> <div class="slide-layer"></div> </div> </div> <style> .slide-background-container{ z-index:1; position:absolute; width:100%; height:100%; left:0; top:0; } .slide-background{ position:absolute; left: -100%; top: 0; width: 100%; height: 100%; } .slide-background.slide-active{ left: 0; } .slide-layers{ position:absolute; left: -100%; top: 0; width: 100%; height: 100%; z-index: 2; visibility: hidden; } .slide-layers.slide-active{ left: 0; } .slide-layer{ position: absolute; } .slide-layers > *{ visibility: visible; } </style>
  4. User can place several layers on the canvas which overlays each other. They can add timelines on their own which can be triggered with events. For example you have 2 buttons and when you click on the first button, it shows an image. If you click on the second button, it shows a different image at the same place as the first image. But, when you click on the image, each has its own url. If you do not set the opacity:0; image to visibility:hidden, you might open the link of the invisible image. Here is a quick example with the applied visibility:hidden -> https://smartslider3.com/bugs/gsap/2/ As the user can create timelines, it is very hard to implement your original solution with the events as the animated properties are not predestined. There might be opacity change or there might not be. So, I'm always trying to come up something universal
  5. I think I'm getting closer to the final solution And here is an example which use removeProperty for visibility instead of set it to inherit: https://codepen.io/anon/pen/oqoeRE
  6. Based on the official attribute plugin, I made it work. The code adds the current opacity value as an attribute, so I can style when the attribute value is 0. I would be better if I would be able to toggle the attribute 0/1 based on the not-visible/visible state as it might reduce the overhead instead of writing the attribute on every frame.
  7. Your first solution is close enough, so I started to work on that idea as a plugin to GSAP. It creates a custom property: nAutoAlpha which currently adds and removes the class on the parent. The .container should be green when the box visible and grey when it is hidden. That only issue what I have it that when I reset the timeline in "hidden - grey background" state, it does not removes the class on the .container.
  8. Well, that seems overkill solution to do that I have an animation builder and I need something easy to use, but still robust. autoAlpha would be great, if I could switch it to add/remove class instead of the default behaviour. https://smartslider3.com/city/
  9. Here is the bug report for IE if you need it in the future: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/16452345/
  10. I have a special case when my layers sits in a container element which must be visibility:hidden. The elements in the container are visibility:visible, but I need to make them visibility:hidden when the opacity is 0. I tried autoAlpha, but it fails for me as it applies visibility:inherit; which inherits the hidden from the parent. The best would be if I could toggle a class when the element's opacity is 0 or not 0. I'm looking for a solution which works without labels or events and I need to be able to specify progess and such on the timeline. Any suggestion would be apreciated!
  11. Thank you! This fix solved the issue. and I still hate IE
  12. Thanks, but this example is not a real world example. I need the perspective at that place. (I know that there is no 3d transforms in the example what could use it.)
  13. Hey guys! I have encountered an issue in IE Edge version 41. I see strange image clipping during the animation. Do you have any suggestion? Is it a bug in Edge? See the weird result on the attached image.
  14. I'm not telling you that it will cause problems. It will work fine. I use that method in my files too. We should also forget my specific use-case. In my opinion my described method with _gsScope.window is a much more elegant way to access to the properties and services of window as GSAP's code depends on that several places. You shouldn't use _gsScope.navigator, you should use _gsScope.window.navigator as it results more understandable code. It probably be slower, I do not doubt it. Then if you does this change you could suggest the following instead of the variable swapping. I think it is much more cleaner, don't you think? var myScope = {window: window}; (function(){ //Here comes GSAP }).call(myScope); Here is my loader, but I think it is not related with or discussion. It is just an example when _gsScope is not a window. The code might be messy, but it does a great job for me. window.N2Classes is my scope variable n2 holds jQuery and this class loader runs when jQuery is available on the page. window.N2Classes = {}; (function ($, undefined) { "use strict"; var a = {}; window.N2Require = function (name, dependencies, fn) { var deps = []; if (name && a[name] == undefined) { a[name] = $.Deferred(); } if (arguments.length == 2) { fn = arguments[1]; dependencies = undefined; } if (dependencies !== undefined && dependencies) { for (var i = 0; i < dependencies.length; i++) { if (a[dependencies[i]] == undefined) { a[dependencies[i]] = $.Deferred(); } deps.push(a[dependencies[i]]); } } $.when.apply($, deps).done(function () { var args = [$]; if (name) { if (typeof fn == 'function') { N2Classes[name] = fn.apply(N2Classes, args); } else { N2Classes[name] = true; } a[name].resolve(); } else { fn.apply(N2Classes, args); } }); }; for (var i = 0; i < window.n2require.length; i++) { window.N2Require.apply(window, window.n2require[i]); } })(n2); In my application JS files made in build process and I have several different JS files which holds classes for specific areas. backend.min.js frontend.min.js gsap.min.js etc... Every file starts with, so if the module loader is not loaded yet, the resources added to a global array for later evaluation: window.n2require = window.n2require || []; window.N2Require = window.N2Require || function() { window.n2require.push(arguments) }; And here is a class definition: N2Require('MyClass', function ($, undefined) { function MyClass(){}; return MyClass; }); Class definition with dependecy: N2Require('Hello', ['MyClass', 'MyOtherClass'], function ($, undefined) { function Hello(){}; return Hello; }); Then I can use this class as: new N2Classes.MyClass(); //Or if there is chance that the gived class is not loaded yet. //For example when you start the application as inline script, you can not be sure that resources are loaded as async or not N2Require(0,['MyClass' /* dependencies */], function(){ // It runs when MyClass available new N2Classes.MyClass(); });
  15. My module loader is nothing special, it just does what I told, creates a new scope for my stuff and loads there the required things. Custom jQuery, GSAP etc... But, my enviroment is special. We are creating WordPress plugins and we have to make sure that our thing runs in every different environment. Async, not async, other plugin combines every JS files put them into the head with/without async, put to the end of the body, loads it with AJAX and just eval the JS codes. I'm sure that I can use your solution with the variable exchange.You won't be able to convince me that this is the BEST solution, but you convinced me that this is the official solution. I know that people want to use GSAP even in CLI environment where window is not available only global (like my scope, but I have window too). So you can even look for window that it is optional and you should prepare the code in that way. What I suggest could work and you would be able to know that you are in a non-window-ed context. _gsScope.window = _gsScope.window || false; Then you can use _gsScope.window when you need window and for example you can skip the runtime of CSSPlugin when _gsScope.window is false. I think in theory it should work. Also I accept if you want to close the discussion on topic as this is your code and who am I to push anything
  16. Ok, I understand. I take the risk. Hopefully this topic will help others who encounter the same issue. Another idea. If you do not mind I would like to continue the converstation, maybe we will figure out something good for GSAP window.window holds the window object. Why don't you use _gsScope.window.navigator and such instead of _gsScope.navigator Then we can use: var obj = {}; (function ($, undefined) { this.window = window; // Here comes GSAP }).call(obj); If _gsScope.window is undefined, you could throw an error for the developers.
  17. I have a custom module loader which creates a custom scope for the modules. I load GSAP into this module loader, so this is why this issue popped up. (It worked fine with with an older version of GSAP) If GSAP really needs window object for specific tasks then it should use directly, I think: _gsScope.document => window.document _gsScope.navigator => window.navigator _gsScope.console => window.console
  18. I do not see why do you think that playing with temporary variables is a good solution instead of creating a new scope: I went through the source code and the following needed to make GSAP to work as expected in custom scope: _gsScope.document _gsScope.navigator _gsScope.console
  19. Thank you, you gave me an idea I create a custom scope for GSAP to prevent conflicts. var myScope = {}; (function(){ // Here comes the source code of GSAP }).call(myScope); Then GSAP creates _gsScope with the following definition: var _gsScope = (typeof(module) !== "undefined" && module.exports && typeof(global) !== "undefined") ? global : this || window; So the _gsScope variable will be equal with myScope. Then GSAP tries to find the navigator in the _gsScope which is not there as it assumes it is a Window object: _agent = (_gsScope.navigator || {}).userAgent || "", As _agent is empty string, GSAP is unable to find which browser it is and it assumes that opacity not supported, then it tries to use filter as opacity not supported Solution: Define navigator in the custom scope: myScope.navigator = window.navigator; Jack: Do you know any other variable what GSAP presume in _gsScope?
  20. Hi! After I updated my application to the latest GASP version I run into strange errors. I'm pretty sure that GSAP is fine and the issue is with my application, but I'm unable to find the cause. Maybe the following error message will ring a bell and you will be able to tell me where to look. Error message: TypeError: c.removeAttribute is not a function at S.CSSPropTween.Ua [as setRatio] And here are a screenshot of the clues from the call stack: https://i.imgur.com/FI6SDHg.png I tried to recreate the issue on CodePen, but it does not happen there with the same parameter to the timeline's fromTo method. Here you can the error in real environment: https://smartslider3.com/bugs/gsap/1/index.html
  21. Hi, I have this example located: https://smartslider3.com/video-slider/#four When you switch slides - in Safari 11.0.1 the animated slides start the flickering until the animation ends. Do you see any issue on the applied transforms or is it a Safari bug which I should report? I will try to create a Codepen on Monday, but currently I do not have the time for that. What fixed the example: z axis 1px to the slides or rotationX or rotationY 1 deg
  22. Noticed a bug in your code, so here is a fixed version. In your code the _filterCSSProp variable was "webkit-filter", but it should be "-webkit-filter". (function () { var _div = document.createElement("div"), _filterProp = /Edge\/\d./i.test(navigator.userAgent) ? false : (_div.style.webkitFilter !== undefined) ? "webkitFilter" : (_div.style.filter !== undefined) ? "filter" : false, _filterCSSProp = _filterProp ? (_filterProp == 'filter' ? _filterProp : '-' + _filterProp.replace(/([A-Z])/g, "-$1").toLowerCase()) : ""; _gsScope._gsDefine.plugin({ propName: "n2blur", API: 2, version: "1.1.0", overwriteProps: ["n2blur"], 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 = window.getComputedStyle(target)[_filterProp], end = "blur(" + value + "px)"; if (start === "none") { start = "blur(0px)"; } this._style = target.style; this._remove = !value; this._addTween(target.style, _filterProp, start, end, "n2blur"); return true; }, set: function (ratio) { this._super.setRatio.call(this, ratio); console.trace(_filterProp, ratio, this._remove); //ratio is typically 1 when tween is done. if (ratio === 1 && this._remove) { this._style.removeProperty(_filterCSSProp); } } }); })();
  23. Thank you Jack, it is good to see how extendable your plugin system. It would be great if it would have documentation, maybe in that case I would be able to write these things myself BTW.: I'm not sure why, but I can not fork your Codepens as the Fork button is not there. Maybe it is a setting on your end which makes it harder to do changes to your codepens.
×
×
  • Create New...