在我继续尝试在Fabric.js中创建可以保存和加载的自定义类的传奇。我正在尝试扩展Line和Circle类并添加一些自定义属性......但是在尝试加载数据时我遇到了问题。它保存好了,我的简单'name'属性就在那里,但是在尝试加载时,我陷入了“enlivenObjects”函数,即klass从fabric.util.getKlass函数中获取该对象类型。对于我的对象我没有得到任何回报(“未定义”)。 在附带的示例中,如果单击“SAVE”将画布的数据放入DIV,则可以“清除”画布并尝试“加载”数据。尝试加载时发生错误。 因此,在JS控制台窗口中,我可以运行“fabric.util.getKlass('Line')”并且可以工作,我得到一个对象,但当我对'namedCircle'或'namedLine'执行相同操作时,我得到了未定义... 有什么想法吗?这种方法对我不起作用吗?
var canvas;
window.onload = function() {
canvas = new fabric.Canvas('c');
/**
* Attempt to make a custom Line, inherited from the fabric.Line
* currently has a custom attribute of 'name'
*
*/
fabric.namedLine = fabric.util.createClass(fabric.Line, {
type: 'namedLine',
initialize: function(points, options) {
options || (options = { });
this.callSuper('initialize', points, options);
this.set('name', options.name || '');
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
name: this.get('name')
});
},
fromObject: function(object, callback) {
return fabric.Object._fromObject('namedLine', options, callback);
},
_render: function(ctx) {
this.callSuper('_render', ctx);
}
});
/**
* Attempt at custom Circle, inherited from fabric.Circle with
* a 'name' attribute.
*
*/
fabric.namedCircle = fabric.util.createClass(fabric.Circle, {
type: 'namedCircle',
initialize: function(options) {
options || (options = { });
this.callSuper('initialize', options);
this.set('name', options.name || '');
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
name: this.get('name')
});
},
fromObject: function(object, callback) {
return fabric.Object._fromObject('namedCircle', object, callback);
},
_render: function(ctx) {
this.callSuper('_render', ctx);
}
});
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
// First Create our line.
var line = makeLine([ 250, 125, 250, 175 ], "myLine");
canvas.add(line);
// Now we create our circles, linking to our line.
canvas.add(
// first circle is at top of line, line1 is null, line2 is the line.
makeCircle(line.get('x1'), line.get('y1'), "head", null, line),
// second circle is at the bottom, line 1 is the line, nothing for line 2.
makeCircle(line.get('x2'), line.get('y2'), "tail", line),
);
canvas.on('object:moving', function(e) {
var p = e.target;
// set bottom of the line to the shapes left and top position.
p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top });
// set the top to the line to the circle position.
p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top });
canvas.renderAll();
});
// Add our button events.
document.getElementById("btnSave").addEventListener("click", saveData);
document.getElementById("btnLoad").addEventListener("click", loadData);
document.getElementById("btnClear").addEventListener("click", clearData);
};
// our circle has up to 2 links.
function makeCircle(left, top, name, line1, line2) {
var c = new fabric.namedCircle({
left: left,
top: top,
strokeWidth: 5,
radius: 12,
fill: '#fff',
stroke: '#666',
name: name
});
c.hasControls = c.hasBorders = false;
c.line1 = line1;
c.line2 = line2;
return c;
}
function makeLine(coords, name) {
return new fabric.namedLine(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 5,
selectable: false,
name: name
});
}
function saveData() {
document.getElementById("out").innerHTML = "";
document.getElementById("out").innerHTML = JSON.stringify(canvas.toDatalessJSON());
};
function loadData() {
var data = document.getElementById("out").innerHTML;
console.log(data);
canvas.loadFromDatalessJSON(data);
canvas.renderAll();
};
function clearData() {
canvas.clear();
}
#out {
width:500px;
height:300px;
border:1px solid red;
overflow:scroll;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.min.js"></script>
<canvas style="border: 2px solid; " height="500" width="600" id="c"></canvas>
<p>
<button id="btnSave">Save</button>
<button id="btnClear">Clear</button>
<button id="btnLoad">Load</button>
</p>
<div id="out"></div>
答案 0 :(得分:1)
嗯,有时你只需要远离事物并思考它。 我仔细研究了getKlass函数,并将类名称的第一个字符大写......所以修复是将类从“namedLine”和“namedCircle”更改为“NamedLine”和“NamedCircle”。 我要做的另一件事是将返回函数移到类之外。
var canvas;
/**
* Attempt to make a custom Line, inherited from the fabric.Line
* currently has a custom attribute of 'name'
*
*/
fabric.NamedLine = fabric.util.createClass(fabric.Line, {
type: 'NamedLine',
initialize: function(points, options) {
options || (options = { });
this.callSuper('initialize', points, options);
this.set('name', options.name || '');
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
name: this.get('name')
});
},
_render: function(ctx) {
this.callSuper('_render', ctx);
}
});
fabric.NamedLine.fromObject = function(object, callback) {
callback && callback(new fabric.NamedLine([object.x1, object.y1, object.x2, object.y2], object));
};
/**
* Attempt at custom Circle, inherited from fabric.Circle with
* a 'name' attribute.
*
*/
fabric.NamedCircle = fabric.util.createClass(fabric.Circle, {
type: 'NamedCircle',
initialize: function(options) {
options || (options = { });
this.callSuper('initialize', options);
this.set('name', options.name || '');
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
name: this.get('name')
});
},
_render: function(ctx) {
this.callSuper('_render', ctx);
}
});
fabric.NamedCircle.fromObject = function(object, callback) {
return fabric.Object._fromObject('NamedCircle', object, callback);
};
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
window.onload = function() {
canvas = new fabric.Canvas('c');
// First Create our line.
var line = makeLine([ 250, 125, 250, 175 ], "myLine");
canvas.add(line);
// Now we create our circles, linking to our line.
canvas.add(
// first circle is at top of line, line1 is null, line2 is the line.
makeCircle(line.get('x1'), line.get('y1'), "head", null, line),
// second circle is at the bottom, line 1 is the line, nothing for line 2.
makeCircle(line.get('x2'), line.get('y2'), "tail", line),
);
canvas.on('object:moving', function(e) {
var p = e.target;
// set bottom of the line to the shapes left and top position.
p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top });
// set the top to the line to the circle position.
p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top });
canvas.renderAll();
});
// Add our button events.
document.getElementById("btnSave").addEventListener("click", saveData);
document.getElementById("btnLoad").addEventListener("click", loadData);
document.getElementById("btnClear").addEventListener("click", clearData);
};
// our circle has up to 2 links.
function makeCircle(left, top, name, line1, line2) {
var c = new fabric.NamedCircle({
left: left,
top: top,
strokeWidth: 5,
radius: 12,
fill: '#fff',
stroke: '#666',
name: name
});
c.hasControls = c.hasBorders = false;
c.line1 = line1;
c.line2 = line2;
return c;
}
function makeLine(coords, name) {
return new fabric.NamedLine(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 5,
selectable: false,
name: name
});
}
function saveData() {
document.getElementById("out").innerHTML = "";
document.getElementById("out").innerHTML = JSON.stringify(canvas.toDatalessJSON());
};
function loadData() {
var data = document.getElementById("out").innerHTML;
console.log(data);
canvas.loadFromDatalessJSON(data);
canvas.renderAll();
};
function clearData() {
canvas.clear();
}
#out {
width:500px;
height:300px;
border:1px solid red;
overflow:scroll;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.min.js"></script>
<canvas style="border: 2px solid; " height="500" width="600" id="c"></canvas>
<p>
<button id="btnSave">Save</button>
<button id="btnClear">Clear</button>
<button id="btnLoad">Load</button>
</p>
<div id="out"></div>