1 //= require "object.class" 2 3 (function(){ 4 5 var fabric = this.fabric || (this.fabric = { }), 6 piBy2 = Math.PI * 2, 7 extend = fabric.util.object.extend; 8 9 if (fabric.Ellipse) { 10 fabric.warn('fabric.Ellipse is already defined.'); 11 return; 12 } 13 14 /** 15 * @class Ellipse 16 * @extends fabric.Object 17 */ 18 fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @scope fabric.Ellipse.prototype */ { 19 20 /** @property */ 21 type: 'ellipse', 22 23 /** 24 * Constructor 25 * @method initialize 26 * @param {Object} [options] Options object 27 * @return {Object} thisArg 28 */ 29 initialize: function(options) { 30 options = options || { }; 31 32 this.callSuper('initialize', options); 33 34 this.set('rx', options.rx || 0); 35 this.set('ry', options.ry || 0); 36 37 this.set('width', this.get('rx') * 2); 38 this.set('height', this.get('ry') * 2); 39 }, 40 41 /** 42 * Returns object representation of an instance 43 * @method toObject 44 * @return {Object} object representation of an instance 45 */ 46 toObject: function() { 47 return extend(this.callSuper('toObject'), { 48 rx: this.get('rx'), 49 ry: this.get('ry') 50 }); 51 }, 52 53 /** 54 * @method render 55 * @param ctx {CanvasRenderingContext2D} context to render on 56 * @param noTransform {Boolean} context is not transformed when set to true 57 */ 58 render: function(ctx, noTransform) { 59 // do not use `get` for perf. reasons 60 if (this.rx === 0 || this.ry === 0) return; 61 return this.callSuper('render', ctx, noTransform); 62 }, 63 64 /** 65 * @private 66 * @method _render 67 * @param ctx {CanvasRenderingContext2D} context to render on 68 */ 69 _render: function(ctx, noTransform) { 70 ctx.beginPath(); 71 ctx.save(); 72 ctx.transform(1, 0, 0, this.ry/this.rx, 0, 0); 73 ctx.arc(noTransform ? this.left : 0, noTransform ? this.top : 0, this.rx, 0, piBy2, false); 74 ctx.restore(); 75 if (this.stroke) { 76 ctx.stroke(); 77 } 78 if (this.fill) { 79 ctx.fill(); 80 } 81 }, 82 83 /** 84 * @method complexity 85 * @return {Number} complexity 86 */ 87 complexity: function() { 88 return 1; 89 } 90 }); 91 92 fabric.Ellipse.ATTRIBUTE_NAMES = 'cx cy rx ry fill fill-opacity stroke stroke-width transform'.split(' '); 93 94 /** 95 * Returns fabric.Ellipse instance from an SVG element 96 * @static 97 * @method fabric.Ellipse.fromElement 98 * @param {SVGElement} element Element to parse 99 * @param {Object} [options] Options object 100 * @return {fabric.Ellipse} 101 */ 102 fabric.Ellipse.fromElement = function(element, options) { 103 options || (options = { }); 104 var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES); 105 if ('left' in parsedAttributes) { 106 parsedAttributes.left -= (options.width / 2) || 0; 107 } 108 if ('top' in parsedAttributes) { 109 parsedAttributes.top -= (options.height / 2) || 0; 110 } 111 return new fabric.Ellipse(extend(parsedAttributes, options)); 112 }; 113 114 /** 115 * Returns fabric.Ellipse instance from an object representation 116 * @static 117 * @method fabric.Ellipse.fromObject 118 * @param {Object} object Object to create an instance from 119 * @return {fabric.Ellipse} 120 */ 121 fabric.Ellipse.fromObject = function(object) { 122 return new fabric.Ellipse(object); 123 } 124 })();