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.
Related
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?
I have a very specific issue. I am doing a demo in VR with three.js where I want to display 2D data. The data that will be displayed is dynamic (Text info) and needs to be animated.
Animate CC providing a nice suite of tools is an easy choice for this. With three.js, the way I found to add some 2D animation in the world, was to create a plane, add a texture from a canvas I created, which I update on RAF. No problem as of now.
The canvas I'm rendering is also the one that I create my stage from. Here the issue : Whatever the animation is (even an empty stage) I see a drop in framerate of about 15, as soon as I add the eventlistener on tick for the stage update. I tried many things (like not even adding the mesh, onto which I draw the canvas, to my scene) And If the eventlistener is added, I see my fps take a hit.
Whether the animation is "heavy" or not, I see this drop in framerate. And that drop is a big issue in VR since staying on 60 FPS is pretty much a must have at this point.
Any lead on what I could do to make this better ? Thank you !
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.
Lets say i am making a game in which there is background that is dynamic. Now in a setup where i am using multiple canvas, so one canvas dedicated for background as it doesn't need to update as often, Also Map is not infinite it's big but not that big.
So in should i move redraw the map at every move.
Or move the whole canvas which then would act like a layer.
Any ideas?
Will use css to clip map to size of game.
While it's true i have not tried anything but that is because i dont know what to try. I'd make both but wont know which one is working. Basically i am clueless in bench marking sector.
http://jsperf.com/translate-vs-background-position
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.)