使用http://fabricjs.com/的 stickman 示例, 移动线时,我一直试图移动相关的圆圈。示例中的代码结构不合理,重量级和有错误:),因为我无法对称地移动相关的圆圈。
如果在 //移动另一个圈部分,则使用下一行
obj.set({ 'left':( s.calcLinePoints()。x1 + _l), 'top':( -s.calcLinePoints()。y1 + _t) });
[示例代码]
$(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/
我以前要感谢你,甚至只是为了阅读这个问题。
答案 0 :(得分:0)
感谢 MiltoxBeyond的建议,问题得到解决。 这是一个工作且很少清理的例子:
//to save the old cursor position: used on line mooving
var _curX, _curY;
$(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) {
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;
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), makeCircle(line.get('x2'), line.get('y2'), line, line2), makeCircle(line2.get('x2'), line2.get('y2'), line2, line3), makeCircle(line3.get('x2'), line3.get('y2'), line3, line4)
);
canvas.on('object:selected', function(e) {
//find the selected object type
var objType = e.target.get('type');
if (objType == 'line') {
_curX = e.e.clientX;
_curY = e.e.clientY;
//console.log(_curX);
//console.log(_curY);
}
});
canvas.on('object:moving', function(e) {
//find the moving object type
var p = e.target;
var objType = p.get('type');
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') {
var _curXm = (_curX - e.e.clientX);
var _curYm = (_curY - e.e.clientY);
//console.log("moved: " + _curXm);
//console.log("moved: " + _curYm);
//loop all circles and if some contains the line - move it
for (var i = 0; i < canvas.getObjects('circle').length; i++) {
var currentObj = canvas.getObjects('circle')[i];
if (currentObj.line1.get("name") == p.get('name') || currentObj.line2.get("name") == p.get('name')) {
currentObj.set({
'left': (currentObj.left - _curXm),
'top': (currentObj.top - _curYm)
});
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();
}
}
_curX = e.e.clientX;
_curY = e.e.clientY;
}
});
});
&#13;
canvas {
border: 1px solid #808080;
}
&#13;
<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>
&#13;