Canvas flickers if size is over 256px on Android (Cordova) - javascript

I'm developing a coloring mobile app using Cordova and the project https://github.com/theisensanders-wf/responsive-sketchpad
Everything works fine, but the canvas flickers if is not exactly 256px or less. I made some tests changing on the console the size with the Sketchpad.resize() function, and always over 256px the canvas starts flickering. I inserted it without modifications, on a document.ready listener as follows:
window.pad = new Sketchpad(document.getElementById('canvasDiv'));
By flicker I meant the lines seems to have an effect of being blurry and then rendered again, and that behavior repeats every 1 second.
I tried using requestAnimationFrame but that made the performance very poor in terms of refresh rate. It is a coloring app so it is important that the feeling of drawing feels real time.

I don't know if it still works but there's a plugin to improve canvas speed on android.
The only thing is that it hasn't been maintained for 4 years now...

Related

React Native Android: Is renderToHardwareTextureAndroid working?

I am having performance and "jank" issues while scrolling on a Android React Native app. The JS FPS drops from ~60fps down to ~3-10fps while scrolling.
The content being scrolled DOES include images containing transparency and text layered over images. If I remove the images, performance increases significantly.
The above scenario sounds like a perfect case for renderToHardwareTextureAndroid. That said, enabling this property on a View containing the images/text seems to have no effect at all.
How can I confirm this feature is truly turned on and working as expected? Is it possible that something I am doing/not doing is forcing the hardware rendering to not take place?

NW/Node Webkit - Image decodes even if it is already visible

I am currently working on a JavaScript(pure js) based game. The game contains 5 large sprite sheets(e.g. 2861 × 768 and 4096 × 4864). When the game starts, all 5 sprite sheets are preloaded to canvas elements. Three of those 5 sprites represent together one animation, where each sprite contains 75 frames. When one sprite ends with its animation, I hide it and display the next sprite. When the second sprite finishes animating, I hide it and display the third/last one.
When the second or third sprite is about to be displayed, a small delay of 0.5 s - 1 s happens. The image is being decoded.
It is not something that happens just the first time, it is something that happens always. And that animation repeats every 5 minutes, and the small delay happens always.
The reason why I'm using canvas elements for preloading is that I thought WebKit would just throw away decoded images for some time being unused and that the canvas element would prevent WebKit from deleting it from memory. But that does not work.
I've tried almost every optimization I'm aware of. I have even refactored all my CSS by removing descendant selectors etc.
The renderer I'm using to draw those animations is built by myself and it is working perfect, so that could not be the problem, since it is working very well in Firefox.
EDIT [2016/03/04]:
I made a mode with canvas and the result is even worse. It laggs a lot. And the delay remains the same. Only in NW, the problem does not persist in Chrome neither in Firefox.
Canvas mode - Lags:
Default(HTML) mode - Works perfect:
Codepen: My renderer http://codepen.io/anon/pen/JXPWXX
Note: If i hide those other elements with opacity:0.2 rather than opacity:0, the problem does not happen. But, I can not hide them like that since they remain still visible. They shouldn't be visible. If I add opacity:0.01 it is not visible and the problem does not happen in Chrome, but still persists in NW.
In NW, when I swtich from opacity:0.2 to opacity:1, an image decode is being processed. The same thing does not happen in Chrome browser.
I am using the following version:
nw.js v0.12.3
io.js v1.2.0
Chromium 41.0.2272.76
commit hash: 591068b-b48a69e-27b6800-459755a-2bdc251-1764a45
The three image sprites are 14.4MB, 14.9MB and 15.5MB size. Each sprite contains 75 frames.
Why could this be happening and how can I prevent it?
Try to switch to google-chrome directly since the new nw version is probably released 19.04.2016. After that NW will hopefully keep up with every Chromium release.
You should not have the same problems in Chrome.
Given that keeping Webkit thinking the image is still displayed makes the problem disappear (as your opacity experiment shows), I'd move it nearly completely out of the visible area, with only a single transparent row overlapping with the viewport (using overflow hidden).
Note that an unpacked 4000x4000 sprite sheet will use 64 Megabytes of RAM (4 bytes (=RGBA) per pixel), so perhaps it might be better to make sure the next image gets "warmed up" a bit ahead of time, without keeping all of them unpacked all the time?
I'd recommend using idata = ctx.getImageData(0, 0, canvas.width, canvas.height) to retrieve the data array from the canvases, then ctx.putImageData(idata, 0, 0) to switch between sprites, rather than hiding the canvases.

Why do I get better performance in Chrome when Dev Console is up?

