拖动放置在画布上的缩放图像

时间:2016-03-12 18:37:22

标签: javascript jquery html html5 canvas

我有拖动缩放图像的问题 我创建了main_canvas,其中包含通过bg_canvas resp表示的背景和图像。 img_canvas。然后我制作了背景坐标(panoramaXpanoramaY)和图片(imageXimageY)来检查我是否点击了其中一些并能够拖动它们。

图像放在背景之上:

var drawToMain = function() 
{        
     // first clear the canvas
    main_ctx.clearRect(0,0,canvas.width, canvas.height);
    ctx.scale(scaleFactor, scaleFactor);
    // draw the background image
    main_ctx.drawImage(bg_canvas, panoramaX,panoramaY, 600, 300);
    // do the transforms
    main_ctx.translate( imageX+img_canvas.width/2,
                                            imageY+img_canvas.height/2);
    main_ctx.rotate(angle);
    main_ctx.translate( -(imageX+img_canvas.width/2),
                                            -(imageY+img_canvas.height/2));
    // draw the img with the transforms applied
    main_ctx.drawImage(img_canvas, imageX, imageY);
    // reset the transforms
    main_ctx.setTransform(1,0,0,1,0,0);
};

如果点击其中一个项目,拖动我正在测试的项目:

function hitImage(x, y) {
    if (x > imageX_hit && x < imageX_hit + img_canvas.width * scaleFactor &&
        y > imageY_hit && y < imageY_hit + img_canvas.height * scaleFactor)
          return 1;

    if (x > panoramaX && x < panoramaX + bg_canvas.width * scaleFactor &&
        y > panoramaY && y < panoramaY + bg_canvas.height * scaleFactor)
        return 2;

        return 0;
}

然后我制作了wheel事件以扩展main_canvas的内容(背景和图像,两者)我的问题在哪里,我正在更新那里的图像坐标,但是当我缩小图像时它对我不起作用示例并尝试拖动它,它不移动,当我缩小图像在背景中“旅行”时:

canvas.addEventListener("wheel", myFunction);
canvas.addEventListener('DOMMouseScroll', myFunction);
function myFunction(evt) {
    var delta = evt.wheelDelta ? evt.wheelDelta / 40 : evt.detail ? -evt.detail : 0;
    if (delta > 0)  scaleFactor = scaleFactor + 0.05;
    else            scaleFactor = scaleFactor - 0.05;
    imageX = imageX * scaleFactor;
    imageY = imageY * scaleFactor;
    imageX_hit = imageX_hit * scaleFactor;
    imageY_hit = imageY_hit * scaleFactor;
    drawToMain();
}

THERE是我问题的一个例子 请问有什么解决方案吗?

2 个答案:

答案 0 :(得分:1)

您需要通过乘以imageX来更改imageYimageX_hitimageY_hitscaleFactor个变量。您可以通过context.scale缩放图像,这样您就不需要在坐标中更改某些内容。只需记住比例因子并在hitImage中使用它来检查坐标。

我会尝试编辑帖子并更清楚地解释,如果这可以解决您的问题:

https://jsfiddle.net/j1f306w5/1/

我的更改:

function hitImage(x, y) { 
      if (x > imageX_hit * scaleFactor && x < imageX_hit * scaleFactor + img_canvas.width * scaleFactor &&
                y > imageY_hit * scaleFactor && y < imageY_hit * scaleFactor + img_canvas.height * scaleFactor)
        return 1;

      if (x > panoramaX * scaleFactor && x < panoramaX * scaleFactor + bg_canvas.width * scaleFactor &&
            y > panoramaY * scaleFactor && y < panoramaY * scaleFactor + bg_canvas.height * scaleFactor)
        return 2;

    return 0;
 }

  function myFunction(evt) {
    var delta = evt.wheelDelta ? evt.wheelDelta / 40 : evt.detail ? -evt.detail : 0;
    if (delta > 0)  scaleFactor = scaleFactor + 0.05;
    else                        scaleFactor = scaleFactor - 0.05;
    //imageX = imageX * scaleFactor;
    //imageY = imageY * scaleFactor;
    //imageX_hit = imageX_hit * scaleFactor;
    //imageY_hit = imageY_hit * scaleFactor;      
    drawToMain();
  }

答案 1 :(得分:1)

