1

我有一种情况,ImageData即使在平移图像之后,我也需要在画布内获得全部内容。

提前致谢

小提琴中的示例:https ://jsfiddle.net/z46cvm9h/

<canvas id="canvas"></canvas>
<button onclick="showImage()">
Show panned Image
</button>
<img id="image" src='' />
var context     = canvas.getContext("2d");
canvas.width    = 400;
canvas.height   = 300;

var global = {
scale : 1,
offset    : {
 x : 0,
 y : 0,
},
};
var pan = {
start : {
 x : null,
 y : null,
},
offset : {
 x : 0,
 y : 0,
},
};

function draw() {
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);

context.translate(pan.offset.x, pan.offset.y);

context.beginPath();
context.rect(50, 50, 100, 100);
context.fillStyle = 'skyblue';
context.fill();

context.beginPath();
context.arc(350, 250, 50, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();

}

draw();

canvas.addEventListener("mousedown", startPan);
canvas.addEventListener("mouseleave", endPan);
canvas.addEventListener("mouseup", endPan);

function startPan(e) {
canvas.addEventListener("mousemove", trackMouse);
canvas.addEventListener("mousemove", draw);
pan.start.x = e.clientX;
pan.start.y = e.clientY;
}

function endPan(e) {
canvas.removeEventListener("mousemove", trackMouse);
pan.start.x = null;
pan.start.y = null;
global.offset.x = pan.offset.x;
global.offset.y = pan.offset.y;
}

function trackMouse(e) {
var offsetX    = e.clientX - pan.start.x;
var offsetY    = e.clientY - pan.start.y;
pan.offset.x = global.offset.x + offsetX;
pan.offset.y = global.offset.y + offsetY;
}

function showImage(){
document.getElementById('image').src = canvas.toDataURL();
}

PS:JSFiddle是为了演示,我不能把确切的场景放到JSFiddle中。在应用程序中,我平移图像,然后使用鼠标使用mousedownmousemove事件在画布上绘制一些东西。在mouseup活动中,我需要拥有ImageData我绘制的完整图像,但是当使用 时getImageData,我只会让图像出现在画布上。平移的图像被裁剪为画布大小。

4

1 回答 1

1

正如@Blindman67 建议的那样,您可以制作第二张画布。

创建一个对象来存储图像中最远的点。

const imagePadding = {
  top: 0,
  right: 0,
  bottom: 0,
  left: 0
}

top应为绘图的最高点,right应为最右侧的点,依此类推。出于演示目的,填充设置为等于您在每个方向上平移的距离。您将希望将其设置为在每个方向(上、右、下和左——这些是我正在谈论的方向)上最远的图形的形状/点。

function panImage(e) {
  pan.x += e.movementX
  pan.y += e.movementY
  drawPreview()
  
  imagePadding.top = Math.max(imagePadding.top, pan.y)
  imagePadding.left = Math.max(imagePadding.left, pan.x)
  imagePadding.bottom = Math.max(imagePadding.bottom, -pan.y)
  imagePadding.right = Math.max(imagePadding.right, -pan.x)
}

要绘制完整图像,您可以创建如下函数:

function drawFinalImage() {
  const canvas = document.createElement('canvas')
  const ctx = canvas.getContext('2d')
  const pannedImage = document.getElementById('image')

  canvas.width = previewCanvas.width + imagePadding.left + imagePadding.right
  canvas.height = previewCanvas.height + imagePadding.top + imagePadding.bottom

  ctx.translate(imagePadding.left, imagePadding.top)
  drawShapes(ctx)

  pannedImage.src = canvas.toDataURL()
}

有关演示以及如何实现代码,请参阅JSFiddle 。如果有什么我应该更好地解释的,请告诉我。

您可以使用 JSFiddle Console 来调整填充。键入imagePadding.top = 200,按回车键,然后单击画布以更新最终图像。

imagePadding.top = 200

于 2020-07-10T11:57:15.723 回答