在HTML5画布中移动裁剪的图像

时间:2017-07-01 14:51:34

标签: javascript html5 canvas html5-canvas

如何将裁剪后的图像向下移动100px并在画布内放置50px?包括jsfiddle链接。

的Javascript

// Grab the Canvas and Drawing Context
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');



// Create an image element
var img = document.createElement('IMG');

// When the image is loaded, draw it
img.onload = function () {

// Save the state, so we can undo the clipping
ctx.save();


// Create a shape, of some sort
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(100, 30);
ctx.lineTo(180, 10);
ctx.lineTo(200, 60);
ctx.arcTo(180, 70, 120, 0, 10);
ctx.lineTo(200, 180);
ctx.lineTo(100, 150);
ctx.lineTo(70, 180);
ctx.lineTo(20, 130);
ctx.lineTo(50, 70);
ctx.closePath();
// Clip to the current path
ctx.clip();


ctx.drawImage(img, 0, 0);

// Undo the clipping
ctx.restore();
}

// Specify the src to load the image
img.src = "http://i.imgur.com/gwlPu.jpg";

html

<canvas id="c" width="400" height="400"></canvas>

的jsfiddle http://jsfiddle.net/dDUC3/3805/

3 个答案:

答案 0 :(得分:0)

您应该首先在所需位置创建形状,这将是合适的解决方案。

但是,在此阶段,您可以使用 getImageData() putImageData() 方法来完成动作......

&#13;
&#13;
// Grab the Canvas and Drawing Context
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');

// Create an image element
var img = document.createElement('IMG');

// When the image is loaded, draw it
img.onload = function() {

   // Save the state, so we can undo the clipping
   ctx.save();

   // Create a shape, of some sort
   ctx.beginPath();
   ctx.moveTo(10, 10);
   ctx.lineTo(100, 30);
   ctx.lineTo(180, 10);
   ctx.lineTo(200, 60);
   ctx.arcTo(180, 70, 120, 0, 10);
   ctx.lineTo(200, 180);
   ctx.lineTo(100, 150);
   ctx.lineTo(70, 180);
   ctx.lineTo(20, 130);
   ctx.lineTo(50, 70);
   ctx.closePath();
   // Clip to the current path
   ctx.clip();

   ctx.drawImage(img, 0, 0);

   // Undo the clipping
   ctx.restore();
   move(50, 100); //move left: 50px, down: 100px
}

// Set cross origin for the image, as it's not hosted on local server
img.crossOrigin = 'anonymous';

// Specify the src to load the image
img.src = "http://i.imgur.com/gwlPu.jpg";

function move(left, down) {
   var croppedImage = ctx.getImageData(0, 0, 200, 200);
   ctx.clearRect(0, 0, canvas.width, canvas.height); //clear canvas
   ctx.putImageData(croppedImage, 0 + left, 0 + down);
}
&#13;
canvas {
   background: #CEF;
}
&#13;
<canvas id="c" width="400" height="400"></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

安全的画布剪切和粘贴

由于与ctx.getImageData相关联的跨域安全违规行为以及您域外的图片,给定答案在许多情况下都会失败。

直接复制&amp;粘贴

如果您将图像移动为方形区域,或者它与原始图像不重叠,则可以直接从画布中复制。

ctx.drawImage(ctx.canvas, 0, 0, 200, 200, 100, 100, 200, 200);

直接切割&amp;粘贴

由于您需要清除一些重叠,您可以分两部分复制

// move bottom half
ctx.drawImage(ctx.canvas, 0, 100, 200, 100, 100, 200, 200, 100); 
// clear bottom half
ctx.clearRect(0, 100, 200, 100);
// move top half
ctx.drawImage(ctx.canvas, 0, 0, 200, 100, 100, 100, 200, 100); 
// lear top half
ctx.clearRect(0, 0, 200, 100);

但这仍然有点问题。

一般剪切和粘贴

理想的解决方案是创建一个临时画布来保存图像,以便可以移动它。它不会受到重叠的影响,如果画布被交叉原始数据污染也不会失败。

function cutFromCanvas(ctx, x, y, w, h){
    const cut = document.createElement("canvas");
    cut.width = w;
    cut.height = h;
    cut.getContext("2d").drawImage(ctx.canvas, -x, -y, w, h, 0, 0, w, h);
    ctx.clearRect(x, y, w, h);
    return cut;
}

然后在新位置过去只绘制图像

  ctx.drawImage(cutFromCanvas(ctx, 0, 0 200, 200), 100, 100);

答案 2 :(得分:0)

正如@gaand所说,最好的方法是将你的剪裁形状移动到应有的位置。 这可以在不使用setTransform修改路径声明的情况下完成。

