之前我们进修了基本和高等特征 如今引见更奇异的东西
Groups
话说这个功用我最喜欢
构成群组能够一致修正个中一切组件属性
怎样定义
var circle = new fabric.Circle({
radius: 100,
fill: '#eef',
scaleY: 0.5,
originX: 'center',
originY: 'center'
});
var text = new fabric.Text('hello world', {
fontSize: 30,
originX: 'center',
originY: 'center'
});
var group = new fabric.Group([ circle, text ], {
left: 150,
top: 100,
angle: -10
});
canvas.add(group);
如今我们就能够对个中的对象集修正
group.item(0).setFill('red');
group.item(1).set({
text: 'trololo',
fill: 'white'
});
group中的元素相对于group定位
然则因为要确保之前获得却切位置 所以要异步
fabric.Image.fromURL('/assets/pug.jpg', function(img) {
var img1 = img.scale(0.1).set({ left: 100, top: 100 });
fabric.Image.fromURL('/assets/pug.jpg', function(img) {
var img2 = img.scale(0.1).set({ left: 175, top: 175 });
fabric.Image.fromURL('/assets/pug.jpg', function(img) {
var img3 = img.scale(0.1).set({ left: 250, top: 250 });
canvas.add(new fabric.Group([ img1, img2, img3], { left: 200, top: 200 }))
});
});
});
group 能够动态增加
group.add(new fabric.Rect({
...
originX: 'center',
originY: 'center'
}));
增加并修正group
group.addWithUpdate(new fabric.Rect({
...
left: group.getLeft(),
top: group.getTop(),
originX: 'center',
originY: 'center'
}));
固然 你能够运用canvas上已有的举行克隆 组合
// create a group with copies of existing (2) objects
var group = new fabric.Group([
canvas.item(0).clone(),
canvas.item(1).clone()
]);
// remove all objects and re-render
canvas.clear().renderAll();
// add group onto canvas
canvas.add(group);
Serialization
序列化是为了互相传输
toObject, toJSON
canvas 完成了toJSON接口 能够被序列化
var canvas = new fabric.Canvas('c');
JSON.stringify(canvas); // '{"objects":[],"background":"rgba(0, 0, 0, 0)"}'
canvas 能够随时被修正 json数据会被修正
canvas.backgroundColor = 'red';
JSON.stringify(canvas); // '{"objects":[],"background":"red"}'
增加新对象 也会转变json数据
canvas.add(new fabric.Rect({
left: 50,
top: 50,
height: 20,
width: 20,
fill: 'green'
}));
console.log(JSON.stringify(canvas));
'{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0}],"background":"rgba(0, 0, 0, 0)"}'
再增加一个
canvas.add(new fabric.Circle({
left: 100,
top: 100,
radius: 50,
fill: 'red'
}));
console.log(JSON.stringify(canvas));
'{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0},{"type":"circle","left":100,"top":100,"width":100,"height":100,"fill":"red","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"radius":50}],"background":"rgba(0, 0, 0, 0)"}'
toObject
能够转化成js object对象
{ "background" : "rgba(0, 0, 0, 0)",
"objects" : [
{
"angle" : 0,
"fill" : "green",
"flipX" : false,
"flipY" : false,
"hasBorders" : true,
"hasControls" : true,
"hasRotatingPoint" : false,
"height" : 20,
"left" : 50,
"opacity" : 1,
"overlayFill" : null,
"perPixelTargetFind" : false,
"scaleX" : 1,
"scaleY" : 1,
"selectable" : true,
"stroke" : null,
"strokeDashArray" : null,
"strokeWidth" : 1,
"top" : 50,
"transparentCorners" : true,
"type" : "rect",
"width" : 20
}
]
}
每一个fabric对象有toObject要领 这和toJSON 也有关 能够自定义
var rect = new fabric.Rect();
rect.toObject = function() {
return { name: 'trololo' };
};
canvas.add(rect);
console.log(JSON.stringify(canvas));
'{"objects":[{"name":"trololo"}],"background":"rgba(0, 0, 0, 0)"}'
固然我们能够保存原有的数据 新增数据
var rect = new fabric.Rect();
rect.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
name: this.name
});
};
})(rect.toObject);
canvas.add(rect);
rect.name = 'trololo';
console.log(JSON.stringify(canvas))
'{"objects":[{"type":"rect","left":0,"top":0,"width":0,"height":0,"fill":"rgb(0,0,0)","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0,"name":"trololo"}],"background":"rgba(0, 0, 0, 0)"}'
toSvg
怎么能不支持转成svg呢
canvas.add(new fabric.Rect({
left: 50,
top: 50,
height: 20,
width: 20,
fill: 'green'
}));
console.log(canvas.toSVG());
'<?xml version="1.0" standalone="no" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="800" height="700" xml:space="preserve"><desc>Created with Fabric.js 0.9.21</desc><rect x="-10" y="-10" rx="0" ry="0" width="20" height="20" style="stroke: none; stroke-width: 1; stroke-dasharray: ; fill: green; opacity: 1;" transform="translate(50 50)" /></svg>'
Deserialization, SVG parser
fabric.Canvas#loadFromJSON
fabric.Canvas#loadFromDatalessJSON
fabric.loadSVGFromURL
fabric.loadSVGFromString
var canvas = new fabric.Canvas();
canvas.loadFromJSON('{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0},{"type":"circle","left":100,"top":100,"width":100,"height":100,"fill":"red","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"radius":50}],"background":"rgba(0, 0, 0, 0)"}');
通常情况下 svg 会被序列化 然则能够运用 fabric.Canvas#toDatalessJSON
canvas.item(0).sourcePath = '/assets/dragon.svg';
console.log(JSON.stringify(canvas.toDatalessJSON()));
{"objects":[{"type":"path","left":143,"top":143,"width":175,"height":151,"fill":"#231F20","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":-19,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"path":"/assets/dragon.svg"}],"background":"rgba(0, 0, 0, 0)"}
Subclassing
组织类
var Point = fabric.util.createClass({
initialize: function(x, y) {
this.x = x || 0;
this.y = y || 0;
},
toString: function() {
return this.x + '/' + this.y;
}
});
继续类
var ColoredPoint = fabric.util.createClass(Point, {
initialize: function(x, y, color) {
this.callSuper('initialize', x, y);
this.color = color || '#000';
},
toString: function() {
return this.callSuper('toString') + ' (color: ' + this.color + ')';
}
});
继续默许类
var LabeledRect = fabric.util.createClass(fabric.Rect, {
type: 'labeledRect',
initialize: function(options) {
options || (options = { });
this.callSuper('initialize', options);
this.set('label', options.label || '');
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
label: this.get('label')
});
},
_render: function(ctx) {
this.callSuper('_render', ctx);
ctx.font = '20px Helvetica';
ctx.fillStyle = '#333';
ctx.fillText(this.label, -this.width/2, -this.height/2 + 20);
}
});
不过实在没必要的