按比例缩放画布图像

时间:2015-05-21 20:46:25

标签: javascript jquery html5 html5-canvas

我使用以下代码创建用户上传图像的画布,并可以拖动,调整大小并将图像旋转到产品上。有点像T恤设计工具。

我的问题是,我需要按比例缩放图像,这样当用户调整图像大小时,它看起来不会扭曲或拉伸。

var canvas = document.getElementById("editorCanvas");
var ctx = canvas.getContext("2d");

var canvasOffset = $("#editorCanvas").offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;

var startX;
var startY;
var isDown = false;


var pi2 = Math.PI * 2;
var resizerRadius = 4;
var rr = resizerRadius * resizerRadius;
var draggingResizer = {
  x: 0,
  y: 0
};
var imageX = 0;
var imageY;
var imageWidth, imageHeight, imageRight, imageBottom;
var draggingImage = false;
var startX;
var startY;

var img = new Image();
img.crossOrigin='anonymous';
img.onload = function () {

  var ratio = img.width / img.height;

  imageWidth = 71;
  imageHeight = imageWidth / ratio;
  imageY = (245-imageHeight)/2;
  if (imageHeight > 245) {
    imageHeight = 245;
    imageWidth = imageHeight * ratio;
    imageY = 0;
  }

  imageX = ((canvas.width-imageWidth)/2);
  imageY = ((canvas.height-imageHeight)/2);

  imageRight = imageX + imageWidth;
  imageBottom = imageY + imageHeight;

  draw(true, false);
}
//img.src='https://dl.dropboxusercontent.com/u/139992952/multple/leftarrow.png';

function draw(withAnchors, withBorders) {

  // clear the canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // draw the image
  ctx.drawImage(img, 0, 0, img.width, img.height, imageX, imageY, imageWidth, imageHeight);

  // optionally draw the draggable anchors
  if (withAnchors) {
    drawDragAnchor(imageX, imageY);
    drawDragAnchor(imageRight, imageY);
    drawDragAnchor(imageRight, imageBottom);
    drawDragAnchor(imageX, imageBottom);
  }

  // optionally draw the connecting anchor lines
  if (withBorders) {
    ctx.beginPath();
    ctx.moveTo(imageX, imageY);
    ctx.lineTo(imageRight, imageY);
    ctx.lineTo(imageRight, imageBottom);
    ctx.lineTo(imageX, imageBottom);
    ctx.closePath();
    ctx.stroke();
  }

}

function drawDragAnchor(x, y) {
  ctx.beginPath();
  ctx.arc(x, y, resizerRadius, 0, pi2, false);
  ctx.closePath();
  ctx.fill();
}

function anchorHitTest(x, y) {

  var dx, dy;

  // top-left
  dx = x - imageX;
  dy = y - imageY;
  if (dx * dx + dy * dy <= rr) {
    return (0);
  }
  // top-right
  dx = x - imageRight;
  dy = y - imageY;
  if (dx * dx + dy * dy <= rr) {
    return (1);
  }
  // bottom-right
  dx = x - imageRight;
  dy = y - imageBottom;
  if (dx * dx + dy * dy <= rr) {
    return (2);
  }
  // bottom-left
  dx = x - imageX;
  dy = y - imageBottom;
  if (dx * dx + dy * dy <= rr) {
    return (3);
  }
  return (-1);

}


function hitImage(x, y) {
  return (x > imageX && x < imageX + imageWidth && y > imageY && y < imageY + imageHeight);
}


function handleMouseDown(e) {
  startX = parseInt(e.clientX - offsetX);
  startY = parseInt(e.clientY - offsetY);
  draggingResizer = anchorHitTest(startX, startY);
  draggingImage = draggingResizer < 0 && hitImage(startX, startY);
}

function handleMouseUp(e) {
  draggingResizer = -1;
  draggingImage = false;
  draw(true, false);
}

function handleMouseOut(e) {
  handleMouseUp(e);
}

function handleMouseMove(e) {

  if (draggingResizer > -1) {

    mouseX = parseInt(e.clientX - offsetX);
    mouseY = parseInt(e.clientY - offsetY);

    // resize the image
    switch (draggingResizer) {
      case 0:
        //top-left
        imageX = mouseX;
        imageWidth = imageRight - mouseX;
        imageY = mouseY;
        imageHeight = imageBottom - mouseY;
        break;
      case 1:
        //top-right
        imageY = mouseY;
        imageWidth = mouseX - imageX;
        imageHeight = imageBottom - mouseY;
        break;
      case 2:
        //bottom-right
        imageWidth = mouseX - imageX;
        imageHeight = mouseY - imageY;
        break;
      case 3:
        //bottom-left
        imageX = mouseX;
        imageWidth = imageRight - mouseX;
        imageHeight = mouseY - imageY;
        break;
    }

    if(imageWidth<25){imageWidth=25;}
    if(imageHeight<25){imageHeight=25;}

    // set the image right and bottom
    imageRight = imageX + imageWidth;
    imageBottom = imageY + imageHeight;

    // redraw the image with resizing anchors
    draw(true, true);

  } else if (draggingImage) {

    imageClick = false;

    mouseX = parseInt(e.clientX - offsetX);
    mouseY = parseInt(e.clientY - offsetY);

    // move the image by the amount of the latest drag
    var dx = mouseX - startX;
    var dy = mouseY - startY;
    imageX += dx;
    imageY += dy;
    imageRight += dx;
    imageBottom += dy;
    // reset the startXY for next time
    startX = mouseX;
    startY = mouseY;

    // redraw the image with border
    draw(false, true);

  }


}

$("#editorCanvas").mousedown(function (e) {
  handleMouseDown(e);
});
$("#editorCanvas").mousemove(function (e) {
  handleMouseMove(e);
});
$("#editorCanvas").mouseup(function (e) {
  handleMouseUp(e);
});
$("#editorCanvas").mouseout(function (e) {
  handleMouseOut(e);
});

function rotate(rotationPointX,rotationPointY,degreeRotation){

  // Create an second in-memory canvas:
  var mCanvas=document.createElement('canvas');
  mCanvas.width=canvas.width;
  mCanvas.height=canvas.height;
  var mctx=mCanvas.getContext('2d');

  // Draw your canvas onto the second canvas
  mctx.drawImage(canvas,0,0);

  // Clear your main canvas
  ctx.clearRect(0,0,canvas.width,canvas.height);

  // Rotate the main canvas

  // set the rotation point as center of the canvas
  // (but you can set any rotation point you desire)
  ctx.translate(rotationPointX,rotationPointY);

  // rotate by 90 degrees (==PI/2)
  var radians=degreeRotation/180*Math.PI;
  ctx.rotate(radians);


  // Draw the second canvas back to the (now rotated) main canvas:
  ctx.drawImage(mCanvas,-canvas.width/2,-canvas.height/2);

  // clean up -- unrotate and untranslate
  ctx.rotate(-radians);
  ctx.translate(-canvas.width/2,-canvas.height/2);

}

$('#rotate').click(function(){
  rotate(canvas.width/2,canvas.height/2,90);
});

我认为有一种方法可以做到这一点,我不完全确定需要更改的内容或代码中的错误。

所以我的问题是如何更改代码以允许比例缩放?

1 个答案:

答案 0 :(得分:0)

我实际上通过编辑handleMouseMove(e)函数中的数学来解决这个问题,如下所示:

Cannot use web ui to deploy additional leaf nodes to hosts which already have at least one leaf node.

在我评论代码之前的位置是修复 - 这可以确保imageHeight通过使用最初计算的比率与imageWidth成比例。