加载stickman.tojson后,圆圈和直线旋转逻辑消失了。
我能够复制stickman逻辑以向对象添加线条,并且当我移动线条时线条将旋转并跟随对象。我使用canvas.toJSON来保存Json,所有这一切都很好。我可以使用canvas.loadFromJSON(json)加载Json并加载它。
问题是我加载后,当我移动圆圈时,线条不跟随并旋转。我尝试搜索要包含在toJSON()中的属性,但我找不到任何内容。
这是一个jsfiddle样本。
var canvas = this.__canvas = new fabric.Canvas('c', { selection: false });
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
saveNow = (function(){
var jsonSave = JSON.stringify(canvas.toJSON())
// alert(jsonSave);
sessionStorage.canvase = jsonSave;
});
loadNow = (function(){
var jsonLoad = sessionStorage.canvase;
// alert(jsonLoad);
canvas.loadFromJSON(jsonLoad, canvas.renderAll.bind(canvas));
});
(function() {
function makeCircle(left, top, line1, line2, line3, line4) {
var c = new fabric.Circle({
left: left,
top: top,
strokeWidth: 5,
radius: 12,
fill: '#fff',
stroke: '#666'
});
c.hasControls = c.hasBorders = false;
c.line1 = line1;
c.line2 = line2;
c.line3 = line3;
c.line4 = line4;
return c;
}
function makeLine(coords) {
return new fabric.Line(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 5,
selectable: false
});
}
var line = makeLine([ 250, 125, 250, 175 ]),
line2 = makeLine([ 250, 175, 250, 250 ]),
line3 = makeLine([ 250, 250, 300, 350]),
line4 = makeLine([ 250, 250, 200, 350]),
line5 = makeLine([ 250, 175, 175, 225 ]),
line6 = makeLine([ 250, 175, 325, 225 ]);
canvas.add(line, line2, line3, line4, line5, line6);
canvas.add(
makeCircle(line.get('x1'), line.get('y1'), null, line),
makeCircle(line.get('x2'), line.get('y2'), line, line2, line5, line6),
makeCircle(line2.get('x2'), line2.get('y2'), line2, line3, line4),
makeCircle(line3.get('x2'), line3.get('y2'), line3),
makeCircle(line4.get('x2'), line4.get('y2'), line4),
makeCircle(line5.get('x2'), line5.get('y2'), line5),
makeCircle(line6.get('x2'), line6.get('y2'), line6)
);
canvas.on('object:moving', function(e) {
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 });
canvas.renderAll();
});
})();
重现的步骤: 1.移动圆形物体。 2.单击“保存”按钮。 3.移动圆形物体。 4.单击“加载”按钮。 5.移动圆形物体。现在,这将揭示我想要修复/坚持的内容。
提前致谢。
答案 0 :(得分:2)
您遇到的问题是canvas.toJSON()
会保存所有结构的对象,如画布中所示,但不会保存您自己的对象,因此会松动参考文献,例如圆圈和线条之间的链接。
我不是fabric.js专家所以可能有一个更简单的解决方案,但是我重写了你的代码,以便它可以完成你想要做的事情。
我使用数组来存储我们所有的行,现在saveNow()
函数只保存这些行的坐标。
我还必须重写绘图函数,现在放入init()
函数。
另外,请注意它有点脏:
var canvas = this.__canvas = new fabric.Canvas('c', {
selection: false
});
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
(function () {
//Some other objects
canvas.add(
new fabric.Rect({ top: 100, left: 100, width: 50, height: 50, fill: '#f55' }),
new fabric.Circle({ top: 140, left: 230, radius: 75, fill: 'green' }),
new fabric.Triangle({ top: 300, left: 210, width: 100, height: 100, fill: 'blue' })
);
var lines,
links = [[0,1,4,5], [1,2,3], [2], [3], [4], [5]];
var saveNow = function () {
//save our stickMan
var coords = [],l;
for (var i = 0; l = lines[i]; i++) {
coords.push([l.x1, l.y1, l.x2, l.y2]);
}
sessionStorage.stickman = JSON.stringify(coords);
//Hide our stickman
lines.forEach(function(l){canvas.remove(l)});
circles.forEach(function(c){canvas.remove(c)});
//save the rest of the canvas
sessionStorage.canvase = JSON.stringify(canvas.toJSON());
//unhide stickman
lines.forEach(function(l){canvas.add(l)});
circles.forEach(function(c){canvas.add(c)});
canvas.renderAll();
};
var loadNow = function () {
var coords = JSON.parse(sessionStorage.stickman);
canvas.clear();
var jsonLoad = sessionStorage.canvase;
canvas.loadFromJSON(jsonLoad, function(){canvas.renderAll.bind(canvas); init(coords);});
};
var btns = document.querySelectorAll('button');
btns[0].addEventListener('click', saveNow, false);
btns[1].addEventListener('click', loadNow, false);
var circles;
function makeCircle(left, top, l) {
var c = new fabric.Circle({
left: left,
top: top,
strokeWidth: 5,
radius: 12,
fill: '#fff',
stroke: '#666'
});
c.hasControls = c.hasBorders = false;
for (var i = 0; i < links.length; i++) {
c["line" + i] = lines[l[i]];
}
circles.push(c);
return c;
}
function makeLine(coords) {
return new fabric.Line(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 5,
selectable: false
});
}
function init(coords) {
coords = coords || [
[250, 125, 250, 175],
[250, 175, 250, 250],
[250, 250, 300, 350],
[250, 250, 200, 350],
[250, 175, 175, 225],
[250, 175, 325, 225]
];
lines = circles = [];
var i;
for (i = 0; i < coords.length; i++) {
lines.push(makeLine(coords[i]));
}
for (i = 0; i < lines.length; i++) {
canvas.add(lines[i]);
}
for (i = 0; i < lines.length; i++) {
if (i === 0) {
canvas.add(makeCircle(lines[i].get('x1'), lines[i].get('y1'), [null, 0]));
canvas.add(makeCircle(lines[i].get('x2'), lines[i].get('y2'), links[i]));
} else canvas.add(makeCircle(lines[i].get('x2'), lines[i].get('y2'), links[i]));
}
}
canvas.on('object:moving', function (e) {
var p = e.target;
p.line0 && p.line0.set({'x2': p.left,'y2': p.top});
p.line1 && p.line1.set({'x1': p.left,'y1': p.top});
p.line2 && p.line2.set({'x1': p.left,'y1': p.top});
p.line3 && p.line3.set({'x1': p.left,'y1': p.top});
canvas.renderAll();
});
init();
})();
替代将按照this answer中的建议对您的对象进行子类化。