I'm trying to change the size of an HTML5 canvas element created by the KineticJS framework--that is, not the objects inside the canvas, but the element's size.
Since the jQuery .animate
function can't be used in this matter (it changes CSS, I want it to change the actual attributes of the element), I had to develop my own function that uses the internal stage.setSize(width, height)
function provided by the KineticJS API.
I have no experience at writing animation functions at all, so I might be approaching the situation completely wrong.
The problem:
It is performance dependent, therefore often not fast enough (thanks to setInterval). Not to mention that it only partially works on mobile devices (iPhone 4S iOS 5.0.1 tested). Any solution has to work more or less flawlessly, even on mobile devices.
I'm looking for different ways to improve this function. Shoot.
(For those who didn't get see the link to my code; http://jsfiddle.net/G4nuH/animateResize
is the relevant function.)
Without knowing the specifics of your final application, I would recommend avoiding animation of the canvas size if you can. As you probably know, if you change the size of a canvas element, everything stored on it is wiped clean. This means that animating the dimensions requires you to adjust the width and/or height incrementally while re-drawing the entire canvas at each iteration. For a desktop, this probably isn't a huge issue. Mobile devices will struggle, though.
Instead, I would suggest that you fake the animation by increasing the size of a container element (with a border, background color, etc. so the animation is apparent). Then, when the animation is done, save your current canvas data to a temporary object, increase the size of your canvas, and stamp the old content back on it.
If you are looking to animate the canvas dimensions to reveal content that is already present on a larger theoretical canvas (i.e. the user has a small window that's cropping the full canvas), you would be better off playing with your CSS width
and height
along with the overflow: hidden;
property. With this approach you would be editing your full canvas during all draw operations, but animating the size of your viewport would be simple and smooth.
The canvas is a view port for graphics, it can be the entire size of your document. You can use the context.clip()
function to define the area you wish to display instead of resizing the canvas which requires the html box model to be updated. (your performance problem!)
ctx.moveTo(162, 20);
ctx.lineTo(162, 320);
ctx.lineTo(300, 320);
ctx.lineTo(300, 20);
ctx.clip();
After some research, I found my own hacky-solution. An example using jQuery.animate
. Had to animate them all, since KineticJS has several background layers.
//Gather all canvases
var canvases = document.getElementsByTagName("canvas");
//Animate their size
for(var c in canvases) {
$(canvases[c]).animate({
'width': "100px",
'height': "100px"
}, 500);
}