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