我有一个带圆圈的画布和一个带连线的三角形。我正在尝试使用三角形作为箭头。如果两个对象中的任何一个被移动,我都希望箭头始终指向圆心。我以为可以用线的角度旋转三角形,但结果不尽人意,我敢肯定我的方法是错误的。
是否有解决此问题的建议或技巧?在我链接的JSFiddle中,您可以移动任意一个对象,并且三角形的角度也可以旋转,但这从来都不是正确的:
https://jsfiddle.net/zh1bkfs5/
const c = new fabric.Canvas('c');
c.preserveObjectStacking = true;
function radiansToDegrees (radians) {
return radians * 180 / Math.PI;
}
function calcAngle (opposite, adjacent) {
return radiansToDegrees(Math.atan(opposite / adjacent));
}
function syncObjects (e) {
const x1 = triangle.left;
const y1 = triangle.top;
const x2 = circle.left + circle.radius;
const y2 = circle.top + circle.radius;
line.set('x1', x1);
line.set('y1', y1);
line.set('x2', x2);
line.set('y2', y2);
const angle = calcAngle(y2 - y1, x1 - x2);
triangle.set('angle', -angle);
triangle.setCoords();
c.renderAll();
}
const circle = new fabric.Circle({
fill: 'black',
radius: 20,
top: 100,
left: 100,
hasBorders: false,
hasControls: false
});
const triangle = new fabric.Triangle({
fill: 'orange',
height: 20,
width: 20,
top: 50,
left: 120,
hasBorders: false,
hasControls: false,
originX: 'center',
originY: 'center'
});
const coords = [
triangle.left,
triangle.top,
circle.left + circle.radius,
circle.top + circle.radius
];
const line = new fabric.Line(coords, {
stroke: 'orange',
strokeWidth: 1,
selectable: false
});
c.add(circle, line, triangle);
c.on('object:moving', syncObjects);
答案 0 :(得分:1)
将您的syncObject函数的一部分更改为此:
const x = x1 - x2;
const y = y2 - y1;
const angle = calcAngle(x, y);
if(x < 0 && y > 0 || x > 0 && y > 0) {
triangle.set('angle', angle);
} else if(x < 0 && y < 0) {
triangle.set('angle', 180 + angle);
} if(x > 0 && y < 0) {
triangle.set('angle', -180 + angle);
}
这应该有效。您更新的小提琴https://jsfiddle.net/zh1bkfs5/30/
答案 1 :(得分:0)
更新后,我不再需要反转角度,因此将“相邻”和“相反”的值翻转了。我现在有99%的人,只是在某些情况下,三角形有时会以错误的方式翻转,但应该很容易修复,至少我最初的方法可行。
更新:https://jsfiddle.net/zh1bkfs5/1/
const c = new fabric.Canvas('c');
c.preserveObjectStacking = true;
function radiansToDegrees (radians) {
return radians * 180 / Math.PI;
}
function calcAngle (opposite, adjacent) {
return radiansToDegrees(Math.atan(opposite / adjacent));
}
function syncObjects (e) {
const x1 = triangle.left;
const y1 = triangle.top;
const x2 = circle.left + circle.radius;
const y2 = circle.top + circle.radius;
line.set('x1', x1);
line.set('y1', y1);
line.set('x2', x2);
line.set('y2', y2);
const angle = calcAngle(x1 - x2, y2 - y1);
triangle.set('angle', angle);
triangle.setCoords();
c.renderAll();
}
const circle = new fabric.Circle({
fill: 'black',
radius: 20,
top: 100,
left: 100,
hasBorders: false,
hasControls: false
});
const triangle = new fabric.Triangle({
fill: 'orange',
height: 20,
width: 20,
top: 50,
left: 120,
hasBorders: false,
hasControls: false,
originX: 'center',
originY: 'center'
});
const coords = [
triangle.left,
triangle.top,
circle.left + circle.radius,
circle.top + circle.radius
];
const line = new fabric.Line(coords, {
stroke: 'orange',
strokeWidth: 1,
selectable: false
});
c.add(circle, line, triangle);
c.on('object:moving', syncObjects);