&#13;
&#13;
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
img.onload = function() {

  // move everything
  ctx.setTransform(1, 0, 0, 1, 100, 100);

  ctx.save();
  ctx.beginPath();
  ctx.moveTo(10, 10);
  ctx.lineTo(100, 30);
  ctx.lineTo(180, 10);
  ctx.lineTo(200, 60);
  ctx.arcTo(180, 70, 120, 0, 10);
  ctx.lineTo(200, 180);
  ctx.lineTo(100, 150);
  ctx.lineTo(70, 180);
  ctx.lineTo(20, 130);
  ctx.lineTo(50, 70);
  ctx.closePath();
  ctx.clip();
  ctx.drawImage(img, 0, 0);

  // to restore the original matrix
  ctx.setTransform(1, 0, 0, 1, 100, 100);

  // but it's also restored here anyway...
  ctx.restore();

};

img.src = "http://i.imgur.com/gwlPu.jpg";
&#13;
canvas {
  background: lightblue
}
&#13;
<canvas id="c" width="500" height="300"></canvas>
&#13;
&#13;
&#13;

但是如果你真的需要在绘制后移动你的绘图,那么最好的方法是使用一个屏幕外的画布,你将在其上生成剪切的图像,最后在可见的一个上绘制你想要的屏幕外画布:

&#13;
&#13;
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
var clippedCanvas = document.createElement('canvas');
var clippedCtx = clippedCanvas.getContext('2d');
img.onload = function() {
  //prepare our offscreen canvas
  clippedCanvas.width = this.width;
  clippedCanvas.height = this.height;
  // generate the drawing on the offscreen ctx
  clippedCtx.save();
  clippedCtx.beginPath();
  clippedCtx.moveTo(10, 10);
  clippedCtx.lineTo(100, 30);
  clippedCtx.lineTo(180, 10);
  clippedCtx.lineTo(200, 60);
  clippedCtx.arcTo(180, 70, 120, 0, 10);
  clippedCtx.lineTo(200, 180);
  clippedCtx.lineTo(100, 150);
  clippedCtx.lineTo(70, 180);
  clippedCtx.lineTo(20, 130);
  clippedCtx.lineTo(50, 70);
  clippedCtx.closePath();
  clippedCtx.clip();
  clippedCtx.drawImage(img, 0, 0);

  // now we can our composed image anywhere in th visible canvas
  ctx.drawImage(clippedCanvas, 100,100);

};

img.src = "http://i.imgur.com/gwlPu.jpg";
&#13;
canvas {
  background: lightblue
}
&#13;
<canvas id="c" width="500" height="300"></canvas>
&#13;
&#13;
&#13;

但是对于一次性,您可能会发现声明一个新的canvas元素很麻烦。所以第三种选择是使用globalCompositeOperation 'copy',它允许我们在不保留以前状态的情况下绘制画布:

&#13;
&#13;
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
img.onload = function() {

  ctx.save();
  ctx.beginPath();
  ctx.moveTo(10, 10);
  ctx.lineTo(100, 30);
  ctx.lineTo(180, 10);
  ctx.lineTo(200, 60);
  ctx.arcTo(180, 70, 120, 0, 10);
  ctx.lineTo(200, 180);
  ctx.lineTo(100, 150);
  ctx.lineTo(70, 180);
  ctx.lineTo(20, 130);
  ctx.lineTo(50, 70);
  ctx.closePath();
  ctx.clip();
  ctx.drawImage(img, 0, 0);
  ctx.restore();

  // the magic
  ctx.globalCompositeOperation = 'copy';
  // draw the canvas over itself, at 100 100
  ctx.drawImage(canvas, 100,100);

};

img.src = "http://i.imgur.com/gwlPu.jpg";
&#13;
canvas {
  background: lightblue
}
&#13;
<canvas id="c" width="500" height="300"></canvas>
&#13;
&#13;
&#13;

现在我们已经发现了gCO,我们甚至可以删除这个裁剪操作:

&#13;
&#13;
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
img.onload = function() {
  // move everything
  ctx.setTransform(1,0,0,1,100,100);
  ctx.beginPath();
  ctx.moveTo(10, 10);
  ctx.lineTo(100, 30);
  ctx.lineTo(180, 10);
  ctx.lineTo(200, 60);
  ctx.arcTo(180, 70, 120, 0, 10);
  ctx.lineTo(200, 180);
  ctx.lineTo(100, 150);
  ctx.lineTo(70, 180);
  ctx.lineTo(20, 130);
  ctx.lineTo(50, 70);
  // we draw this shape
  ctx.fill();
  // new pixels will be drawn only where they do overlap with existing ones
  ctx.globalCompositeOperation = 'source-in';
  ctx.drawImage(img, 0, 0);
  // restore the matrix
  ctx.setTransform(1,0,0,1,0,0);
};

img.src = "http://i.imgur.com/gwlPu.jpg";
&#13;
canvas {
  background: lightblue
}
&#13;
<canvas id="c" width="500" height="300"></canvas>
&#13;
&#13;
&#13;