1 //= require "object.class" 2 3 (function(global){ 4 5 "use strict"; 6 7 var fabric = global.fabric || (global.fabric = { }), 8 piBy2 = Math.PI * 2, 9 extend = fabric.util.object.extend; 10 11 if (fabric.Ellipse) { 12 fabric.warn('fabric.Ellipse is already defined.'); 13 return; 14 } 15 16 /** 17 * @class Ellipse 18 * @extends fabric.Object 19 */ 20 fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @scope fabric.Ellipse.prototype */ { 21 22 /** 23 * @property 24 * @type String 25 */ 26 type: 'ellipse', 27 28 /** 29 * Constructor 30 * @method initialize 31 * @param {Object} [options] Options object 32 * @return {Object} thisArg 33 */ 34 initialize: function(options) { 35 options = options || { }; 36 37 this.callSuper('initialize', options); 38 39 this.set('rx', options.rx || 0); 40 this.set('ry', options.ry || 0); 41 42 this.set('width', this.get('rx') * 2); 43 this.set('height', this.get('ry') * 2); 44 }, 45 46 /** 47 * Returns object representation of an instance 48 * @method toObject 49 * @return {Object} object representation of an instance 50 */ 51 toObject: function() { 52 return extend(this.callSuper('toObject'), { 53 rx: this.get('rx'), 54 ry: this.get('ry') 55 }); 56 }, 57 58 /** 59 * Renders this instance on a given context 60 * @method render 61 * @param ctx {CanvasRenderingContext2D} context to render on 62 * @param noTransform {Boolean} context is not transformed when set to true 63 */ 64 render: function(ctx, noTransform) { 65 // do not use `get` for perf. reasons 66 if (this.rx === 0 || this.ry === 0) return; 67 return this.callSuper('render', ctx, noTransform); 68 }, 69 70 /** 71 * @private 72 * @method _render 73 * @param ctx {CanvasRenderingContext2D} context to render on 74 */ 75 _render: function(ctx, noTransform) { 76 ctx.beginPath(); 77 ctx.save(); 78 ctx.transform(1, 0, 0, this.ry/this.rx, 0, 0); 79 ctx.arc(noTransform ? this.left : 0, noTransform ? this.top : 0, this.rx, 0, piBy2, false); 80 ctx.restore(); 81 if (this.stroke) { 82 ctx.stroke(); 83 } 84 if (this.fill) { 85 ctx.fill(); 86 } 87 }, 88 89 /** 90 * Returns complexity of an instance 91 * @method complexity 92 * @return {Number} complexity 93 */ 94 complexity: function() { 95 return 1; 96 } 97 }); 98 99 /** 100 * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement}) 101 * @static 102 * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement 103 */ 104 fabric.Ellipse.ATTRIBUTE_NAMES = 'cx cy rx ry fill fill-opacity stroke stroke-width transform'.split(' '); 105 106 /** 107 * Returns {@link fabric.Ellipse} instance from an SVG element 108 * @static 109 * @method fabric.Ellipse.fromElement 110 * @param {SVGElement} element Element to parse 111 * @param {Object} [options] Options object 112 * @return {fabric.Ellipse} 113 */ 114 fabric.Ellipse.fromElement = function(element, options) { 115 options || (options = { }); 116 var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES); 117 if ('left' in parsedAttributes) { 118 parsedAttributes.left -= (options.width / 2) || 0; 119 } 120 if ('top' in parsedAttributes) { 121 parsedAttributes.top -= (options.height / 2) || 0; 122 } 123 return new fabric.Ellipse(extend(parsedAttributes, options)); 124 }; 125 126 /** 127 * Returns fabric.Ellipse instance from an object representation 128 * @static 129 * @method fabric.Ellipse.fromObject 130 * @param {Object} object Object to create an instance from 131 * @return {fabric.Ellipse} 132 */ 133 fabric.Ellipse.fromObject = function(object) { 134 return new fabric.Ellipse(object); 135 } 136 })(this);