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 に入れることはできません。mousedownアプリケーションでは、画像をパンし、マウスを使用してとmousemoveイベントを使用してキャンバスに何かを描画します。mouseupイベントでは、描いた画像全体を持っている必要がありますが、ImageDataを使用getImageDataすると、キャンバスに画像が表示されるだけです。パンされた画像がキャンバス サイズにトリミングされます。

4

1 に答える 1

1

@ Blindman67 が示唆したように、2 番目のキャンバスを作成できます。

イメージ内の最も離れたポイントを格納するオブジェクトを作成します。

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 コンソールを使用してパディングを調整できます。と入力してEnterimagePadding.top = 200キーを押し、キャンバスをクリックして最終的な画像を更新します。

imagePadding.top = 200

于 2020-07-10T11:57:15.723 に答える