Since I dont have either of these devices handy to test, which method would be faster on an iphone/ipad?
One large canvas (overlayed over a bg of the same size), that is cleared, and has new pixel data drawn to it each frame, at a certain position
or
A small canvas that updates each frame, contained in a div that is animated across a background
As it turns out iphone/ipad aren't even capable of running this small animation either way. I will have to look at alternative solutions for mobile/tablet devices.
Yes, I've found the iPhone too slow in all my canvas experiment.
Even moving a simple div around (CSS3 styled, no canvas) is barely accettable ( my test with the new motion API: http://www.omiod.com/i.htm )
Related
I am building a web-based image editor, and everything seems to work fine until very large images are uploaded (>5mb), and then operations like adjusting the brightness using a slider takes a while to reflect. The issue is quite obvious, and that is because I have to loop through each pixel (step of 4) in context.getImageData().data in order to modify each pixel value.
I checked out a couple of already existing online image editors, and theirs seem to work pretty well without lags.
Initially, my first step was to resize the image to fit the canvas on the screen which worked fine without lags, but why I switched to modifying the original image size was because the original size does not change compared to the one on the screen which changes if the user resizes the screen (or if chrome displays the currently downloading bar at the bottom of the browser), and since it is constant, I can always keep track of all editing operations, and then display on the screen by basing scaling down to fit the screen.
I'd love to know how I can optimize for large-sized images, without losing the quality of the original (due to resizing etc). Thanks!
[UPDATED]
This was copied from a comment under this post.
"JavaScript is not suited for image pixels editing. That is what the GPU is for. Most image manipulation needs can be done using filters, standard 2D canvas as they use the hardware designed for the task. If you have custom PX manipulation needs then WebGL is the solution."
I have created a website to allow users to design playing cards online using fabricjs and have made the canvas responsive so it will work equally well on mobile devices as desktop. Almost everything works perfect... On smaller screens the objects are scaled correctly with the canvas and positioned correctly based on the canvas size but selecting/manipulating the objects doesn't work properly. When the canvas is scaled down from it's original (desktop based) size I cannot click on the object. I have noticed that the point on the canvas you need to click to select the object is shifted down and right from the object itself. The smaller the canvas gets, the further from the object the selection point gets. Is there a way to fix this?
Thanks!
Steve Sherrin
vI know to some extent this is a known issue that has been asked here but never answered, but I'm hoping for some additional insight.
I have a simple SVG image in a div on a web page. I want to be able to zoom the image using pinch gestures and have the SVG render sharply. It doesn't need to be sharp during the zoom, but should be sharp after the gesture is complete.
I'm doing my testing on a Windows 8.1 computer with a touch monitor, on an iPad, and on an old Android Galaxy Tab. On the main computer, I'm using IE11 and Chrome. For handling touch gestures, I'm using Hammer.js. I'm doing the zooming by modifying the transform CSS using the jQuery css() function (I'm setting scale3d and translate3d).
IE11 on my computer works exactly like I would like it to. It keeps the SVG image sharp throughout the pinch zoom and the image is always sharp regardless of when I set the CSS.
Chrome on my computer always renders the SVG blocky when I am zoomed in using pinch zoom. It is blocky during the zoom and does not get sharp afterwards. If I add a call to zoom the image after the page (x13) is loaded, the image is sharp. If I use a setTimeout() call to reset the zoom and then rezoom the image after the pinch zoom ends, the image is sharp.
On the iPad and Android tablet, the SVG never renders sharply, regardless of when I zoom it in code.
Does anyone have any ideas of how to reliably end up with a sharp rendering of SVG after a pinch-zoom is completed? Does anyone have a better solution? Using the SVG viewBox to zoom and pan during the gesture does not provide good enough performance for our more complex SVG images. I'm thinking of attempting to use the hardware accelerated scale3d/translate3d during the gesture and then attempt to convert this to new SVG viewBox settings afterwards, but this is a challenge and I'm not sure panning will work correctly after this is done. Any pointers or ideas are greatly appreciated.
Having just tried to answer your other SVG Question I will have a try at this one.
Michael Mullany is spot on that GPU translations will never give you a sharp image. This is because the GPU just maps one array of pixels to a new one. Because it has no concept of lines or rectangles the resolution is set by the time the GPU gets the image. The CPU will always struggle to re-render in time for a smooth drag.
What happens to allow some browsers to produce a sharp image is they do clever manipulations like rendering more pixels than they need so some zooming can happen without loss of resolution. These however are completely inconsistent and just not possible to rely on.
The as I see it 'correct' solution is to translate and zoom with hardware accelerated transformations during a pinch or zoom and then to refresh the viewbox with no css transformation when the translation has finished.
Challenges to overcome are
The css transformation will use screen coordinates but the viewBox manipulation will use the SVG coordinate system.
There are browser inconsistencies in both screenCTM and device pixel ratio
limits so that people don't drag or zoom too far need to be calculated in both systems
Pinch centerpoints also need to be calculated in both
To improve performance further the css transforms will be wrapped into updating on the requestAnimationFrame loop.
My working solution is hammerhead2. I am concentrating on desktops and android mobiles first and it seams to be working for them. To simplify the problem zoom is always centered to the screen center. I do however thing this is currently one of the only solutions. Here is an example of it working.
Why does this example run slower when the position is set by translate3d(x,y,z)?
My guess is that every change to the CSS requires a recalculation of the style, which is less expensive when the element isn't being sent to the GPU. Is there a way to do the dynamic transitions that I need without recalculating the style?
I'm interested in running in a WebView on iOS and Android. Is CSS3 the only option for accessing the GPU? Is there a way to use the GPU to increase performance here?
A good way to use the GPU for accelerated drawing on mobile webviews is via the <Canvas> element. This similar example is able to move four times as many particles at a similar framerate:
Canvas Particles
I am trying to develop a "Web App" (for lack of better terminology) that displays a sort of interactive map using the HTML5 Canvas element for mobile devices. The map has about 30 buildings (made from semi-transparent PNG images on it) of different shapes and sizes. I want the user to be able to tap on any of the buildings to get information about them. The buildings are often within the same theoretical bounding box of others, so it isn't as simple as just detecting when the user taps in a bounding box (imagine a U shaped building with another building inside the U). Therefore, it should use some sort of raster pixel detection. To make matters more complicated, I need to allow the user to zoom in/out and pan around on the map (because 30 buildings and a map are way too much to show a user on a tiny cellphone screen). So scaling and moving smoothly is a necessity.
I am looking for a JavaScript library that can support these functions:
Image pixel detection
Mobile touch events
Canvas (or stage?) scaling
Usable on mobile devices
So far, I have found KineticJS which supports all of these features. But when I try to move the map with more than 4 buildings on the stage, it is way too jumpy. I tried checking into Fabric.js but it doesn't seem to have pixel detection (as it selects the image when you click within the bounding box, not the actual image itself).
Is there any other JavaScript library out there that can do these things?
Thanks for any help!
The KineticJS is pretty good ( the best lib i found so far )
I never tried to use png images with it, but zooming and panning with a few hundreds primitive objects is pretty smooth (without pixel detection - I imagine the pixel detection is quite cpu expensive operation ).
Maybe you could try overlay standard polygons ( a few for one building ) and attach to the same click/tap event.
Also you don't necessary need to move objects on the canvas you can just put bigger canvas in smaller div ( with overflow:hidden) and drag the whole canvas element.