【问题标题】:Limit canvas panning in Fabric JS to a boundary?将 Fabric JS 中的画布平移限制为边界?
【发布时间】:2017-05-18 01:11:03
【问题描述】:

我已经使用 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 画布对象中看到有一个 viewportTransform[] 数组,它保存字段 [0] 中的缩放级别以及字段 [4] 和 [5] 中的 X 和 Y 偏移量,但不确定如何最好地实现平移边界。是否有 Fabric 函数可以完成这项工作?

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

有什么想法吗?

谢谢!

【问题讨论】:

标签: javascript html5-canvas fabricjs


【解决方案1】:

FabricJS 网页中已经有一个关于它的教程,它适用于鼠标滚轮,但你可以调整它:http://fabricjs.com/fabric-intro-part-5

我用一些按钮做到了。

首先我要告诉你,缩放和平移会影响画布 viewportTransform 属性,它是一个矩阵,类似于 css 变换属性的工作原理(或者我相信...)。

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

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);

    }

 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-13
    • 2017-08-07
    • 1970-01-01
    • 2014-05-19
    • 2018-06-24
    • 2021-12-23
    • 2017-03-02
    • 2021-08-13
    相关资源
    最近更新 更多