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 })();