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