在Fabric.js中使用setAngle()后,旋转和缩放控件关闭 [英] Rotation and Scaling controls are off after using setAngle() in Fabric.js

查看:1336
本文介绍了在Fabric.js中使用setAngle()后,旋转和缩放控件关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让用户旋转 Fabric.js 动力画布上的对象,但将其旋转限制为90度增量。想法是,当他们旋转然后停止时,对象将以最接近的角度捕捉到位。

I want to let users rotate objects on the Fabric.js powered canvas, but limit their rotation to 90 deg increments. Idea is that as they rotate and then stop, the object would "snap" into place at the closest angle.

通过收听对象:旋转设置最接近的角度,然后调用object.setAngle(angleClosestTo90)。但是,一旦对象被捕捉,用于缩放/旋转图像的控件就会关闭。你仍然可以选择它们,但它很脆弱 - 我想对象应该在它的最后一个位置,而不是通过setAngle()重新计算。

This works okay by listening to "object:rotating", setting the closest angle, then calling object.setAngle(angleClosestTo90). However, once the object has been "snapped", the controls for scaling/rotating the image are off. You can still select them, but it's finicky - I guess the object is expected to be at it's last location, not the one recalculated via setAngle().

这个JSFiddle 演示了这个问题:

var canvas = new fabric.Canvas("c");

var rect = new fabric.Rect({
  left: 100,
  top: 100,
  fill: 'red',
  width: 90,
  height: 90
});

canvas.add(rect);
canvas.renderAll();

var lastClosestAngle = 0,
    snapAfterRotate = false;

function calculateClosestAngle(targetObj) {
  // if angle > 360 then mod 360
  var currentAngle = targetObj.angle;
  var normalizedAngle = Math.abs(Math.round(Math.asin(Math.sin(currentAngle * Math.PI/360.0)) * 360.0/Math.PI));
  console.log("normalized: ", normalizedAngle);
  snapAfterRotate = true;
  if (normalizedAngle >= 45 && normalizedAngle < 135) {
    return 90;
  } else if (normalizedAngle >= 135 && normalizedAngle < 225) {
    return 180;
  } else if (normalizedAngle >= 225 && normalizedAngle < 315) {
    return 270;
  } else if ((normalizedAngle >= 315 && normalizedAngle <= 360) || (normalizedAngle >= 0 && normalizedAngle < 45)) {
    return 0;
  }
  return currentAngle;
}

canvas.on("object:rotating", function(rotEvtData) {
  var targetObj = rotEvtData.target;
  lastClosestAngle = calculateClosestAngle(targetObj);
});

canvas.on("object:modified", function(modEvtData) {
  // modified fires after object has been rotated 
  var modifiedObj = modEvtData.target;
  if (modifiedObj.angle && snapAfterRotate) {
      modifiedObj.setAngle(lastClosestAngle);
      snapAfterRotate = false;
      canvas.renderAll();
  }
})

旋转框,然后放开鼠标。将选择对象,但尝试再次旋转它。指针很难找到/不可用。

Rotate the box, then let go of the mouse. The object will be selected, but try to rotate it again. The pointer is hard to find/unavailable.

如果你点击远离对象,然后重新选择(或旋转后移动对象),这是很好。

If you click away from the object, then reselect (or just move the object after rotating), it is fine.

推荐答案

在setAngle()之后运行setCoords()。这将更新控件的位置。试着在你的小提琴。工作正常。

Run setCoords() after setAngle(). This will update the position of the controls. Tried it in your fiddle. Works fine.

   canvas.on("object:modified", function(modEvtData) {
     // modified fires after object has been rotated 
     var modifiedObj = modEvtData.target;
     if (modifiedObj.angle && snapAfterRotate) {
         modifiedObj.setAngle(lastClosestAngle).setCoords();
         snapAfterRotate = false;
         canvas.renderAll();
     }
   })

问候,
Benick

regards, Benick

这篇关于在Fabric.js中使用setAngle()后,旋转和缩放控件关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