      1 //= require "object.class"
      2
      3 (function() {
      4
      5   var fabric = this.fabric || (this.fabric = { }),
      6       extend = fabric.util.object.extend,
      7       min = fabric.util.array.min,
      8       max = fabric.util.array.max;
      9
     10   if (fabric.Polygon) {
     11     fabric.warn('fabric.Polygon is already defined');
     12     return;
     13   }
     14
     15   function byX(p) { return p.x; }
     16   function byY(p) { return p.y; }
     17
     18   /**
     19    * @class Polygon
     20    * @extends fabric.Object
     21    */
     22   fabric.Polygon = fabric.util.createClass(fabric.Object, /** @scope fabric.Polygon.prototype */ {
     23
     24     /**
     25      * @property
     26      * @type String
     27      */
     28     type: 'polygon',
     29
     30     /**
     31      * Constructor
     32      * @method initialize
     33      * @param {Array} points Array of points
     34      * @param {Object} options Options object
     35      * @return {fabric.Polygon} thisArg
     36      */
     37     initialize: function(points, options) {
     38       options = options || { };
     39       this.points = points;
     40       this.callSuper('initialize', options);
     41       this._calcDimensions();
     42     },
     43
     44     /**
     45      * @private
     46      * @method _calcDimensions
     47      */
     48     _calcDimensions: function() {
     49
     50       var points = this.points,
     51           minX = min(points, 'x'),
     52           minY = min(points, 'y'),
     53           maxX = max(points, 'x'),
     54           maxY = max(points, 'y');
     55
     56       this.width = maxX - minX;
     57       this.height = maxY - minY;
     58       this.minX = minX;
     59       this.minY = minY;
     60     },
     61
     62     /**
     63      * Returns object representation of an instance
     64      * @method toObject
     65      * @return {Object} object representation of an instance
     66      */
     67     toObject: function() {
     68       return extend(this.callSuper('toObject'), {
     69         points: this.points.concat()
     70       });
     71     },
     72
     73     /**
     74      * @private
     75      * @method _render
     76      * @param ctx {CanvasRenderingContext2D} context to render on
     77      */
     78     _render: function(ctx) {
     79       var point;
     80       ctx.beginPath();
     81       for (var i = 0, len = this.points.length; i < len; i++) {
     82         point = this.points[i];
     83         ctx.lineTo(point.x, point.y);
     84       }
     85       if (this.fill) {
     86         ctx.fill();
     87       }
     88       if (this.stroke) {
     89         ctx.closePath();
     90         ctx.stroke();
     91       }
     92     },
     93
     94     /**
     95      * Returns complexity of an instance
     96      * @method complexity
     97      * @return {Number} complexity of this instance
     98      */
     99     complexity: function() {
    100       return this.points.length;
    101     }
    102   });
    103
    104   /**
    105    * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`)
    106    * @static
    107    * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement
    108    */
    109   fabric.Polygon.ATTRIBUTE_NAMES = 'fill fill-opacity stroke stroke-width transform'.split(' ');
    110
    111   /**
    112    * Returns fabric.Polygon instance from an SVG element
    113    * @static
    114    * @method fabric.Polygon.fromElement
    115    * @param {SVGElement} element Element to parse
    116    * @param {Object} options Options object
    117    * @return {fabric.Polygon}
    118    */
    119   fabric.Polygon.fromElement = function(element, options) {
    120     if (!element) {
    121       return null;
    122     }
    123     options || (options = { });
    124
    125     var points = fabric.parsePointsAttribute(element.getAttribute('points')),
    126         parsedAttributes = fabric.parseAttributes(element, fabric.Polygon.ATTRIBUTE_NAMES);
    127
    128     for (var i = 0, len = points.length; i < len; i++) {
    129       // normalize coordinates, according to containing box (dimensions of which are passed via `options`)
    130       points[i].x -= (options.width / 2) || 0;
    131       points[i].y -= (options.height / 2) || 0;
    132     }
    133
    134     return new fabric.Polygon(points, extend(parsedAttributes, options));
    135   };
    136
    137   /**
    138    * Returns fabric.Polygon instance from an object representation
    139    * @static
    140    * @method fabric.Polygon.fromObject
    141    * @param {Object} object Object to create an instance from
    142    * @return {fabric.Polygon}
    143    */
    144   fabric.Polygon.fromObject = function(object) {
    145     return new fabric.Polygon(object.points, object);
    146   }
    147 })();