将Fabric JS中的画布平移限制为边界?

时间:2017-01-03 20:44:44

标签: javascript html5-canvas fabricjs

我使用Fabric JS画布实现了画布平移,使用以下代码:

canvas.on("mouse:down", function(e) {
  panning = true;
});

canvas.on("mouse:up", function(e) {
  panning = false;
});

canvas.on("mouse:move", function(e) {
  if (panning) {
    var delta = new fabric.Point(e.e.movementX, e.e.movementY);
    canvas.relativePan(delta);
  }
});

这样可以正常工作,但您可以向任何方向无限滚动/平移。我想将其限制为边界,以便较小的画布实际上是较大绘图区域的视图。例如400 x 400像素的画布,它不允许你平移超过1000 X 1000像素区域。我在Fabric JS canvas对象中看到有一个viewportTransform[]数组,它在字段[0]中保存缩放级别,在字段[4]和[5]中保存X和Y偏移但不确定如何最好地实现平移边界。是否有Fabric功能可以使这个工作?

我还必须考虑缩放级别(我正在使用canvas.setZoom())并且不希望用户拖动对象超出平移边界(这可能是一个单独的问题!)。

有什么想法吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

FabricJS网页上已经有关于它的教程,它可以通过鼠标滚轮使用,但是您可以对其进行调整:http://fabricjs.com/fabric-intro-part-5

我用一些按钮做到了。

首先,我必须告诉您缩放和平移会影响画布的viewportTransform属性,该属性是一个矩阵,类似于css transform属性的工作原理(或者我相信是这样...)。

这些是我在工作时在控制台中获得的一些输出:

originalViewporTransform (6)[1、0、0、1、0、0]

缩放 影响索引0和3

zoomViewporTransform(6)[1.2,0,0,1.2,0,0] zoomViewporTransform(6)[1.44,0,0,1.44,0,0]

平移

右: 影响指数4

panningViewporTransform(6)[1.44,0,0,1.44,-82,0] panningViewporTransform(6)[1.44,0,0,1.44,-83,0]

左: 影响指数4

panningViewporTransform(6)[1.728,0,0,1.728,259,0] panningViewporTransform(6)[1.728,0,0,1.728,260,0]

底部: 影响指数5 panningViewporTransform(6)[1.728,0,0,1.728,0,-241] panningViewporTransform(6)[1.728,0,0,1.728,0,-242]

顶部: 影响指数5 panningViewporTransform(6)[1.728,0,0,1.728,0,305] panningViewporTransform(6)[1.728,0,0,1.728,0,306]

这是我在四个方向上使用按钮控制平移的功能。要限制顶部和左侧平移,只要将相应的视口设置为0即可。关于左右平移时,必须输入要考虑的边界的数字大小。我当时在考虑画布的大小,但是您可以使用所需的任何大小。

...
else if (this.actualCanvasViewportTransform[4] < this.canvas.getWidth() - (this.canvas.getWidth() * this.actualCanvasZoom))
...

在这些行上,您必须按照所需的大小更改(this.canvas.getWidth()* this.actualCanvasZoom),

(pxLimitRight * this.actualCanvasZoom)

希望有帮助

whileMouseDown(caseType){

   if (this.actualCanvasZoom <= this.originalCanvasZoom) return;

   const units = 1;
   let   delta;

   switch (caseType) {
      case 'right':
        delta = new fabric.Point(-units,0);
        break;
      case 'left':
        delta = new fabric.Point(units,0);
        break;
      case 'bottom':
        delta = new fabric.Point(0,-units);
        break;
      case 'top':
        delta = new fabric.Point(0,units);
        break;
    }

this.canvas.relativePan(delta);

// console.log('panningViewporTransform', this.canvas.viewportTransform, this.actualCanvasZoom);

    this.actualCanvasViewportTransform = this.canvas.viewportTransform;

    /*
    WE ARE PANNING LEFT AND RIGHT
    */
    if (this.actualCanvasViewportTransform[4] >= 0) {
      // WE ARE GOING LEFT
      this.actualCanvasViewportTransform[4] = 0;

    } else if (this.actualCanvasViewportTransform[4] < this.canvas.getWidth() - (this.canvas.getWidth() * this.actualCanvasZoom)) 
    {
      // WE ARE GOING RIGHT
      this.actualCanvasViewportTransform[4] = this.canvas.getWidth() - (this.canvas.getWidth() * this.actualCanvasZoom);

    }


    /*
    WE ARE PANNING DOWN AND UP
    */
    if (this.actualCanvasViewportTransform[5] >= 0) {
      // WE ARE GOING UP
      this.actualCanvasViewportTransform[5] = 0;

    } else if (this.actualCanvasViewportTransform[5] < this.canvas.getHeight() - (this.canvas.getHeight() * this.actualCanvasZoom)) {
      // WE ARE GOING DOWN
      this.actualCanvasViewportTransform[5] = this.canvas.getHeight() - (this.canvas.getHeight() * this.actualCanvasZoom);

    }

 }