转载

Fabric.js 简单介绍和使用 (三)

之前我们学习了基础和高级特性 现在介绍更神奇的东西

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);   } });

不过其实没必要的

原文  https://segmentfault.com/a/1190000004895504
正文到此结束
Loading...