Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How redraw on canvas resize without blurring?

When the canvas element is resized (via the style changing) I also want to scale the canvas' drawn image as well. I cannot just change the height/width as this causes the canvas to clear itself, so I do:

  1. Create a temporary canvas element
  2. Draw the current canvas' image onto that temporary canvas
  3. Resize the current canvas
  4. Draw the temp canvas' image back to the current canvas but scaled to the new size

This results in some blurring - very noticeable after many resizes (example: when dragging to resize). How would I do this without any blurring?

EDIT: Turning off image smoothing (context.webkitImageSmoothingEnabled = false;) does not fix the problem, it simply makes it redraw it more and more jagged until the image looks nothing like the original after a number of resizes.

Called on resize event:

    var tmpCanvas = null;       

    //Make a temporary canvas
    tmpCanvas = document.createElement( "canvas" );

    //Set its size to be equal
    tmpCanvas.height = originalCanvas.height;
    tmpCanvas.width = originalCanvas.width;

    //Draw our current canvas onto it
    tmpCanvas.getContext( "2d" ).drawImage( originalCanvas, 0, 0 );

    //Set new dimensions
    originalCanvas.width = originalCanvas.offsetWidth;
    originalCanvas.height = originalCanvas.offsetHeight;

    var originalContext = originalCanvas.getContext( "2d" );

    //Set background and colors
    originalContext.fillStyle = "#ffffff";
    originalContext.strokeStyle = "#000000";

    //Set paintbrush
    originalContext.lineWidth = 4;
    originalContext.lineCap = "round";

    //Fill background as white
    originalContext.fillRect( 0, 0, originalCanvas.width, originalCanvas.height );

    //We have a saved signature
    if ( SignatureCanvas.hasSignature === true )
    {
        //Draw it back but scaled (results in blurred image)
        originalContext.drawImage( tmpCanvas, 0, 0, tmpCanvas.width, tmpCanvas.height, 0, 0, originalCanvas.width, originalCanvas.height );

        /** 
         * This results in a blurred image as well
         //Draw it back but scaled
         originalContext.scale( originalCanvas.width / tmpCanvas.width, originalCanvas.height / tmpCanvas.height );
         originalContext.drawImage( tmpCanvas, 0, 0, tmpCanvas.width, tmpCanvas.height, 0, 0, tmpCanvas.width, tmpCanvas.height );
         */
    }

Is there a way to get the strokes and "scale" all those points and redraw?

like image 615
Don Rhummy Avatar asked Oct 09 '13 23:10

Don Rhummy


Video Answer


1 Answers

Instead of taking the rendered image from the original canvas, actually redraw the image. By that, I mean execute the same logic you executed against the original canvas, but with the points involved scaled to the new size.

If you can, think about using SVG instead. It scales well by its nature.

Edit: Another option I've thought of is to simply use a gigantic canvas to start with. Sizing down tends to look better than sizing up, especially with smoothing on.

like image 180
Samantha Branham Avatar answered Sep 30 '22 19:09

Samantha Branham