【发布时间】:2015-08-15 08:10:02
【问题描述】:
使用http://fabricjs.com/的stickman示例, 我一直试图在移动一条线时移动相关的圆圈。示例中的代码结构不合理、繁重且有错误:),因为我无法对称地移动相关圆圈。
如果在//移动其他圆圈部分使用下一行
obj.set({ '左': (s.calcLinePoints().x1 + _l), '顶部': (-s.calcLinePoints().y1 + _t) });
- 不同之处在于 y1 收集信息的符号我们在视觉上移动了一些水平线结果OK,但在我看来这种“调整”不是正确的......
[示例代码]
$(function() {
//create the fabriccanvas object & disable the canvas selection
var canvas = new fabric.Canvas('c', {
selection: false
});
//move the objects origin of transformation to the center
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
function makeCircle(left, top, line1, line2, usedLine, usedEnd) {
//used line - used line for the center
//usedEnd - fromt the used line
var c = new fabric.Circle({
left: left,
top: top,
strokeWidth: 2,
radius: 6,
fill: '#fff',
stroke: '#666'
});
c.hasControls = c.hasBorders = false;
c.line1 = line1;
c.line2 = line2;
//add information which line end is used for center
var _usedLineName;
if (usedLine == 1) {
_usedLineName = line1.name;
} else {
_usedLineName = line2.name;
}
c.usedLineName = _usedLineName;
c.usedEndPoint = usedEnd;
return c;
}
function makeLine(coords, name) {
var l = new fabric.Line(coords, {
stroke: 'red',
strokeWidth: 4,
selectable: true, //false
name: name
});
l.hasControls = l.hasBorders = false;
return l;
}
//initial shape information
var line = makeLine([250, 125, 350, 125], "l1"),
line2 = makeLine([350, 125, 350, 225], "l2"),
line3 = makeLine([350, 225, 250, 225], "l3"),
line4 = makeLine([250, 225, 250, 125], "l4");
canvas.add(line, line2, line3, line4);
canvas.add(
makeCircle(line.get('x1'), line.get('y1'), line4, line, 1, 2),
makeCircle(line.get('x2'), line.get('y2'), line, line2, 1, 2),
makeCircle(line2.get('x2'), line2.get('y2'), line2, line3, 1, 2),
makeCircle(line3.get('x2'), line3.get('y2'), line3, line4, 1, 2));
canvas.on('object:moving', function(e) {
//find the moving object type
var objType = e.target.get('type');
var p = e.target;
if (objType == 'circle') {
p.line1 && p.line1.set({
'x2': p.left,
'y2': p.top
});
p.line2 && p.line2.set({
'x1': p.left,
'y1': p.top
});
//set coordinates for the lines - should be done if element is moved programmely
p.line2.setCoords();
p.line1.setCoords();
canvas.renderAll();
} else if (objType == 'line') {
//loop all circles and if some is with coordinates as some of the ends - to change them
for (var i = 0; i < canvas.getObjects('circle').length; i++) {
var currentObj = canvas.getObjects('circle')[i];
if (currentObj.get("usedLineName") == e.target.get('name')) {
//usedEndPoint=2
for (var ss = 0; ss < canvas.getObjects('line').length; ss++) {
var s = canvas.getObjects('line')[ss];
//console.log(s.calcLinePoints())
//console.log(s.calcLinePoints().y2)
var _l = s.left;
var _t = s.top;
if (s.get("name") == currentObj.get("usedLineName")) {
currentObj.set({
'left': (s.calcLinePoints().x2 + _l),
'top': (s.calcLinePoints().y2 + _t)
});
console.log(s.calcLinePoints().y2 + _t)
currentObj.setCoords();
currentObj.line1 && currentObj.line1.set({
'x2': currentObj.left,
'y2': currentObj.top
});
currentObj.line2 && currentObj.line2.set({
'x1': currentObj.left,
'y1': currentObj.top
});
currentObj.line2.setCoords();
currentObj.line1.setCoords();
//move the other circle
canvas.forEachObject(function(obj) {
var _objType = obj.get('type');
if (_objType == "circle" && obj.line2.name == s.get("name")) {
obj.set({
'left': (s.calcLinePoints().x1 + _l),
'top': (s.calcLinePoints().y1 + _t)
});
console.log(s.calcLinePoints().y1 + _t)
obj.setCoords();
obj.line1 && obj.line1.set({
'x2': obj.left,
'y2': obj.top
});
obj.line2 && obj.line2.set({
'x1': obj.left,
'y1': obj.top
});
obj.line2.setCoords();
obj.line1.setCoords();
//canvas.renderAll();
}
});
canvas.renderAll();
//end move oter
}
}
}
}
}
});
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<canvas id="c" width="500" height="500"></canvas>
这也是 jsfiddle 上的代码: https://jsfiddle.net/muybien/mzsa3z9L/
我想先谢谢你,即使只是为了阅读这个问题。
【问题讨论】:
-
您可以使用事件clientX 和clientY 根据鼠标的移动而不是相对于每个对象进行计算。然后你只需根据这些偏移量移动每个元素,据我所知,你应该得到你的结果。
-
谢谢你的回答,但我觉得你说的不对。鼠标可能无处不在。这条线也可以随机倾斜。如何准确地找到线的末端,然后在这些坐标上放置圆圈?好的,我可以使用 sin() 和 cos() 来做到这一点,但在我看来,它会更加复杂,并且更有可能出错。当然,如果你想证明你的建议,并告诉我我错了,当我看到一些可行的例子时,我会同意你的。
-
我可能会误解,如果是这种情况,请原谅我,但我假设您想相对于线移动对象或连接点?如果是这种情况,您可以使用增量。存储鼠标的最后一个位置,然后当您再移动鼠标时,减去两个位置以查看相对方向(即 x 轴上 -5px,y 轴上 10px)。您可以将该值添加到点的位置和线的位置以均匀移动它们。
-
感谢您的建议,我解决了不对称运动的问题。顺便说一句:尝试获取线的结束坐标的最初原因是一个想法(已经放弃),以便能够在旋转时更新相关的圆位置。
标签: coordinates move fabricjs lines