Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
345 views
in Technique[技术] by (71.8m points)

jquery - Can't make image draggable on canvas

var img1 = new Image();
var img2 = new Image();
var img3 = new Image();
var img4 = new Image();
var imageCount = 0, NUM_IMAGES=4;
var ctx;
var WIDTH;
var HEIGHT;

 //drag
var draggable = false;
var startX;
var startY;
//array of images
var images=[];
images.push({image:img1, x:0, y:20, width:550, height:466});
images.push({image:img2, x:476, y:170, width:230, height:240});
images.push({image:img3, x:500, y:20, width:635, height:313});
images.push({image:img4, x:910, y:328, width:219, height:134});


function init(){
  ctx = $('#myCanvas')[0].getContext("2d");
  WIDTH = $("#myCanvas").width();
  HEIGHT = $("#myCanvas").height();
  ctx.fillStyle = "#A0DCE5";
  ctx.fillRect(0,0,WIDTH,HEIGHT);
  loadResources();
  $('#myCanvas').mousedown(onMouseDown);
  $('#myCanvas').mouseup(onMouseUp);
  $('#myCanvas').mousemove(onMouseMove);


}

function startInteraction() {
    imageCount++;
    if (imageCount ==NUM_IMAGES)
        render();
}

function loadResources() {
    img1.onload = startInteraction;
    img1.src = "america.png";
    img2.onload = startInteraction;
    img2.src = "africa.png";
    img3.onload = startInteraction;
    img3.src = "europe and asia.png";
    img4.onload = startInteraction;
    img4.src = "australia.png";
}
function image(image,x,y,width,height) {
    ctx.drawImage(image,x,y,width,height)
}

function render() {
    for(var i=0;i<images.length;i++){
            var r=images[i];
            image(r.image,r.x,r.y,r.width,r.height);
        }

}

function onMouseDown(e){

    // tell browser we're handling this mouse event
    e.preventDefault();
    e.stopPropagation();

    //get current position
    var mx=parseInt(e.clientX-$('#myCanvas').offset().left);
    var my=parseInt(e.clientY-$('#myCanvas').offset().top);

    //test to see if mouse is in image
    d = false;
    for(var i=0;i<images.length;i++){
        var r=images[i];
        if(mx>r.x && mx<r.x+r.width && my>r.y && my<r.y+r.height){
            //if true set is dragging=true
            draggable=true;
        }
    }
    //save mouse position
    startX=mx;
    startY=my;
}

function onMouseUp(e){
    //tell browser we're handling this mouse event
    e.preventDefault();
    e.stopPropagation();

    draggable = false;
    for(var i=0;i<images.length;i++){
        images[i].isDragging=false;
    }
}

function onMouseMove(e){
    //if we can drag an image
    if(draggable){

        //tell brower we're handling this mouse event
        e.preventDefault
        e.stopPropagation

        //get current mouseposition
        var mx = parseInt(e.clientX-$('#myCanvas').offset().left);
        var my = parseInt(e.clientY-$('#myCanvas').offset().top);

        //calculate how far the mouse has moved;

        var dx = mx - startX;
        var dy = my - startY;

        //move each image by how far the mouse moved
        for(var i=0;i<images.length;i++){
            var r=images[i];
            if(r.isDragging){
                r.x+=dx;
                r.y+=dy;
            }
        }
        //re render the images
        render();

        //reset the mouse positions for next mouse move;
        startX = mx;
        startY = my;
    }
}



$(document).ready(init);

I am having real difficulty trying to get images to move and every tutorial i look at I just can seem to understand it.

Is there something blindingly obvious I'm doing wrong?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When dragging 1+ images on a canvas, the procedure is:

In mousedown:

  • get the current mouse position
  • set the isDragging flag on any image that is under the mouse
  • save the current mouse position

In mousemove:

  • get the current mouse position
  • calculate how far the mouse has moved ( distance = newMousePosition-oldMousePosition )
  • add the distance to the position of any image that isDragging
  • save the current mouse position
  • redraw the scene with images in their new positions