I'm currently working on a small canvas game written in pure javascript from scratch.
The game involves a 2d lighting algorithm similar to this one, but with one light source and 25 polygons which makes for about 30,000 calculations per frame.
My frame rate is great in Safari, meh in Chrome, and unplayable in Firefox. However, if I have the Chrome developer console up while playing the game, the frame rate is the same as Safari.
What could be the reason for this?
After the comments suggested the window size might be affecting the frame rate, I found out that the smaller the window, the smoother the game runs but only in chrome. The amount that is drawn on screen or any calculations used by the game don't depend at all on the screen size.
I measure the frame rate difference purely by eye, and you can see the effect in these gifs:
Bad, big window:
Good, small window:
The game runs much smoother in the browser than is apparent in these gifs, but the effect is still noticeable.
I can get the same effect to happen with the first example in the link that I posted. Is it just me or does anyone else get the same effect?
Even stranger... I gotten the same effect on several other websites, like Facebook when I scroll the home feed. The bigger the window, the choppier the scrolling gets. Is this a Chrome specific thing, is anyone getting similar results?
I've seen this as well in my pages/applications. The issue seems to apply to anything, but is more pronounced with canvas and accelerated CSS. As far as I can tell, this issue is a performance bug relating to Chrome's composited layer rendering. Basically, Chrome breaks the page up into layers and uses the GPU to render those layers. You can see these by enabling the "Show composited layer borders" option in the "Rendering" tab on the dev console. Chrome's FPS performance decreases as the number of composite layers increases, regardless of the layers changing or not.
Here's an independent example. Steps to reproduce:
Load this page in Chrome, it's a relatively simple animated CSS demo that is a fixed size like your game: http://www.subcide.com/experiments/fail-whale/
Bring up the Chrome developer window (pop it out so it's an independent window) and enable the "Show FPS meter" option.
Size the window small so that it just contains the fail whale demo. Note your FPS.
Now size the window large or full screen it. Note your FPS.
With a small window, I get 55 FPS. Full screen, I get 34 FPS. I would expect the FPS to be nearly the same, regardless of the page size as the animated area doesn't change. The FPS seems to be proportional to the number of composite layers on the visible screen. Also, resizing the window results in the animation being chunky and skipping frames. If I perform the same window resizing in Safari, the animation stays smooth. Safari knows there's nothing new to render, while Chrome is seemingly doing a bunch of work for no reason.
So the reason why you see better performance when your dev console is open is because you have your dev console inline/embedded with the page, which makes the page itself smaller when it's open. This results in a page with fewer composite layers for Chrome to handle, which results in better FPS. If you pop your developer console out so it's an independent window and doesn't affect the page size, your FPS won't be affected by the dev console being up or not.
This appears to be the "why" this is happening. Now, if anyone figures out what can be done about this, I'd certainly be interested to know.

Scaling and touch interaction on Retina screens

I have a problem similar to one described in the following questions.
KineticJS : scaling issue while using custom clipFunc on 2x pixel aspect display
In my application: (please try on retina ipad vs normal ipad or desktop browser, even iOS simulator would also do)
There is are two canvas layers, one of them contains a blanket group that I scale with pinch-zoom gesture in the range of 0.5x to 1.5x
On the retina screen my canvas gets zoomed out to 1/4 the screen when at 0.5x
Now, with the change suggested in the comments, I managed to make it scale it properly however touch events are no longer scaled accordingly. Any ideas whats going on here?
Note that it is working perfectly on non-retina screens.
Am using KineticJS 4.4.3 - as its was an academic project that began early this year for proof-of-concept and now I'm continuing it to make a complete application.
Thanks!
My problem got solved after I upgraded to KineticJS 4.7.4
It however broke the clipping code I had as clipFunc was deprecated but that's a different issue which was resolved by resetting clip parameters on dragmove event.
Not an efficient solution but it works for now!

iPad running iOS5 loads large image with smaller dimension

I'm building a multiplatform HTML5 canvas game with EaselJS (although I tested without using this library and the problem persists);
I'm loading an image in that is 1280 x 1800 and then rendering it to the canvas.
This runs as expected on all devices except the ipad 1st gen running iOS5.
It loads and draws the image to canvas at 640x900...
I alerted Image.width with a result of 640, so I don't think it has anything to do with the actual rendering to canvas but rather limitations to image size with iOS5?
As a work around I am scaling the image up, so it just appears lower quality on this particular device, but I'm looking for a solution or at least explanation of why this is happening!
here is an example of the problem:
http://kokodev.co.uk/ipadcanvasimageproblem/
I also connected the iPad to the xCode organizer console to see if it reported any errors or memory warnings, but it did not!

Categories

Resources