Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 Canvas Resize image Click to Zoom

I have an image of a map in a canvas that I would like to act like the google map interface using HTML5 and jQuery. I would like to perform the following actions:

• Double click on pan in without changing the size of the containing div

• Click on a building to bring up a pop up of information on that building

• Click and drag to pan

The code I have right now is the image in the canvas. I have found several codes that show "zooming" on the image, but either resize the container div or aren't a smooth and responsive way to do it, it just jumps to a larger size and I would like the zooming to be animated.

There will be several buildings that are "pinned" on the map that the user can click on to bring up information about that building.

The code is as follows:

JS:

$( document ).ready( function() {
var canvas = document.getElementById( 'canvas' );
var context = null;
var map = null;

if( canvas.getContext )
{
    context = canvas.getContext( '2d' );

    $( '#map' ).load( function( evt ) {
        context.drawImage( evt.currentTarget, 10, 10 );
    } );

    map = new Image();
    map.onload = function() {
        context.drawImage( this, 20, 20 );
    };
    map.src = 'images/asu_poly_map.png';
} else {
    alert( 'Your browser does not support canvas.' );
}
} );

HTML:

<div id="map">

<canvas id="canvas" width="1055" height="600"></canvas>

</div>

CSS:

#map {
margin:0 auto;
margin-top : 180px;
width : 1200px;
}

EDITED TO ADD: I'm assuming it would be something similar to this, but can't figure out how to apply it to an image from the server being drawn onto the canvas.

Zoom in on a point (using scale and translate)

like image 809
Jen Avatar asked Apr 21 '13 18:04

Jen


1 Answers

Boom! I combined a bunch of StackOverflow references into something that works for you: http://jsfiddle.net/CMse5/1/

Here is the code:

HTML:

<div id="map">
    <canvas id="canvas" width="300" height="300"></canvas>
</div>

CSS:

canvas {
    border: 1px solid black;
}

JS:

$( document ).ready( function() {
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var scale = 1.5;
var originx = 0;
var originy = 0;
var imageObj = new Image(); 
    imageObj.src = 'http://placehold.it/300x300';

function draw(){
    // From: http://goo.gl/jypct
    // Store the current transformation matrix
    context.save();

    // Use the identity matrix while clearing the canvas
    context.setTransform(1, 0, 0, 1, 0, 0);
    context.clearRect(0, 0, canvas.width, canvas.height);

    // Restore the transform
    context.restore();

    // Draw on transformed context    
    context.drawImage(imageObj, 0, 0, 300, 300);

}
setInterval(draw,100);

canvas.onmousewheel = function (event){
    var mousex = event.clientX - canvas.offsetLeft;
    var mousey = event.clientY - canvas.offsetTop;
    var wheel = event.wheelDelta/120;//n or -n


    //according to Chris comment
    var zoom = Math.pow(1 + Math.abs(wheel)/2 , wheel > 0 ? 1 : -1);

    context.translate(
        originx,
        originy
    );
    context.scale(zoom,zoom);
    context.translate(
        -( mousex / scale + originx - mousex / ( scale * zoom ) ),
        -( mousey / scale + originy - mousey / ( scale * zoom ) )
    );

    originx = ( mousex / scale + originx - mousex / ( scale * zoom ) );
    originy = ( mousey / scale + originy - mousey / ( scale * zoom ) );
    scale *= zoom;
}

} );

Also, you mention animating the zooming in a smooth fashion. To do this, you will need to ease the zooming each frame. So, within your draw function, each frame you will want to ease between an original scale to the new one. You will definitely want to change to requestAnimationFrame, so that you get a better framerate.

It may be simpler to use a canvas/DOM hybrid, and use CSS3 transformations and animation on an image, which takes care of all the easing for you. You could overlay any necessary canvas things if needed.

like image 60
Dan Avatar answered Sep 21 '22 02:09

Dan