Do browsers stil animate invisible content? - performance

When a page contains CSS3 animations that are below the fold, or that get hidden as the user scrolls down, should you apply a class using Javascript to stop the animation, or do browsers not animate invisible elements?

Even though browsers will not draw elements that are outside of the viewport I'm still pretty sure they will continue to update the css properties as determined by the css animation even when the element is not visible.
This is needed in order to be able to listen for animation events, or to be able to read the value of an animated css property at any given time.
So, in theory you might improve performance by removing the css class that animates the element, but unless you have very complex animations or animate hundreds of elements I wouldn't really worry about it.
"Drawing" is the most expensive part usually, especially if you're animating things such as colors, which causes a repaint. However, if you're animating a translation or rotation using a css transform the browser usually doesn't need to do a repaint each frame. Instead it can just paint the element once and send it to the GPU as a texure and let the GPU translate or rotate it each frame, which is crazy fast since it's all hardware accelerated.

Related

UI Elements not affected by light

I'm trying to make a menu screen in which all the UI elements (buttons, text...) are completely dark and by touching the screen you create a fire (or just an area light) that makes the UI elements visible.
Sort of like this
I read that the default shader for the UI elements isn't affected by light, but i can't seem to change it.
How do I go about doing this?
The UI elements by default use a unlit shader and are also rendered directly to clip space. so you'll need to do two things, first put a lit shader onto the elements, the unity standard shader should do fine, then you should change the canvas render mode to world space. with the canvas in world space you can move it around like it was a sprite. i would also recommend creating a second higher priority camera for the UI with culling turned off. with the canvas in view of the UI camera, you should be able to place a light source near it and see the resulting lighting on the UI.

How to draw carets for text input controls on double-buffered surface with GPU?

For example, when I have a complex view with the only thing actually changing is the caret, I don't want to redraw the whole scene just to update the caret.
For now the only reasonable way I can finger out to do this is to cache the content without the cursor. This doesn't seems to be a too bad one, but I have to choose between always render to texture or decide whether to render to texture or not all the time.
Maybe this problem can be generalized to "the right way to handle an almost-static complex scene with GPU".
My experience from working on a few games is to generally render the whole scene again. The cases where it is prohibitively expensive to re-render the resource every frame you implement the caching yourself. e.g. You cache a shadow map for a dynamic light until the light moves again.
The caching solution you described is what an automatic cache would have to anyways, so its not unreasonable. What concern do you have with rendering the whole scene again?

is requestAnimationFrame needed when drawing to a hidden canvas?

I have code that paints to a hidden canvas style="visibility: hidden" and then plots this hidden canvas onto one that is visible on screen.
Now as far as I understand, with the hidden canvas drawing should be performant even if it is not triggered via requestAnimationFrame. Is this so? Because I would then only use requestAnimationFrame for the blitting of the hidden canvas on the main screen.
The app I'm working on is not heavily animated but has quite a lot of lines to draw when something changes.
You should create the canvas with document.createElement("canvas") and don't attach this created canvas in any DOM container instead of use a hidden style . (Needs tests to prove, but at least is another way to create a back buffer canvas).
Even so, in my experience I never see effective gains by using backbuffered canvas with requestAnimationFrame. In fact, requestAnimationFrame does their job of synchronize the browser paint with the monitor's refresh rate and this enables smooth animations and more responsive pages. Also the animation will stop if the user switches to another tab which saves CPU usage and battery life of mobile devices.
I would not recommend the use of a back buffer canvas and I suggest, instead, that you perform your drawing stuff directly in main canvas inside a requestAnimationFrame callback. If you continuously keep drawing into the backbuffer canvas and trapped the main canvas into a requestAnimationFrame call you might unnecessarily(or not, that depends on you) lose some frames generating waste of CPU usage and low quality animations.
To help choose the better approach always do your own performance tests for your specific use cases.
And requestAnimationFrame is no needed at all. You are always able to use setInterval or setTimeout but the pros of using requestAnimationFrame are way bigger than his cons what make it the better approach for animations.

Make HTML5 canvas behave like TclTK canvas for scale/translate?

I'm trying to port a TclTK program I wrote 20 years ago to HTML5.
After hours of frustation, I learned that when you "scale" or
"translate" HTML5's canvas element, it only applies to future
drawings, not items already on the canvas.
This is the opposite of TclTK, where items already on the canvas are
scaled/translated instead.
Short of creating a draw/redraw loop (where I clear the canvas and
redraw all the objects myself when I want to scale/translate), is
there anyway to make HTML5's canvas element behave like TclTK's?
Or am I missing something big?
The Canvas 2D Context is based around pixel-wise image manipulations — it is not a “retained mode” graphics interface as you are apparently familiar with. There literally is no record of your graphics for it to redraw. If you want to change the graphics, you have to redraw them somehow.
Everything is redrawing, in the end (though the redrawing may be hidden from your code), but there are ways to reduce the amount of work you have to do. Here are some options, roughly in order of amount of change you'll have to do to your code (and roughly in order of improved quality/performance):
Draw your graphics on the canvas, then scale and translate the canvas itself using CSS properties (not the width and height attributes of the canvas, which will clear it). This will rescale the image, possibly losing quality, since you're not drawing it anew optimized for the current scale.
Draw your graphics on the canvas, then export them into an ImageData or a data URL, then when needed redraw that onto the canvas. Again, may lose quality.
The above two are essentially kludges to keep using the canvas code you've already written. To get a proper system like you describe TK as being, you want to:
Build your own scene graph: Create a set of objects like Circle, Line, etc. which represent graphics, and containers for those which store transform attributes like scale and position. Then write routines to walk this graph and execute the appropriate drawing commands, whenever you need to redraw.
Use SVG instead. SVG is a language for vector graphics which, in modern browsers, you can embed directly in your HTML, and manipulate in JavaScript just like you would the rest of your page. In SVG, you can simply change a scale attribute and get the change you expect to see.
(The previous option is basically reinventing a small amount of SVG.)

How do I animate clouds?

I have 3 nice and puffy clouds I made in Photoshop, all the same size, now I would like to animate them so they appear like they were moving in the background. I want this animation to be the base background in all my scenes (menu,settings, score, game).
I'm using cocos2d, I have setup the menus and the buttons so the work but how do I accomplish this?
I was thinking to add this as a layer, any other suggestions?
Can anyone show me how some code how to make this please?
David H
A simple way to do it is with sine and cosine. Have slighly different parameters (period and amplitude) to ensure that the user doesn't realise (as easily) that they are programmatically animated.
You may also want to play with animating the opacity value. I'm not sure if layers have those, otherwise you'll have to add the clouds to separate nodes or images and applying it to them.
It's hard to be more specific without knowing what the images look like.
The simplest way to animate anything is to add the sprite to the scene, set the position and call something like...
[myClouds runAction:[CCMoveBy actionWithDuration:10 position:CGPointMake(200, 0)]];
This will slide the sprite 200px to the right over 10 seconds. As Srekel suggested, you can play around with some trig functions to get a more natural feel and motion paths, but you'll have to schedule a selector and iteratively reposition the elements.
The more difficult part of your questions is about getting the animation in the background of all scenes. Keep in mind that when you switch scenes, you're unloading one node hierarchy and loading a new one. The background cannot be shared. You CAN, however, duplicate the sprites and animation in all scenes, but when you transition between them there will be a jump.

Resources