I've implemented a canvas element that uses drawarc to create the effect of bubbles rising up at various speeds on the background (it's an underwater themed site for an underwater-themed client) - It looks really good and I'm pretty pleased with it, but I'm noticing a slight performance issue in some browsers (specifically IE9).
I'm drawing the bubbles using drawarc to create semi translucent circles - can anyone tell me if this is more or less expensive (in terms of client side performance) to stamp images/sprites onto the canvas instead?
-Mike
Drawing arcs / circles is much more expensive than drawing images. Drawing images is most likely the most efficient method for drawing anything to a canvas. I wrote my Bachelor Thesis on this subject. It is in german, but basicly when drawing arcs using arc and arcTo you get less than 15.000 operations / sec in IE9. When drawing images you get more than 160.000 operations per second.
Related
I have a mapbox project in production where the street map the user customizes (location, zoom, and text) will ultimately be printed on a surface which has rather small dimensions (3.5" x 2.25" at 600dpi. keeping in mind that the zoom level affects the visibility of the different street types, The problem I am running into is this:
Since the canvas element renders at 72dpi, this means that in order to get an accurate representation of how the map will print, I actually have to make the map's div container real size # 72dpi (252px x 162px) which is of course quite small and far less detailed than the map will look when it's printed at 600dpi
In order to allow people to interact with the map at a reasonable size on the screen, the cheap solution is of course to scale up the canvas using css transforms: i.e. #mapContainer {transform: scale(2.5)}. However this results in a very pixelated map since, unlike svg vector graphics (as seen in the text and graphics overlays in the images below), the browser does not re-render the canvas when it scales up.
Unscaled canvas
Scaled Canvas
I have spent a lot of time searching for a solution to this problem, and at best it looks like I may have to utilize a method where I pull in mapbox data into tiling services like nextzen with data visualization libraries like D3.js but id like to make this one last ditch effort to see if there is any way to trick the browser into rendering this element in a higher size dpi without changing the map bounds or zoom.
I suspect the answer to this lies in a similar vein to this stack overflow question Higher DPI graphics with HTML5 canvas However when I attempt it, I get a null value for var ctx = canvas.getContext('2d') since the mapbox canvas is "webgl" not "2d"... looking into the "webgl" method of resizing a canvas for higher dpi here: https://www.khronos.org/webgl/wiki/HandlingHighDPI but I really am having a hard time understanding how exactly to redraw the canvas after the resize.
I have been familiar with the SVG format since a long time. It's usability and benefits over a raster image as well.
But Recently I came to a situation where I needed blur effect in SVG(basically a asset defined by primitive shapes that mimics blur effect and is infinitely scalable), so I did a google search and much to my surprise there are official ways of doing it; I was expecting it not to be!
I am basically intrigued by the fact that if SVGs are really made up primitives shapes defined mathematically then how can it incorporate effect like blur. What shape can even be used for such a process?
In Firefox we render the SVG to an offscreen surface, blur the pixels on that surface and then blit the offscreen surface. I imagine other browsers work similarly.
Filters and masks are raster operations, most everything else is vector.
Is there a way to universally multiply physics2D calculations on the canvas?
I'm trying to make a set of canvas UI elements with 2D physic properties. The objects contain images and text, but need to respond to gravity, impacts, and overlapping collision boxes with other GUI elements.
I've added 2D RigidBody and boxCollider components to my objects. However, they move very slowly. If given a gravity, they fall slowly. If overlapped, they push each other apart slowly.
I've figured out that this is due to the canvas having a very large scale. My objects are effectively 'very big and very far away'.
I can't modify the canvas scale. It needs to be huge or I get render artifacts.
I can't just modify gravity because it doesn't provide a universal fix. Things fall faster, but they don't push apart or spring right.
I can't modify the timestep because it affects the whole world, not just the canvas.
My canvas objects have widths akin to 80, where unity physics expects widths akin to 1. How can I get them to behave like they have a width of 1?
Is there some universal scaling factor for canvas based physics, or am I simply mis-using the canvas for something it is not intended for?
if you are still having this problem, the answer to fixing the movement rates of your scaled-up objects is to scale up your movement forces as well as your gravity. If you can't get certain elements to work right, use a forcepush that you can set to any strength.
I am programming tile based strategy game, so I have orthographic view. The rendered screen has 40*20 tiles wide and each tile has got 50*50px texture. I have one layer of tiles (let's say grass) and I place walls on top of it. The game runs smoothly at 60fps now. But do I need to remove the underlaying grass tile, when I place wall over it? Because the grass is rendered before the wall and so the wall overdraws it, but I am worried about the performance cost. I render it on SpriteBatch and there is no documentation on how does the inner processes in SpriteBatch work.
So the question is: Is it highly performance unfriendly to render tiles which are not visible anyway?
In my game I have tiled levels with 100-200x50 (one tile =90x90). Level has 4 layers (includes physic one). 10% of all tile are animated.
I don't have any problems with rendering of such map even on devices like Sumsung galaxy s2. As far as I know for rendering tiled maps libgdx uses sprite cashing technology. Such way even map with huge amount of tiles should works smoothly.
So I think you should not worry about performance with tiled map, you can remove invisible tiles and in theory it is good thing to do, but in practice it will impact on performance only if you have really huge amount of different invisible tiles.
I couldn't post the image, but I use the "CGContextDrawRadialGradient" method to draw a shaded blue ball (~40 pixel diameter), it's shadow and to make a "pulsing" white ring around the ball (inner and outer gradients on the ring). The ring starts at the edges of the blue ball and expands outward (radius grows with a timer). The white ring fades as it expands outward like a radio wave.
Looks great running in the simulator but runs incredibly slow on the iPhone 4. The ring should pulse in about a second (as in simulator), but takes 15-20 seconds on the phone. I have been reading a little about CALayer, CGLayer and reading some segments on a some gradient animation, but it isn't clear what I should be using for best performance.
How do I speed this up. Should I put the ball on a layer and the expanding ring on another layer? If so, how do I know which layer to update on a drawrect?
Appreciate any guidance. Thanks.
The only way to speed something like that up is to pre-render it. Determine how many image frames you need to make it look good and then draw each frame into a context you created with CGBitmapContextCreate and capture the image using CGBitmapContextCreateImage. Probably the easiest way to animate the images would be to set the animationImages property of a UIImageView (although there are other options, like CALayer animations).
The newest Apple docs finally mention which pixel formats are supported in iOS so make sure to reference those when creating your bitmap context.