In mouseup and mouseout:

  • clear all isDragging flags

Here's annotated code and a Demo:

// canvas related stuff
var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
ctx.fillStyle = "#A0DCE5";
$myCanvas=$('#myCanvas');

//drag
var isDragging = false;
var startX;
var startY;

//array of image objects
var images=[];
var NUM_IMAGES=0;

// queue up 4 test images
addImage(20,20,0.50,'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpg');
addImage(240,20,0.50,'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-2.jpg');
addImage(20,220,0.50,'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-3.jpg');
addImage(240,220,0.50,'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-4.jpg');

// trigger all images to load
for(var i=0;i<images.length;i++){
  images[i].image.src=images[i].url;
}


//////////////////////////////
// functions
//////////////////////////////

// queue up another image
function addImage(x,y,scaleFactor,imgURL){
  var img=new Image();
  img.crossOrigin='anonymous';
  img.onload=startInteraction;
  images.push({image:img,x:x,y:y,scale:scaleFactor,isDragging:false,url:imgURL});
  NUM_IMAGES++;
}

// called after each image fully loads
function startInteraction() {

  // return until all images are loaded
  if(--NUM_IMAGES>0){return;}

  // set all images width/height
  for(var i=0;i<images.length;i++){
    var img=images[i];
    img.width=img.image.width*img.scale;
    img.height=img.image.height*img.scale;
  }

  // render all images
  renderAll();

  // listen for mouse events
  $myCanvas.mousedown(onMouseDown);
  $myCanvas.mouseup(onMouseUp);
  $myCanvas.mouseout(onMouseUp);
  $myCanvas.mousemove(onMouseMove);

}

// flood fill canvas and 
// redraw all images in their assigned positions
function renderAll() {
  ctx.fillRect(0,0,WIDTH,HEIGHT);
  for(var i=0;i<images.length;i++){
    var r=images[i];
    ctx.drawImage(r.image,r.x,r.y,r.width,r.height);
  }
}

// handle mousedown events
function onMouseDown(e){

  // tell browser we're handling this mouse event
  e.preventDefault();
  e.stopPropagation();

  //get current position
  var mx=parseInt(e.clientX-$myCanvas.offset().left);
  var my=parseInt(e.clientY-$myCanvas.offset().top);

  //test to see if mouse is in 1+ images
  isDragging = false;
  for(var i=0;i<images.length;i++){
    var r=images[i];
    if(mx>r.x && mx<r.x+r.width && my>r.y && my<r.y+r.height){
      //if true set r.isDragging=true
      r.isDragging=true;
      isDragging=true;
    }
  }
  //save mouse position
  startX=mx;
  startY=my;
}

// handle mouseup and mouseout events
function onMouseUp(e){
  //tell browser we're handling this mouse event
  e.preventDefault();
  e.stopPropagation();

  // clear all the dragging flags
  isDragging = false;
  for(var i=0;i<images.length;i++){
    images[i].isDragging=false;
  }
}

// handle mousemove events
function onMouseMove(e){

  // do nothing if we're not dragging
  if(!isDragging){return;}

  //tell browser we're handling this mouse event
  e.preventDefault
  e.stopPropagation

  //get current mouseposition
  var mx = parseInt(e.clientX-$myCanvas.offset().left);
  var my = parseInt(e.clientY-$myCanvas.offset().top);

  //calculate how far the mouse has moved;
  var dx = mx - startX;
  var dy = my - startY;

  //move each image by how far the mouse moved
  for(var i=0;i<images.length;i++){
    var r=images[i];
    if(r.isDragging){
      r.x+=dx;
      r.y+=dy;
    }
  }

  //reset the mouse positions for next mouse move;
  startX = mx;
  startY = my;

  //re render the images
  renderAll();

}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Drag the images.</h4>
<canvas id="myCanvas" width=400 height=400></canvas>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...