      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.Circle) {
     10     fabric.warn('fabric.Circle is already defined.');
     11     return;
     12   }
     13
     14   /**
     15    * @class Circle
     16    * @extends fabric.Object
     17    */
     18   fabric.Circle = fabric.util.createClass(fabric.Object, /** @scope fabric.Circle.prototype */ {
     19
     20     /** @property */
     21     type: 'circle',
     22
     23     /**
     24      * Constructor
     25      * @method initialize
     26      * @param {Object} [options] Options object
     27      * @return {fabric.Circle} thisArg
     28      */
     29     initialize: function(options) {
     30       options = options || { };
     31
     32       this.set('radius', options.radius || 0);
     33       this.callSuper('initialize', options);
     34
     35       var radiusBy2ByScale = this.get('radius') * 2 * this.get('scaleX');
     36       this.set('width', radiusBy2ByScale).set('height', radiusBy2ByScale);
     37     },
     38
     39     /**
     40      * Returns object representation of an instance
     41      * @method toObject
     42      * @return {Object} object representation of an instance
     43      */
     44     toObject: function() {
     45       return extend(this.callSuper('toObject'), {
     46         radius: this.get('radius')
     47       });
     48     },
     49
     50     /**
     51      * @private
     52      * @method _render
     53      * @param ctx {CanvasRenderingContext2D} context to render on
     54      */
     55     _render: function(ctx, noTransform) {
     56       ctx.beginPath();
     57       ctx.arc(noTransform ? this.left : 0, noTransform ? this.top : 0, this.radius, 0, piBy2, false);
     58       ctx.closePath();
     59       if (this.fill) {
     60         ctx.fill();
     61       }
     62       if (this.stroke) {
     63         ctx.stroke();
     64       }
     65     },
     66
     67
     68     /**
     69      * Returns complexity of an instance
     70      * @method complexity
     71      * @return {Number} complexity of this instance
     72      */
     73     complexity: function() {
     74       return 1;
     75     }
     76   });
     77
     78   /**
     79    * List of attribute names to account for when parsing SVG element (used by `fabric.Circle.fromElement`)
     80    * @static
     81    * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement
     82    */
     83   fabric.Circle.ATTRIBUTE_NAMES = 'cx cy r fill fill-opacity stroke stroke-width transform'.split(' ');
     84
     85   /**
     86    * Returns fabric.Circle instance from an SVG element
     87    * @static
     88    * @method fabric.Circle.fromElement
     89    * @param element {SVGElement} element to parse
     90    * @param options {Object} options object
     91    * @throws {Error} If value of `r` attribute is missing or invalid
     92    * @return {Object} instance of fabric.Circle
     93    */
     94   fabric.Circle.fromElement = function(element, options) {
     95     options || (options = { });
     96     var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);
     97     if (!isValidRadius(parsedAttributes)) {
     98       throw Error('value of `r` attribute is required and can not be negative');
     99     }
    100     if ('left' in parsedAttributes) {
    101       parsedAttributes.left -= (options.width / 2) || 0;
    102     }
    103     if ('top' in parsedAttributes) {
    104       parsedAttributes.top -= (options.height / 2) || 0;
    105     }
    106     return new fabric.Circle(extend(parsedAttributes, options));
    107   };
    108
    109   /**
    110    * @private
    111    */
    112   function isValidRadius(attributes) {
    113     return (('radius' in attributes) && (attributes.radius > 0));
    114   }
    115
    116   /**
    117    * Returns fabric.Circle instance from an object representation
    118    * @static
    119    * @method fabric.Circle.fromObject
    120    * @param {Object} object Object to create an instance from
    121    * @return {Object} Instance of fabric.Circle
    122    */
    123   fabric.Circle.fromObject = function(object) {
    124     return new fabric.Circle(object);
    125   }
    126 })();