从 json 加载 stickman 不会保留线坐标旋转逻辑
loading stickman from json does not persist line coordinate rotation logic
加载stickman.tojson后,圆和线旋转逻辑消失了。
我能够复制火柴人逻辑来向对象添加线条,并且当我移动对象时,线条会旋转并跟随对象。我使用 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. 移动圆圈对象。现在这将揭示我正在尝试 fix/persists.
提前致谢。
您面临的问题是 canvas.toJSON()
将保存所有织物的对象,如 canvas 中绘制的那样,但不会保存您自己的对象,因此它会丢失引用比如圆和线之间的联系。
我不是 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();
})();
▶︎ JsFiddle
另一种方法 是按照 this answer.
中的建议对您的对象进行子类化
加载stickman.tojson后,圆和线旋转逻辑消失了。
我能够复制火柴人逻辑来向对象添加线条,并且当我移动对象时,线条会旋转并跟随对象。我使用 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. 移动圆圈对象。现在这将揭示我正在尝试 fix/persists.
提前致谢。
您面临的问题是 canvas.toJSON()
将保存所有织物的对象,如 canvas 中绘制的那样,但不会保存您自己的对象,因此它会丢失引用比如圆和线之间的联系。
我不是 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();
})();
▶︎ JsFiddle
另一种方法 是按照 this answer.
中的建议对您的对象进行子类化