调整画布图像位置问题的大小

时间:2015-06-17 22:45:07

标签: javascript jquery html html5-canvas window-resize

我使用HTML画布允许用户在瓶子上编辑(移动,调整大小和旋转)图像以创建自己的自定义图像 - 类似于T恤设计师的工作方式。

这一切都有效(虽然旋转有轻微问题)直到你调整屏幕大小。因为画布在我的页面上水平居中,所以当您从页面的初始加载减小(或增加)大小时 - 画布认为图像仍然在其原始位置。这意味着您无法单击图像来移动它,您必须向右或向左单击(取决于屏幕的大小调整方式)。

我认为数学存在问题,可能与调整屏幕大小时窗口或画布偏移未更新有关,但我无法解决问题所在。

示例:https://jsfiddle.net/mpsx1xnj/

代码如下:

<div id="design-canvas">
           <canvas id="bottleCanvas" width="400" height="600"></canvas>
           <center><canvas id="printableCanvas" width="71" height="245"></canvas></center>
           <center><canvas id="editorCanvas" width="400" height="600"></canvas></center>
           <p class="tooltip">Guidelines show the printable area on the bottle.</p>
       </div>

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 ratio;

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

  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) {
    offsetX = offsetX + window.pageXOffset;
    offsetY = offsetY + window.pageYOffset;

  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 = imageWidth/ratio; //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);

}

$(window).on("resize scroll",function(e) {

offsetX = win.left;
offsetY = canvasOffset.top;


  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);

    });

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

所以我的问题是如何解决这个问题,以便调整窗口大小没有问题?

1 个答案:

答案 0 :(得分:0)

如果我理解正确的话......

这是一个解决方案:jsFiddle

画布的宽度和高度属性确定画布坐标系的宽度或高度 - 页面调整大小仅更新css属性(使其响应),这意味着您的固定宽度/高度attrs始终保持不变,即使在调整大小。

所以页面调整大小

$('canvas#editorCanvas').attr('width', $('#design-canvas').width() ); $('canvas#editorCanvas').attr('height', $('#design-canvas').height() );

使用max-height,max-width和设置高度/宽度为100%

使容器响应