在fabricjs中旋转整个画布

1 javascript canvas rotation fabricjs

有没有办法在Fabric.js中旋转画布?

我不希望旋转每个元素,这可以轻松实现,而是一种旋转整个画布的方法,类似于在本机画布元素上使用 canvas.rotate() 实现的效果:

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.rotate(20*Math.PI/180);
Run Code Online (Sandbox Code Playgroud)

从 Fabric.js 访问画布元素getContext()是可能的,但如果我这样做然后旋转它,则只有两个画布之一正在旋转,并且选择/绘图严重关闭,并且绘图/选择/等也不再工作。

我在这里有些不知所措。如果目前Fabric.js无法做到这一点,我将在 github 上创建一个票证,但不知何故感觉它应该是可能的......

[编辑]

在 Ian 的输入之后,我已经弄清楚了一些事情,并且现在可以旋转画布并获得一些结果。然而,物体距离正确位置非常远。然而,这可能是因为,在旋转时,我也在缩放和绝对平移画布(使用canvas.setZoom()和canvas.absolutePan())。我想我会在 GitHub 上创建一个票证,看看开发人员的想法。有点卡在这里......仅供参考,这里是代码片段:

setAngle: function(angle) {
    var self = this;

    var canvas = self.getFabricCanvas();
    var group = new fabric.Group();
    var origItems = canvas._objects;
    var size = self.getSize();

    group.set({width: size.width, height: size.height, left: size.width / 2, top: size.height / 2, originX: 'center', originY: 'center', centeredRotation: true})

    for (var i = 0; i < origItems.length; i++) {
        group.add(origItems[i]);
    }

    canvas.add(group);
    group.set({angle: (-1 * self.getOldAngle())});
    canvas.renderAll();
    group.set({angle: angle});
    canvas.renderAll();

    items = group._objects;
    group._restoreObjectsState();
    canvas.remove(group);

    for (var i = 0; i < items.length; i++) {
        canvas.add(items[i]);
        canvas.remove(origItems[i]);
    }

    canvas.renderAll();

    self.setOldAngle(angle);
},
Run Code Online (Sandbox Code Playgroud)

如上所述,该函数与其他两个函数一起调用:

setPosition: function(left, top) {
    var self = this;

    if (left < 0) {
        left = 0;
    }
    if (top < 0) {
        top = 0;
    }

    var point = new fabric.Point(left, top);
    self.getFabricCanvas().absolutePan(point);
},

setZoom: function(zoom) {
    var self = this;

    self.getFabricCanvas().setZoom(zoom);
},
Run Code Online (Sandbox Code Playgroud)

这些函数是通过以下代码调用的:

MyClass.setZoom(1);

MyClass.setPosition(left, top);
MyClass.setZoom(zoom);
MyClass.setAngle(angle);
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我尝试最后设置角度,但当我这样做时并没有什么区别(至少在视觉上没有区别)。开始时将缩放设置为 1 很重要,否则平移将无法正常工作。

也许有人有一个想法......

cby*_*016 6

这是我的做法(基于此 js fiddle 的代码)。

rotate (degrees) {

  let canvasCenter = new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2) // center of canvas
  let radians = fabric.util.degreesToRadians(degrees)

  canvas.getObjects().forEach((obj) => {
      let objectOrigin = new fabric.Point(obj.left, obj.top)
      let new_loc = fabric.util.rotatePoint(objectOrigin, canvasCenter, radians)
      obj.top = new_loc.y
      obj.left = new_loc.x
      obj.angle += degrees //rotate each object by the same angle
      obj.setCoords()
  });

  canvas.renderAll()


},
Run Code Online (Sandbox Code Playgroud)

完成此操作后,我还必须调整画布背景和大小,以便对象不会脱离画布。