Search code examples
htmlhtml5-canvashtml5-animation

HTML5 : drawing round corner rectangle as animation


I'm able to draw a rectangle with rounded corner with following code. What I'm looking is I want to form this as an animation - starting from one point and draw the line which ends at the beginning point. (like drawing with pencil) Any ideas?

ctx.beginPath(); 
  ctx.moveTo(x,y+radius);
  ctx.lineTo(x,y+height-radius); 

  ctx.quadraticCurveTo(x,y+height,x+radius,y+height);  
  ctx.lineTo(x+width-radius,y+height);  
  ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);  
  ctx.lineTo(x+width,y+radius);  
  ctx.quadraticCurveTo(x+width,y,x+width-radius,y);  
  ctx.lineTo(x+radius,y);  
  ctx.quadraticCurveTo(x,y,x,y+radius);  
  ctx.stroke(); 

Solution

  • Canvases are double-buffered. You'll need to defer each step of the animation using setTimeout() to give the canvas a chance to draw your changes. Update: See requestAnimationFrame as an alternative to setTimeout().

    I've created one example for you that draws each of your rectangle's segments by calling the context method and pausing. I think I know the particular animation you're looking for and this isn't it, but hopefully it gives you a good start.

    Code below and a demo is here: http://jsfiddle.net/q8GcR/

    function animateRoundRect(ctx, x, y, width, height, radius, delay) {
        commands = [
            ['moveTo', x,y+radius],
            ['lineTo', x,y+height-radius], 
            ['quadraticCurveTo', x,y+height,x+radius,y+height],  
            ['lineTo', x+width-radius,y+height],  
            ['quadraticCurveTo', x+width,y+height,x+width,y+height-radius],  
            ['lineTo', x+width,y+radius],  
            ['quadraticCurveTo', x+width,y,x+width-radius,y],  
            ['lineTo', x+radius,y],  
            ['quadraticCurveTo', x,y,x,y+radius]
        ];  
    
        function draw() {
            var args = commands.shift();
            var method = args.shift();
            ctx[method].apply(ctx, args);
            ctx.stroke();
            if (commands.length) {
                setTimeout(draw, delay);
            }
        }
    
        ctx.beginPath();
        draw();
    }
    
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    ctx.lineWidth = 3;
    ctx.strokeStyle = '#f00';
    animateRoundRect(ctx, 20, 20, 250, 100, 10, 500);