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