我们在使用结构中的路径时遇到问题,当用户拖动第一个点或最后一个点时,我们需要一直改变二次线(路径)的坐标,路径会像往常一样更新,但是问题是路径的边界框在每次更改object.path时都没有得到更新(见图片)
(function() {
var canvas = this.__canvas = new fabric.Canvas('c');
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
canvas.on({
'object:selected': onObjectSelected,
'object:moving': onObjectMoving,
'before:selection:cleared': onBeforeSelectionCleared
});
(function drawQuadratic() {
var line = new fabric.Path('M 65 0 Q 100, 100, 200, 0', { fill: '', stroke: 'black' });
line.path[0][1] = 100;
line.path[0][2] = 100;
line.path[1][1] = 200;
line.path[1][2] = 200;
line.path[1][3] = 300;
line.path[1][4] = 100;
line.selectable = true;
line.hasControls = false;
canvas.add(line);
var p1 = makeCurvePoint(200, 200, null, line, null)
p1.name = "p1";
canvas.add(p1);
var p0 = makeCurveCircle(100, 100, line, p1, null);
p0.name = "p0";
canvas.add(p0);
var p2 = makeCurveCircle(300, 100, null, p1, line);
p2.name = "p2";
canvas.add(p2);
})();
function makeCurveCircle(left, top, line1, line2, line3) {
var c = new fabric.Circle({
left: left,
top: top,
strokeWidth: 5,
radius: 12,
fill: '#fff',
stroke: '#666'
});
c.hasBorders = c.hasControls = false;
c.line1 = line1;
c.line2 = line2;
c.line3 = line3;
return c;
}
function makeCurvePoint(left, top, line1, line2, line3) {
var c = new fabric.Circle({
left: left,
top: top,
strokeWidth: 8,
radius: 14,
fill: '#fff',
stroke: '#666'
});
c.hasBorders = c.hasControls = false;
c.line1 = line1;
c.line2 = line2;
c.line3 = line3;
return c;
}
function onObjectSelected(e) {
var activeObject = e.target;
if (activeObject.name == "p0" || activeObject.name == "p2") {
activeObject.line2.animate('opacity', '1', {
duration: 200,
onChange: canvas.renderAll.bind(canvas),
});
activeObject.line2.selectable = true;
}
}
function onBeforeSelectionCleared(e) {
var activeObject = e.target;
if (activeObject.name == "p0" || activeObject.name == "p2") {
activeObject.line2.animate('opacity', '0', {
duration: 200,
onChange: canvas.renderAll.bind(canvas),
});
activeObject.line2.selectable = false;
}
else if (activeObject.name == "p1") {
activeObject.animate('opacity', '0', {
duration: 200,
onChange: canvas.renderAll.bind(canvas),
});
activeObject.selectable = false;
}
}
function onObjectMoving(e) {
if (e.target.name == "p0" || e.target.name == "p2") {
var p = e.target;
if (p.line1) {
p.line1.path[0][1] = p.left;
p.line1.path[0][2] = p.top;
}
else if (p.line3) {
p.line3.path[1][3] = p.left;
p.line3.path[1][4] = p.top;
}
}
else if (e.target.name == "p1") {
var p = e.target;
if (p.line2) {
p.line2.path[1][1] = p.left;
p.line2.path[1][2] = p.top;
}
}
else if (e.target.name == "p0" || e.target.name == "p2") {
var p = e.target;
p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top });
p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top });
p.line3 && p.line3.set({ 'x1': p.left, 'y1': p.top });
p.line4 && p.line4.set({ 'x1': p.left, 'y1': p.top });
}
}
})();
<script src="http://fabricjs.com/lib/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>
(见这个小提琴http://jsfiddle.net/davidtorroija/uyLx3r41/1/)
有更新边界框的功能吗?或者这是fabricjs中的错误?
谢谢!
答案 0 :(得分:1)
这只是向好的方向暗示。 每次重绘都会重新初始化该行(您可以在鼠标向上更好地完成)。 通过这种方式,边界框保持适合形状。
http://jsfiddle.net/uyLx3r41/2/
(function() {
var line;
var canvas = this.__canvas = new fabric.Canvas('c');
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
canvas.on({
'object:moving': onObjectMoving,
});
(function drawQuadratic() {
line = new fabric.Path('M 65 0 Q 100, 100, 200, 0', { fill: '', stroke: 'black' });
line.path[0][1] = 100;
line.path[0][2] = 100;
line.path[1][1] = 200;
line.path[1][2] = 200;
line.path[1][3] = 300;
line.path[1][4] = 100;
line.selectable = true;
line.hasControls = false;
canvas.add(line);
var p1 = makeCurvePoint(200, 200, null, line, null)
p1.name = "p1";
canvas.add(p1);
var p0 = makeCurveCircle(100, 100, line, p1, null);
p0.name = "p0";
canvas.add(p0);
var p2 = makeCurveCircle(300, 100, null, p1, line);
p2.name = "p2";
canvas.add(p2);
})();
function makeCurveCircle(left, top, line1, line2, line3) {
var c = new fabric.Circle({
left: left,
top: top,
strokeWidth: 5,
radius: 12,
fill: '#fff',
stroke: '#666'
});
c.hasBorders = c.hasControls = false;
c.line1 = line1;
c.line2 = line2;
c.line3 = line3;
return c;
}
function makeCurvePoint(left, top, line1, line2, line3) {
var c = new fabric.Circle({
left: left,
top: top,
strokeWidth: 8,
radius: 14,
fill: '#fff',
stroke: '#666'
});
c.hasBorders = c.hasControls = false;
c.line1 = line1;
c.line2 = line2;
c.line3 = line3;
return c;
}
function onObjectMoving(e) {
var p = e.target;
if (p.name == "p0" || p.name == "p2") {
if (p.line1) {
p.line1.path[0][1] = p.left;
p.line1.path[0][2] = p.top;
}
else if (p.line3) {
p.line3.path[1][3] = p.left;
p.line3.path[1][4] = p.top;
}
}
else if (p.name == "p1") {
if (p.line2) {
p.line2.path[1][1] = p.left;
p.line2.path[1][2] = p.top;
}
}
else if (p.name == "p0" || p.name == "p2") {
p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top });
p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top });
p.line3 && p.line3.set({ 'x1': p.left, 'y1': p.top });
p.line4 && p.line4.set({ 'x1': p.left, 'y1': p.top });
}
p && reinit();
}
function reinit() {
canvas.remove(line);
line = new fabric.Path(line.path, { fill: '', stroke: 'black' });
canvas.add(line);
}
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.7/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>