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.globalAlpha *= this.opacity;
 79       ctx.transform(1, 0, 0, this.ry/this.rx, 0, 0);
 80       ctx.arc(noTransform ? this.left : 0, noTransform ? this.top : 0, this.rx, 0, piBy2, false);
 81       if (this.stroke) {
 82         ctx.stroke();
 83       }
 84       if (this.fill) {
 85         ctx.fill();
 86       }
 87       ctx.restore();
 88     },
 89     
 90     /**
 91      * Returns complexity of an instance
 92      * @method complexity
 93      * @return {Number} complexity
 94      */
 95     complexity: function() {
 96       return 1;
 97     }
 98   });
 99   
100   /**
101    * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement})
102    * @static
103    * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement
104    */
105   fabric.Ellipse.ATTRIBUTE_NAMES = 'cx cy rx ry fill fill-opacity opacity stroke stroke-width transform'.split(' ');
106   
107   /**
108    * Returns {@link fabric.Ellipse} instance from an SVG element
109    * @static
110    * @method fabric.Ellipse.fromElement
111    * @param {SVGElement} element Element to parse
112    * @param {Object} [options] Options object
113    * @return {fabric.Ellipse}
114    */
115   fabric.Ellipse.fromElement = function(element, options) {
116     options || (options = { });
117     var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES);
118     if ('left' in parsedAttributes) {
119       parsedAttributes.left -= (options.width / 2) || 0;
120     }
121     if ('top' in parsedAttributes) {
122       parsedAttributes.top -= (options.height / 2) || 0;
123     }
124     return new fabric.Ellipse(extend(parsedAttributes, options));
125   };
126   
127   /**
128    * Returns fabric.Ellipse instance from an object representation
129    * @static
130    * @method fabric.Ellipse.fromObject
131    * @param {Object} object Object to create an instance from
132    * @return {fabric.Ellipse}
133    */
134   fabric.Ellipse.fromObject = function(object) {
135     return new fabric.Ellipse(object);
136   }
137 })(this);