温馨提示:本文翻译自stackoverflow.com,查看原文请点击:javascript - How to display another canvas without zoom in fabricjs
canvas fabricjs javascript

javascript - 如何在不放大fabricjs的情况下显示另一个画布

发布于 2020-04-13 09:51:49

简而言之,我正在开发一个项目,其中有两个画布:一个支持缩放和绘图的画布,另一个画布-第一个画布的副本,应该显示不缩放的一般视图。不幸的是,我不了解如何实现此功能,因为第二个画布还显示了缩放图片。请帮忙!这是我所拥有的一个小例子:

var c1 = document.getElementById("scale");
var c2 = document.getElementById("static");

var canvas = this.__canvas = new fabric.Canvas(c1, {
  isDrawingMode: true
});
var ctx1 = c1.getContext("2d");
var ctx2 = c2.getContext("2d");

function copy() {
    var imgData = ctx1.getImageData(0, 0, 512, 512);
    ctx2.putImageData(imgData, 0, 0);
}

fabric.Image.fromURL(
  "https://cdn-images-1.medium.com/max/1800/1*sg-uLNm73whmdOgKlrQdZA.jpeg",
  img => {
    img.scaleToWidth(canvas.width);
    canvas.setBackgroundImage(img);
    canvas.requestRenderAll();
  },
  {
    crossOrigin: "Annoymous"
  }
);

canvas.on('mouse:wheel', function(opt) {
  var delta = opt.e.deltaY;
  var pointer = canvas.getPointer(opt.e);
  var zoom = canvas.getZoom();
  zoom = zoom + delta/200;
  if (zoom > 20) zoom = 20;
  if (zoom < 0.01) zoom = 0.01;
  canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom);
  opt.e.preventDefault();
  opt.e.stopPropagation();
});
    

setInterval(() => {
    copy();
}, 10)
canvas {
  border: 1px solid black;
}
#static {
  position: relative;
  top: -300px;
  left: 500px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.1/fabric.min.js"> </script>

This is interactive canvas
<canvas id="scale" width="300" height="300"></canvas>

<canvas id="static"width="300" height="300"></canvas>

查看更多

提问者
Arkadiy Vinkovskiy
被浏览
92
AndreaBogazzi 2020-02-02 19:58

没有完美的解决方案,因为fabricJS不支持在更多目标上进行渲染。

这里有一个toCanvasElement方法可创建到另一个画布的副本,但是它不允许您指定要在其上绘制的画布。

所以这里我在做什么,在某个时候:

  • 将缩放重置为1
  • 渲染到新画布
  • 将变焦恢复到原来的水平
  • 将该画布复制到静态画布上

有一个额外的副本,可以在现代硬件上快速运行,以至于您根本不在乎,但最好在toCanvasElement方法中添加canvas参数,以便立即在指定的画布上进行绘制

除此之外,在发射该副本时还有一个问题。“ after:render”不是一个好主意,它会永远循环播放,并且还会在缩放更改时重新绘制,这不是您想要的。

现在我使用object:add,也可以添加object:modified,也许还有其他东西,但是理想情况下,当您运行某些会更改某些图形属性的代码时,可以在需要时手动调用副本。

var c1 = document.getElementById("scale");
var c2 = document.getElementById("static");

var canvas = this.__canvas = new fabric.Canvas(c1, {
  isDrawingMode: true
});
var ctx2 = c2.getContext("2d");

function copy(copiedCanvas) {
   ctx2.drawImage(copiedCanvas,0,0);
}

fabric.Image.fromURL(
  "https://cdn-images-1.medium.com/max/1800/1*sg-uLNm73whmdOgKlrQdZA.jpeg",
  img => {
    img.scaleToWidth(canvas.width);
    canvas.setBackgroundImage(img);
    canvas.requestRenderAll();
  },
  {
    crossOrigin: "Annoymous"
  }
);

canvas.on('mouse:wheel', function(opt) {
  var delta = opt.e.deltaY;
  var pointer = canvas.getPointer(opt.e);
  var zoom = canvas.getZoom();
  zoom = zoom + delta/200;
  if (zoom > 20) zoom = 20;
  if (zoom < 0.01) zoom = 0.01;
  canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom);
  opt.e.preventDefault();
  opt.e.stopPropagation();
});

function afterRender() {
  var originalVP = canvas.viewportTransform;
  canvas.viewportTransform = [1, 0, 0, 1, 0, 0];
  copy(canvas.toCanvasElement());
  canvas.viewportTransform = originalVP;
}

canvas.on('object:added', afterRender);
canvas.on('object:modified', afterRender);
canvas {
  border: 1px solid black;
}
#static {
  position: relative;
  top: -300px;
  left: 500px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.1/fabric.min.js"> </script>

This is interactive canvas
<canvas id="scale" width="300" height="300"></canvas>

<canvas id="static"width="300" height="300"></canvas>