Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by Ninili

  1. Thank you Blake until then I ignore the warnings. Also working with the PIXIJS definitions looks quirky. The definitions look fine but I wonder if PhpStorm can handle multiple inheritances, at least with pure Javascript. It always tells me that "X is not assignable to parameter of type Y", but X actually inherited from Y and should be allowed there ... and a lot more ... But I'm still learning PHPStorm and having one eureka moment after the other. But that's an entirely different story I've been working with sublime text and flashDevelop for AS3 for a long time. Now PHP/WebStorm is quite an epiphany for me
  2. Now with the new TypeScript definitions ( "GSAP" instead of "greensock") we have a problem with pure Javascript: The definitions are all for the namespace gsap, like if you type gsap.TweenMax.to(...); syntax highlighting and type checking works. I had to go to the DefinitelyTyped github page to finally find out that all GSAP types are inside a "gsap" namespace. But the code doesn't work with this namespace, because in the Javascript CDN, it is not defined. How can I get around this? I have PHPStorm for some weeks, so I don't know the super-secret settings yet that could make this work! Anyone having success using GSAP type checking in a current version of (PHP|Web)Storm?! I could imagine like a directive to tell the editor "pretend that all inside the gsap definition is global"
  3. Another strange oservation: There seem to be cases when inlining JPG images as base64 in HTML yields a smaller data size than using actual image files. In this case, the huffman codes are NOT optimized. Maybe that is the cause and the gzip "finishes" what the un-optimized Huffman didn't get.
  4. One thing I really like is the "copy Data-URI" option This is great for testing on codepen. Although I have a pro account there and could upload every asset, it's quite a mess when you have like 25 files, all by the name "logo.jpg" or "product.png". Okay, having BASE64 in the code is ALSO a big mess, but after all a quick and easy method to test stuff. I once wrote my own "transparent JPG" compressor which used a very similar approach like Christophs: ...but it doesn't have all the controls for all the detailed aspects of compression, because it uses built-in Browser image compression. So there's always a lack of optimized Huffman codes, selective quality, separate brightness and color compression, color subsampling, quantizers and so on. You can even sometimes see it in the base64 output, when there is lots of repitition, that's where the entropy is way too low for what you would consider a "good compression". I used this technique about 2 years ago when I had to animage quite big transparent graphics that would be over 300k even with tinyPNG. So going "transparent JPG" was the only way to get it done with sane image sizes. But when I discovered all the details about JPG and that the browser doesn't perform a "huffman optimization" which always left some compression potential untouched made me ... SAD - but now there's Christophs tool that does exactly what I wanted, with almost everything I missed. (almost meaning stuff like - using 8-color PNG data for masking for sharp edges or even traced SVG paths, separate control for Mask quality, etc.) But I think Christoph is already working on all that in secret. Beneath Canvas, my tool also offers various SVG techniques to use the image mask. But beware, CANVAS will render faster, because the CANVAS will be handled like any other image or bitmap when animated. The SVG will introduce too much re-calculating, especially when doing transforms. Except you put that in a html container having the style "will-change: transform", then the SVG itself will get cached as an image and you can transform the container almost as fast as a CANVAS element. Right now I'm on something I call a "compression frenzy" and try to drain out every last bit and it goes as far as re-ordering parts of the HTML, using JSUglify, CSSmin, HTML minifiers, https://jakearchibald.github.io/svgomg/ , manual editing and optimizing of vector data, including re-nesting of transformations, using lots of symbols, etc. AND of course http://compress-or-die.com/ which is something like a dreamland for a compression nerd like me Bzw. the attached image shows what you get - at least as BASE64 - when your JPG is NOT huffman-optimized (like Christophs tool does). This should convince anyone who is compression-aware
  5. Thanks Jack! I wonder if this could be run as a "CustomEase" module, also performance-wise. I noticed that there is a function that converts Eases into SVG paths that is also used in the Ease Visualizer. And those are optimized for runtime performance. The way I did the blending, there are at most 4 tweening and easing processes running at the same time: 1. the main timeline that contains the "gradient" 2. the source easing function 3. the destination easing function 4. The "how to blend" easing function ... one could even ease the main timeline to enable some funky time-distortion... as a fourth parameter. So this isn't really as fast as it could be. Although GSAP is quite fast doing tweens, any performance optimization would be helpful The only thing is that the whole syntax for javascript modules sometimes boggles my mind. I usually think of myself of a good JS programmer but when looking at some modules that were made to "work properly within the system" I think "I know nothing."
  6. Sometimes I thought it would be nice to blend easings from one type to another while time goes by. And then it would be cool to have as much control over how the blending is done as possible. So I created a showcase, not yet a real easing plugin. I don't know how useful it might be to GSAP users, but there are some applications like: Going from linear to an elastic ending or from rough ease to clean ease. This might be especially interesting for long tweens maybe. The syntax is: mixTween(eases,ratios,blendTweens) // example: mixTween( [Linear.easeNone,Elastic.easeOut], [0.2,0.4], [Power2.easeInOut] ); The first array, eases, can be an array of at least 2, but as many eases you like. The second array, ratios will define the time-points of the eases. In the above example, the tween will stay linear until 20% of the tween. Then it starts blending to Elastic.EaseOut until 40% of the tween and stays EaseOut until the end. This parameter can be ommitted. If ommitted, evenly spaced values are calculated. The third array defines HOW the blending should be made. Just linear blending (default if ommited) won't always look best. So you can use any easing function to define how fast one ease blends into the other. In the example above, the easing is smoothly transitioned by a Power2.easeInOut, so there won't be any "sharp" change when the blending begins. You might get a good example of what this does by looking at the codepen I left here I could imagine this to be implemented in a similar way to CustomEase. like BlendedEase(...)
  7. Some years ago I've been using Adobe Edge, but when it got released, the authoring program itself ran so damn slow on my computer, I just couldn't use it at all anymore (refresh rates of 1 fps). Most of the time, I did everything by hand, using CSS3 animations or wherever allowed GSAP or portions of it. There were some "old-fashioned" customers who insisted on the old 40kb size (incuding _everything_) and still there were ways to do it. I rendered texts to SVG outlines to avoid loading font files or having jagged bitmap-texts. But at the moment I find that Adobe Animate (formerly Flash) has reached a point where it is again the tool of my choice for html5 banners and maybe even more! I know the createjs API very well now and can handle it like Flash before. It is even a bit more fun. The Javascript acutaly let's you do even more than Actionscript (even though I think AS3 is the most beautiful language there is ... maybe right after Haxe). For example I wanted to let the whole banner Shake. GSAP already included (via DoubleClick CDN), I could do this on a frame: TweenMax.from('canvas',1,{y:-5,ease:Elastic.easeOut}); This would let the Canvas-Element make a spring-like motion. So you have control over the container itself and so much more. You can create template HTML files where everything is setup for banner creation, like clickTag management, AdHelper (which helps stopping banners after 30secs or enables retina-friendly display) or the google exit Api. Here you can download an AD template for Adobe Animate which already includes GSAP: https://blogs.adobe.com/creativecloud/creating-html5-ads-with-animate-cc-google-html5-ad-templates/ I just had much fun creating the first banner campaign with Adobe Animate again I've been using Flash for 16 years now and am glad that this wonderful authoring tool is still alive and kicking and generating better and better output. I'm wondering if they'll also include pixi.js as an option for rendering content? Of course it's (still) much too big for banner ads, but otherwise great for games or bigger rich applications. Still one thing to consider is: the createjs/Adobe Animate option has one drawback: The constant updating of the stage on every tick. This forces createjs to re-draw every element on the stage on each frame. The engine still doesn't know which elements are moving and which are not, so there is still much room for optimization. If you work with DOM elements instead of canvas, the browser can control which areas need to be updated or not and may not use as much CPU resources.
  8. Using the modifiers plugin I often thought about how cool it would be to have access to more than one variable at the same time. How could this be achieved in a way that would be simple to understand? I think this syntax would be cool: TweenMax.to($obj,5,{ modifiers:{ "x,y,rotation":function(x,y,rotation,target) { return { // Doesn't make much sense, but ... the possibilities! x:rotation > 90 ? x : -x, y:y+Math.random()*50, rotation:rotation % 90 + x*y } } } }); The modifier function would be automatically passed the variables defined in the key (x,y,rotation in this case) and then the target object and return them as an object. And then, added to that, bind "this" in the modifier-function to the TweenLite-Object so you can access stuff like this.progress() But otherwise... isn't it a little bit overkill? And who would really need something like this?
  9. Thanks for all the responses! What I was thinking about was actually order of operations, thanks for the links, Jonathan. I searched a lot in the forums, but it was rather hard to find the right terms to describe what I was looking for. I'll then stick for native translates or nested containers for more complex transforms. It's actually very rare that I need any other kind of Transform other than those GSAP already provide.
  10. Is there any way to have multiple transformes chained in a distinct order with GSAP? With SVG you can write all transforms in the "transform" attribute and they will be executed in the reverse order, like: <circle r="20" transform="scale(2) rotate(20) translate(-20,0)"/> this will move the circle 20 units to the left, rotate it by 20° (having it's origin still at 0,0) and then scale it by 2. a different order of transforms will yield a different result. I wonder if it would be possible to be able to chain transforms like that in GSAP, but with any element, like this: TweenMax.to('#element', 2, { opacity:1, chainedTransform: [{ scale: 1.5 }, { x: -100 }, { rotate: 50, transformOrigin:'50% 20%' }, { scale 1 / 1.5 }, { y: 100, y:-50 }, { matrix: [0.8, 0.4, -0.4, 0.8, 32, -32] }, { skewX:20, transformOrigin:'0 0' } ] }); This way you could do more complex animations and would likely be most suitable for "fromTo" Tweens.
  11. Ninili

    Circular motion

    Now a client asked for an animation where some items, arranged on a circle, should be rotated around while, of course, staying upright, because underneath each icon, there was a description. I didn't want to re-write the whole SVG to use my old function, I wanted to rotate alle the icons just as they were, from their initial position in a rotating manner. This is how it all worked out, again usign the wonderful cycle routine: http://codepen.io/anon/pen/BKQJor ...and using some pen and paper
  12. Ninili

    Circular motion

    Thank you for the nice feedback Yes, IE behaves differently, again! IE seems to shorten translate-attributes in SVG by ommiting the y coordinate if it's value is 0, so "translate(x 0)" becomes "translate(x)". Setting the second parameter of translate to anything other than 0 solves the problem. I have updated the codepen to use "translate(-radius, 0.1)" to circumvent that not-so-funny behaviour of IE.
  13. Ninili

    Circular motion

    Actually, with SVG it is even much easier than wrapping an element. You can use the "transform" attribute of SVG to apply multiple Transforms. The new GSAP 18 can easily tween all parameters in those transform statements and also offers the cylce attribute for the stagger-functions. Imagine this is the SVG object, just 4 small black boxes placed at the center. <svg width="300" height="300"> <g transform="translate(125,125)"> <rect width="50" height="50"/> <rect width="50" height="50"/> <rect width="50" height="50"/> <rect width="50" height="50"/> </g> </svg> This code will let all boxes circulate like on a ferris wheel, rotating with the radius of 100 around the center they were placed at: var radius = 100; TweenMax.staggerFromTo('rect',4,{ cycle: { attr:function(i) { var r = i*90; return { transform:'rotate('+r+') translate('+radius+',0) rotate('+(-r)+')' } } } },{ cycle: { attr:function(i) { var r = i*90+360; return { transform:'rotate('+r+') translate('+radius+',0) rotate('+(-r)+')' } } }, ease:Linear.easeNone, repeat:-1 }); The cycle attribute is used to shift the rotation 90° further for each box. Here's a codepen: http://codepen.io/anon/pen/ZWOZBb
  14. I just replaced the first MorphSVG plugin with the new version (0.8.1) and my morphed animations failed with the error "cannot read property 'toUpperCase' of undefined". When I debugged this in the non-minimized version, I found that the problem might be arrays of jQuery-Elements: I think this is because the jQuery element is put into an array in this line of code: (MorphSVGPlugin.js, _parseShape function, Line 847) e = isString ? TweenLite.selector(shape) : [shape] Then later, it is pulled out of this array: (MorphSVGPlugin.js, _parseShape function, Line 848) if (e && e[0]) { e = e[0]; ...but then it is still the jQuery Object I passed, which doesn't have the "nodeName" member required later in the code. This worked before in the older version of the MorphSVG plugin.