当前位置: 动力学知识库 > 问答 > 编程问答 >

javascript - Create a zoomed in image of a part of the canvas within the canvas

问题描述:

I am trying to get the portion of an HTML canvas around the dot in my code and re-display it within the 75 x75 rectangle in the canvas as a zoomed in version. I know that scale allows me to zoom in but I am not sure how to use it in this case. I have attached the code in this fiddle. Any help will be appreciated.

http://jsfiddle.net/37bs7o3a/

HTML

<canvas id="graph" height ="400" width="500"></canvas>

jQuery

$(document).ready(function(){

var graph = $('#graph');

var l = graph[0].getContext('2d');

l.beginPath();

l.moveTo(50, 50);

l.lineTo(50, 350);

l.lineTo(450, 350);

l.stroke();

l.beginPath();

l.moveTo(100,250);

l.lineTo(450,200);

l.stroke();

l.beginPath();

l.rect(200, 225, 2, 2);

l.stroke();

l.rect(100, 75, 75, 75);

l.stroke();

});

网友答案:

I updated your fiddle and included two different ways to zoom in. One does a redraw and will give you better resolution. The other does a simple scale of the selected area and results in a blurry zoom.

http://jsfiddle.net/37bs7o3a/1/

$(document).ready(function(){
    var graph = $('#graph');
    var l = graph[0].getContext('2d');

    function draw(l) {
        l.beginPath();
        l.moveTo(50, 50);
        l.lineTo(50, 350);
        l.lineTo(450, 350);
        l.stroke();

        l.beginPath();
        l.moveTo(100,250);
        l.lineTo(450,200);
        l.stroke();

        l.beginPath();
        l.rect(200, 225, 2, 2);
        l.stroke();
    }

    draw(l);

    function redrawZoom(srcCtx, drawFn, x, y, scale, dx, dy, dw, dh) {
        var can = document.createElement('canvas');
        var ctx = can.getContext('2d');
        can.width = srcCtx.canvas.width;
        can.height = srcCtx.canvas.height;
        ctx.scale(scale, scale);
        ctx.translate(-x, -y);
        drawFn(ctx);

        // draw zoomed canvas on graph
        // sy, sy, sw, sh, dx, dy, dw, dh
        l.drawImage(can, 0, 0, dw, dh, dx, dy, dw, dh);

        // Draw zoom box
        l.strokeStyle = "rgba(0,0,255,.5)"
        l.rect(dx, dy, dw, dh);
        l.stroke();

        return can;
    }

    redrawZoom(l, draw, 190, 215, 3, 100, 75, 75, 75);

    function blurryZoom(ctx, x, y, w, h, scale, dx, dy) {

        // zoom outline
        ctx.beginPath();
        ctx.rect(190, 215, w, h);
        ctx.strokeStyle = "rgba(255,0,0,.5)"
        ctx.stroke();

        // zoom - Blurry Zoom
        l.drawImage(ctx.canvas,190,215,w,h,dx,dy,w*scale,h*scale);
    }

    blurryZoom(l, 190, 215, 25, 25, 3, 175, 75);

});
网友答案:

You might move the drawing commands to separate function like:

var doWhatEver = function(l) {
    // Drawing commands come here...
}

Then, implement the transformation function, something like:

var clipAndZoomAndScale = function(whatToDo, l, zoomTo) {
  l.save(); // save context, because we change the 2d matrix
  // Creates a clipping rectangle
  l.rect(zoomTo.x, zoomTo.y, zoomTo.width, zoomTo.height);
  l.clip();      

  // translate to the box corner
  l.translate( zoomTo.x , zoomTo.y );
  // scale the drawing area
  l.scale(zoomTo.width/zoomTo.origWidth, zoomTo.height/zoomTo.origHeight);
  // and finally, center the box to the orinal
  l.translate( zoomTo.origWidth/2  - zoomTo.centerAtX,
               zoomTo.origHeight/2 - zoomTo.centerAtY );  

  // draw the custom drawings here...
  whatToDo(l);
  l.restore(); // restore context
}

Then use it to transform your drawing commands to the rectangular area. The benefit of transforming the drawing commands instead of just copying the pixels is of course that you maintain the accuracy of the drawing as it is vectors all the way.

var graph = $('#graph');
var l = graph[0].getContext('2d');

// first draw without the transformation
doWhatEver(l);

// Then draw with the scaled context
clipAndZoomAndScale(doWhatEver, l, {
    x : 100, y : 75,
    width : 75, height:75,
    centerAtX : 200, centerAtY : 225,
    origWidth : 500, origHeight : 400
}); 

Please notice, that in your example the source aspect ratio 500:400 is not the same as in the target box 75:75 aspect ratio so the copy of the original image will appear to be distorted. To fix this set the origWidth to 400.

http://jsfiddle.net/o60t2mhr/

网友答案:

I'm thinking you want something like this? You can use drawImage. You basically select an area of the canvas, a target X / Y and a target width / height.

http://jsfiddle.net/37bs7o3a/2/

$(document).ready(function(){
    var graph = $('#graph');
    var l = graph[0].getContext('2d');
    
    l.beginPath();
    l.moveTo(50, 50);
    l.lineTo(50, 350);
    l.lineTo(450, 350);
    l.stroke();
    
    l.beginPath();
    l.moveTo(100,250);
    l.lineTo(450,200);
    l.stroke();
    
    l.beginPath();
    l.rect(200, 225, 2, 2);
    l.stroke();
    
    l.rect(100, 75, 75, 75);
    l.stroke();
    
    l.drawImage(
        graph[0], // Canvas
        180, // sourceX
        205, // sourceY
        40, // sourceW
        40, // sourceH
        
        100, // destX
        75, // destY
        75, // destW
        75 // destH
    );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="graph" height ="400" width="500"></canvas>
分享给朋友:
您可能感兴趣的文章:
随机阅读: