如何在缩放图像/对象后在画布中拖动它们

How to drag images / objects within Canvas after zooming / scaling them?

本文关键字:布中 拖动 对象 缩放 图像      更新时间:2023-09-26

下面是我的完整代码。哪个是根据此链接编辑的?如何在画布中拖动图像/对象?。

要求:

基本上,我正在做的是,首先,在canvg的帮助下,用drawSvg在画布上绘制SVG文件。

在这个文件上,我通过markers.js.中的JSON绘制图像(green1.png和orange1.png)

场景1:

如果我在不缩放的情况下平移,那么就可以拖动这些图像(绿色1.png、橙色1.png),并且可以正确地平移画布。

但如果我在平移后缩放,那么由于平移X和平移Y点的原因,图像不会在正确的位置平移。但panX和panY是我们想要平移的点。

场景2:

如果我先缩放,然后平移,则图像(橙色.png,绿色1.png)正在更改其位置,无法拖动图像(橙色1.png,绿色1.png)。

在这些情况下可以做些什么

HTML代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>      
        <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
        <style>
            canvas {
                border:1px solid #000
            }
            .tooltip{
                *position:fixed;
                position:absolute;
                *background:#ff7;
                background:green;
                border:1px solid #000;
                padding:7px;
                font-family:sans-serif;
                font-size:12px;
            }
            .tooltip2  {
                *position:fixed;
                position:absolute;
                background:pink;
                border:1px solid #000;
                padding:7px;
                font-family:sans-serif;
                font-size:12px;
            }
        </style>        
    </head>
    <body>
    <script src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script> 
    <script src="http://canvg.googlecode.com/svn/trunk/StackBlur.js"></script>
    <script src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>
    <canvas id="myCanvas" width="800" height="700" style="border: 1px solid;margin-top: 10px;"></canvas>
    <div id="buttonWrapper">
        <input type="button" id="plus" value="+">
        <input type="button" id="minus" value="-">
        <input type="button" id="original_size" value="100%">       
    </div>  
    <script src="/static/js/markers.js"></script>
    <script src="/static/js/draw.js"></script>

    </body>
</html>

draw.js:

var dataJSON = data || [];
var dataJSON2 = data2 || [];
window.onload = function(){ 
  //$(function(){              
    var canvas=document.getElementById("myCanvas");
    var ctx=canvas.getContext("2d");        
    var canvasOffset=$("#myCanvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var lastX=0;
    var lastY=0;
    var panX=0;
    var panY=0;
    var dragging=[];
    var dragging2=[];
    var isDown=false;
    function loadImages(sources, callback){
      var images = {};
      var loadImages = 0;
      var numImages = 0;
      //get num of sources
      for(var i in sources){            
        numImages++;
      }
      for(var i in sources){            
        images[i] = new Image();
        images[i].onload = function(){
          if(++loadImages >= numImages){
            callback(images);
          }
        };
        images[i].src = sources[i];            
      }
    }
    var sources = {orange : '/static/images/orange1.png', green : '/static/images/green1.png'};

    // load the tiger image
    var svgfiles = ["/static/images/awesome_tiger.svg"];
    /*var tiger=new Image();
    tiger.onload=function(){
      draw();
    }
     tiger.src="tiger.png";*/
    function draw(scaleValue){ 
      ctx.clearRect(0,0,canvas.width,canvas.height);    
      ctx.save();
      ctx.drawSvg(svgfiles[0],panX,panY,400*scaleValue, 400*scaleValue);         
      //ctx.drawImage(tiger,panX,panY,tiger.width,tiger.height);    
       //ctx.scale(scaleValue, scaleValue);
      loadImages(sources, function(images){     
        ctx.scale(scaleValue, scaleValue);
        for(var i = 0, pos; pos = dataJSON[i]; i++) {            
          ctx.drawImage(images.orange, parseInt(parseInt(pos.x) + parseInt(panX)), parseInt(parseInt(pos.y) + parseInt(panY)), 20/scaleValue, 20/scaleValue);               
        }
        for(var i = 0, pos; pos = dataJSON2[i]; i++) {            
          ctx.drawImage(images.green, parseInt(parseInt(pos.x) + parseInt(panX)), parseInt(parseInt(pos.y) + parseInt(panY)), 20/scaleValue, 20/scaleValue);             
        }
        ctx.restore();
      });
    };
    var scaleValue = 1;
    var scaleMultiplier = 0.8;
    draw(scaleValue);
    var startDragOffset = {};
    var mouseDown = false;          
    // add button event listeners
    document.getElementById("plus").addEventListener("click", function(){           
        scaleValue /= scaleMultiplier;  
        //checkboxZoomPan();            
        draw(scaleValue);               
    }, false);
     document.getElementById("minus").addEventListener("click", function(){
        scaleValue *= scaleMultiplier;
        //checkboxZoomPan();            
        draw(scaleValue);       
    }, false);
    document.getElementById("original_size").addEventListener("click", function(){
        scaleValue = 1;
        //checkboxZoomPan();            
        draw(scaleValue);   
    }, false);

    // create an array of any "hit" colored-images
    function imagesHitTests(x,y){   
      // adjust for panning
      x-=panX;
      y-=panY;
      // create var to hold any hits
      var hits=[];
      // hit-test each image
      // add hits to hits[]
      loadImages(sources, function(images){
        for(var i = 0, pos; pos = dataJSON[i]; i++) { 
          if(x >= parseInt(pos.x * scaleValue) && x <= parseInt((pos.x * scaleValue) + 20) && y >= parseInt(pos.y * scaleValue) && y <= parseInt((pos.y * scaleValue) + 20)){
            hits.push(i);           
          }              
        }            
      });          
      return(hits);
    }
    function imagesHitTests2(x,y){      
      // adjust for panning
      //x-=panX;
      //x = parseInt(x) - parseInt(panX);     
     // y-=panY;
     x-=panX;
     y-=panY;
      // create var to hold any hits
      var hits2=[];
      // hit-test each image
      // add hits to hits[]
      loadImages(sources, function(images){            
        for(var i = 0, pos; pos = dataJSON2[i]; i++) {          
          //if(x > pos.x && x < parseInt(parseInt(pos.x) + parseInt(20)) && y > pos.y && y < parseInt(parseInt(pos.y) + parseInt(20))){
          if(x >= parseInt(pos.x * scaleValue) && x <= parseInt((pos.x * scaleValue) + 20) && y >= parseInt(pos.y * scaleValue) && y <= parseInt((pos.y * scaleValue) + 20)){           
            hits2.push(i);          
          }              
        }            
      });          
      return(hits2);
    }
    function handleMouseDown(e){
      // get mouse coordinates
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      // set the starting drag position
      lastX=mouseX;
      lastY=mouseY;
      // test if we're over any of the images
      dragging=imagesHitTests(mouseX,mouseY);
      dragging2=imagesHitTests2(mouseX,mouseY);
      // set the dragging flag    
      isDown=true;
    }
    function handleMouseUp(e){
      // clear the dragging flag
      isDown=false;
    }
    function handleMouseMove(e){
      // if we're not dragging, exit
      if(!isDown){
        return;
      }
      //get mouse coordinates
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      // calc how much the mouse has moved since we were last here
      var dx=mouseX-lastX;
      var dy=mouseY-lastY;
      // set the lastXY for next time we're here
      lastX=mouseX;
      lastY=mouseY;
      // handle drags/pans
      if(dragging.length>0){      
        // we're dragging images
        // move all affected images by how much the mouse has moved            
        for(var i = 0, pos; pos = dataJSON[dragging[i]]; i++) {              
          pos.x = parseInt(pos.x) + parseInt(dx);
          pos.y = parseInt(pos.y) + parseInt(dy);              
        }
      }
      else if(dragging2.length>0){      
        for(var i = 0, pos1; pos1 = dataJSON2[dragging2[i]]; i++) {              
          pos1.x = parseInt(pos1.x) + parseInt(dx);              
          pos1.y = parseInt(pos1.y) + parseInt(dy);
        }            
      }
      else{
        // we're panning the tiger
        // set the panXY by how much the mouse has moved
        panX+=dx;
        panY+=dy;
      }
      draw(scaleValue);
    }

    // use jQuery to handle mouse events
    $("#myCanvas").mousedown(function(e){handleMouseDown(e);});
    $("#myCanvas").mousemove(function(e){handleMouseMove(e);});
    $("#myCanvas").mouseup(function(e){handleMouseUp(e);});
// }); // end $(function(){});
  }

markers.js:

data = [  
        {   "id" :["first"],        
            "x": ["195"],
            "y": ["150"],
            "tooltiptxt": ["Region 1"]
        },  
        {
            "id" :["second"],
            "x": ["255"],
            "y": ["180"],
            "tooltiptxt": ["Region 2"]      
        },
        {
            "id" :["third"],
            "x": ["200"],
            "y": ["240"],
            "tooltiptxt": ["Region 3"]      
        }       
    ];
data2 = [  
        {   "id" :["first2"],       
            "x": ["225"],
            "y": ["150"],
            "tooltiptxt": ["Region 21"]
        },  
        {
            "id" :["second2"],
            "x": ["275"],
            "y": ["180"],
            "tooltiptxt": ["Region 22"]     
        },
        {
            "id" :["third3"],
            "x": ["300"],
            "y": ["240"],
            "tooltiptxt": ["Region 23"]     
        }       
    ];

1.)positionX*xScale和positionY*yScale

2.)在绘图功能中尝试此代码

ctx.drawImage(images.orange, parseInt(parseInt(pos.x) + parseInt(panX / scaleValue)), parseInt(parseInt(pos.y) + parseInt(panY / scaleValue)), 20/scaleValue, 20/scaleValue);