我想让用户旋转对象Fabric.js动力画布,但将其旋转限制为 90 度增量。想法是,当它们旋转然后停止时,物体会以最接近的角度“卡入”到位。
通过监听“object:rotating”,设置最近的角度,然后调用 object.setAngle(angleClosestTo90) 就可以了。然而,一旦对象被“捕捉”,缩放/旋转图像的控件就会关闭。您仍然可以选择它们,但它很挑剔 - 我猜该对象应该位于它的最后一个位置,而不是通过 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();
}
})
旋转盒子,然后松开鼠标。该对象将被选择,但尝试再次旋转它。指针很难找到/不可用。
如果您单击远离对象,然后重新选择(或旋转后仅移动对象),则可以。
在 setAngle() 之后运行 setCoords()。这将更新控件的位置。在你的小提琴中尝试过。工作正常。
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();
}
})
问候,
贝尼克
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)