简体   繁体   中英

canvas drawimage is not working properly on image with css height and width

I am trying to write a image magnifier with canvas, It works fine but the problem is when I mouseover the image the image drawn on the canvas is not positioned correctly based on the mouse position on the image.

You can see the problem here

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Magnifier</title>

<style type="text/css">
canvas
{
    border:1px solid #000;
    width:150px;
    height:150px;
    border-radius:80px;
    position:absolute;
}
</style>
</head>
<body>
<img src="natural.jpg" height="400" id="image" width="600" onMouseMove="move(event);">
<canvas id="magnifier"></canvas>
<input type="button" name="magnify" id="magnify" value="magnify" onClick="magnify()" />
</body>
</html>
<script type="text/javascript">
var flag = 0;
var lens = document.getElementById('magnifier');
var img = document.getElementById('image');
var ctx=lens.getContext("2d");
function magnify()
{
    flag = 1;
}
function move(e)
{
    if(flag == 1)
    {
        var co_ord = getImageCoords(e,img);

        var x = co_ord['x']+img.offsetLeft;
        var y = co_ord['y']+img.offsetTop;
        draw(x,y);
        /*lens.style.top = y+"px";
        lens.style.left = x+"px";*/

    }
}
 function getImageCoords(event,img) {
        var cords = new Array;
        cords['x'] = event.offsetX?(event.offsetX):event.pageX-img.offsetLeft;
        cords['y'] = event.offsetY?(event.offsetY):event.pageY-img.offsetTop;
        return cords;
    }
    function draw(a,b)
    {
    ctx.clearRect(0,0,lens.width,lens.height);
    ctx.drawImage(img,a,b,150,150,0,0,300,150);
    }
</script>

The main problem is that you are scaling the original image by forcing it into a 640 by 400 img element. The actual image is quite a bit larger. The width and height are just presentation settings, so when you draw the image ctx.drawImage(img,a,b,150,150,0,0,300,150); it is drawing the original unsized image. This means that your mouse coordinates do not match the location on the original image.

I can see two options:

1. Resize original by drawing to canvas

See update here . I haven't used cssdeck before, so here is a fiddle in case I didn't save it properly. Basically, it resizes the image to a canvas (resizeCanvas) and then uses this canvas for the drawing:

Relevant HTML:

<canvas id='resizeCanvas' height='400' width='600' onMouseMove="move(event);"></canvas>

Relevant JavaScript:

var ctxR=resizeCanvas.getContext("2d");
ctxR.drawImage(theImg,0,0,600,400);

There were a few other tweaks I made. First, you should specify the width and height attributes directly on the magnifier canvas. Otherwise, if this is different from the css then this will cause scaling. Then you can do the scaling to double the size by:

ctx.drawImage(img,a,b,150,150,0,0,300,300);

The only drawback of that approach is that you have a high res image that you are uploading and then losing some quality when you maginify which seems a pity. So, a better approach might be to load the original image without adding to the dom and then translate the x,y coords appropriately for the original image. Which is the second approach:

2. Scale x,y coordinates (better quality)

See the update here (fiddle here as well). As you can see, the quality is much better.

Here, we load the original image:

var origImage = document.createElement('img');
var origImage.src = '<image source>'

Then, just scale accordingly:

scaleX = origImage.width/img.width;
scaleY = origImage.height/img.height;
    ctx.clearRect(0,0,lens.width,lens.height);
    ctx.drawImage(img,a*scaleX,b*scaleY,150,150,0,0,150,150);

Note that we are not actually doing any resizing of the original image at all when we draw it to the canvas (width and height are 150 in all cases), instead we are just showing it at its larger native size. For smaller images, you may want to resize according to some fudge factor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM