【问题标题】:fabric.js rotate object around canvas center smoothlyfabric.js 围绕画布中心平滑旋转对象
【发布时间】:2021-10-11 18:21:15
【问题描述】:

我尝试使用滑块围绕画布中心平滑旋转对象, 我使用fabric.util.rotatePoint 找到新的中心点并设置新的角度,但它似乎不完全围绕中心点并且对象位置在跳跃。

https://jsfiddle.net/j0g1tLsb/26/

这是我的代码:

const canvas = new fabric.Canvas('c', { width: innerWidth, height: innerHeight });
canvas.controlsAboveOverlay = true;
canvas.preserveObjectStacking = true;

const rect = new fabric.Rect({
    width: 300,
  height: 150,
  left: 400,
  top: 400,
  fill: "lightgray",
    originX: 'center',
  originY: 'center'
});

const centerPoint = new fabric.Circle({ 
   originX: 'center',
   originY: 'center',
   top: innerHeight/2, 
   left: innerWidth/2,
   radius: 10, 
   fill: 'red',
   hasControls: false,
   selectable:false
});


const log = new fabric.Text('', {
    left: 30,
  top: 30,
  originX: 'left',
  originY: 'top',
  fontSize: 18,
  evented: false,
  selectable: false
});

canvas.add(rect, centerPoint, log);

document.getElementById('img-rotation').oninput = function() {
      rect.set('angle', this.value);

      var posNewCenter = fabric.util.rotatePoint(
                            rect.getCenterPoint(),
                            canvas.getVpCenter(),
                            fabric.util.degreesToRadians(this.value)
                        );

                        rect.set({
                            left: posNewCenter.x,
                            top: posNewCenter.y,
                            angle: this.value
                        });

      log.set('text', `angle: ${Math.round(rect.angle)} \nleft: ${rect.left} \ntop: ${rect.top}`);
      canvas.requestRenderAll();
    };


rect.on('modified', () => {
    log.set('text', `angle: ${Math.round(rect.angle)} \nleft: ${rect.left} \ntop: ${rect.top}`);
  canvas.renderAll();
});

【问题讨论】:

    标签: fabricjs


    【解决方案1】:

    您的问题是每次都从矩形获取中心点。您只需从原始矩形位置设置新点。

    var posNewCenter = fabric.util.rotatePoint(
        new fabric.Point(400, 400), //here is your mistake
        canvas.getVpCenter(),
        fabric.util.degreesToRadians(this.value)
    );
    rect.set({
        left: posNewCenter.x,
        top: posNewCenter.y,
        angle: this.value
    });
    

    工作fiddle

    更新:

    为了修改矩形,您需要使用object:modified 事件重新分配topleft 坐标。

    首先声明 top 和 left 变量并在矩形对象中使用它们:

    let top = 400;
    let left = 400;
    const rect = new fabric.Rect({
      ...
      left: left,
      top: top,
      ...
      targetObj: 'rectangle' //you can use any value or ID, it's only for targeting purpose
    });
    

    然后您需要检查对象何时被修改。如果事件被触发,则检查它是否是矩形。

    canvas.on('object:modified', (e) => {
        if (e.target.hasOwnProperty('targetObj') && e.target.targetObj === 'rectangle') {
        left = e.target.get('left');
        top = e.target.get('top');
      }
    })
    

    最后,在滑块的 oninput 事件中使用 left 和 top 变量:

    var posNewCenter = fabric.util.rotatePoint(
        new fabric.Point(left, top),
        canvas.getVpCenter(),
        fabric.util.degreesToRadians(this.value)
    );
    

    工作更新fiddle

    【讨论】:

    • 感谢@Observer,当矩形位于其原始位置时它确实有效,但是如果我将矩形移动到新位置然后滑动,它仍然使用(400,400)作为它的中心点但没有更新到新位置。
    • 我尝试添加一个rectCenter来记录中心值,还是不行jsfiddle.net/j0g1tLsb/67
    猜你喜欢
    • 2018-08-07
    • 2013-08-04
    • 2016-09-10
    • 2014-12-27
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 2017-02-06
    • 1970-01-01
    相关资源
    最近更新 更多