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