这是代码(修复Slavik&#39;代码,更新1):

$(document).ready(function() {
// x, y to place image
  var imageX = 80,
    imageY = 80;

  var imageX_hit = 80,
    imageY_hit = 80;
    // x, y to place background image
  var panoramaX = 0,
    panoramaY = 0;

  var startX,
    startY,
    dragImage;
  // mouse coordinates in canvas
  var mouseX,
    mouseY;
// number represents scale of image and background
  var scaleFactor = 1,
        angle = 0;

    // main canvas
  var canvas = document.createElement('canvas');
  canvas.width = 600;
  canvas.height = 300;
  document.body.appendChild(canvas);
  var ctx = canvas.getContext('2d');

  var canvasOffset = $(canvas).offset();
  var offsetX = canvasOffset.left;
  var offsetY = canvasOffset.top;


  var main_ctx = canvas.getContext('2d');
  var bg_canvas = canvas.cloneNode(); // canvas for image
  var img_canvas = canvas.cloneNode();// canvas for background

  var angle = 0;

  // draw on the main canvas, and only on the main canvas
  var drawToMain = function() 
{        
     // first clear the canvas
    main_ctx.clearRect(0,0,canvas.width, canvas.height);
    ctx.scale(scaleFactor, scaleFactor);
    // draw the background image
    main_ctx.drawImage(bg_canvas, panoramaX,panoramaY, 600, 300);
    // do the transforms
    main_ctx.translate( imageX+img_canvas.width/2,
                                            imageY+img_canvas.height/2);
    main_ctx.rotate(angle);
    main_ctx.translate( -(imageX+img_canvas.width/2),
                                            -(imageY+img_canvas.height/2));
    // draw the img with the transforms applied
    main_ctx.drawImage(img_canvas, imageX, imageY);
    // reset the transforms
    main_ctx.setTransform(1,0,0,1,0,0);
  };

  // I changed the event to a simple onclick
  $(canvas).mousedown(function(e) {
    switch (e.which) {
      case 1:
        // mouse position and test if image is hit
        startX = parseInt(e.clientX - offsetX);
        startY = parseInt(e.clientY - offsetY);
        dragImage = hitImage(startX, startY);
        break;
      default:
        break;
    }
  });

  $(canvas).mousemove(function(e) {
      // Im moving with image
      mouseX = parseInt(e.clientX - offsetX);
      mouseY = parseInt(e.clientY - offsetY);
      // move image by the amount of the latest drag
      var dx = (mouseX - startX)/scaleFactor;
      var dy = (mouseY - startY)/scaleFactor;
    if (dragImage == 1) {

      imageX += dx;
      imageY += dy;

      imageX_hit += dx;
      imageY_hit += dy;
      // reset the startXY for next time
      startX = mouseX;
      startY = mouseY;
      drawToMain();
    } 
  else if (dragImage == 2) {

      panoramaX += dx;
      panoramaY += dy;

      imageX += dx;
      imageY += dy;

      imageX_hit += dx;
      imageY_hit += dy;

      // reset the startXY for next time
      startX = mouseX;
      startY = mouseY;

      drawToMain();
    }
  });

  $(canvas).mouseup(function(e) {
    switch (e.which) {
      case 1:
        dragImage = 0;
        break;
      default:
        break;
    }
  });

    // ZOOM-IN or ZOOM-OUT
  canvas.addEventListener("wheel", myFunction);
  canvas.addEventListener('DOMMouseScroll', myFunction);
    // COMPUTING scaleFactor - zoom
  function myFunction(evt) {
    var delta = evt.wheelDelta ? evt.wheelDelta / 40 : evt.detail ? -evt.detail : 0;
    if (delta > 0)  scaleFactor = scaleFactor + 0.05;
    else                        scaleFactor = scaleFactor - 0.05;
    //imageX = imageX * scaleFactor;
    //imageY = imageY * scaleFactor;
  //console.log(imageX, imageY);
    //imageX_hit = imageX_hit * scaleFactor;
    //imageY_hit = imageY_hit * scaleFactor;      
    drawToMain();
  }

  // test if I user clicked image or panorama
  function hitImage(x, y) { 
    x=x/scaleFactor;
    y=y/scaleFactor;

      if (x > imageX_hit && x < imageX_hit  + img_canvas.width &&
            y > imageY_hit && y < imageY_hit  + img_canvas.height)
            return 1;

    if (x > panoramaX && x < panoramaX + bg_canvas.width &&
        y > panoramaY && y < panoramaY + bg_canvas.height)
        return 2;

        return 0;
  }

    // loading images into canvas
  var img = new Image();
  img.onload = function() {
    var this_canvas = img_canvas;
    this_canvas.width = 150;
    this_canvas.height = 150;
    this_canvas.getContext('2d').drawImage(this, 0, 
                                                                                    0, this_canvas.width,
                                            this_canvas.height);
    drawToMain();
  };
  img.src = 'http://pgmagick.readthedocs.org/en/latest/_images/lena_scale.jpg';

  var bg = new Image();
  bg.onload = function() {
    var this_canvas = bg_canvas;
    this_canvas.getContext('2d').drawImage(this, panoramaX, 
                                                                                    panoramaY, 600, 300);
    drawToMain();
  };
  bg.src = 'http://www.ansteorra.org/graphics/background/bg_image.jpg';
});