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.Circle) { 12 fabric.warn('fabric.Circle is already defined.'); 13 return; 14 } 15 16 /** 17 * @class Circle 18 * @extends fabric.Object 19 */ 20 fabric.Circle = fabric.util.createClass(fabric.Object, /** @scope fabric.Circle.prototype */ { 21 22 /** 23 * @property 24 * @type String 25 */ 26 type: 'circle', 27 28 /** 29 * Constructor 30 * @method initialize 31 * @param {Object} [options] Options object 32 * @return {fabric.Circle} thisArg 33 */ 34 initialize: function(options) { 35 options = options || { }; 36 37 this.set('radius', options.radius || 0); 38 this.callSuper('initialize', options); 39 40 var radiusBy2ByScale = this.get('radius') * 2 * this.get('scaleX'); 41 this.set('width', radiusBy2ByScale).set('height', radiusBy2ByScale); 42 }, 43 44 /** 45 * Returns object representation of an instance 46 * @method toObject 47 * @return {Object} object representation of an instance 48 */ 49 toObject: function() { 50 return extend(this.callSuper('toObject'), { 51 radius: this.get('radius') 52 }); 53 }, 54 55 /** 56 * @private 57 * @method _render 58 * @param ctx {CanvasRenderingContext2D} context to render on 59 */ 60 _render: function(ctx, noTransform) { 61 ctx.beginPath(); 62 // multiply by currently set alpha (the one that was set by path group where this object is contained, for example) 63 ctx.globalAlpha *= this.opacity; 64 ctx.arc(noTransform ? this.left : 0, noTransform ? this.top : 0, this.radius, 0, piBy2, false); 65 ctx.closePath(); 66 if (this.fill) { 67 ctx.fill(); 68 } 69 if (this.stroke) { 70 ctx.stroke(); 71 } 72 }, 73 74 /** 75 * Returns horizontal radius of an object (according to how an object is scaled) 76 * @method getRadiusX 77 * @return {Number} 78 */ 79 getRadiusX: function() { 80 return this.get('radius') * this.get('scaleX'); 81 }, 82 83 /** 84 * Returns vertical radius of an object (according to how an object is scaled) 85 * @method getRadiusY 86 * @return {Number} 87 */ 88 getRadiusY: function() { 89 return this.get('radius') * this.get('scaleY'); 90 }, 91 92 /** 93 * Returns complexity of an instance 94 * @method complexity 95 * @return {Number} complexity of this instance 96 */ 97 complexity: function() { 98 return 1; 99 } 100 }); 101 102 /** 103 * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement}) 104 * @static 105 * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement 106 */ 107 fabric.Circle.ATTRIBUTE_NAMES = 'cx cy r fill fill-opacity opacity stroke stroke-width transform'.split(' '); 108 109 /** 110 * Returns {@link fabric.Circle} instance from an SVG element 111 * @static 112 * @method fabric.Circle.fromElement 113 * @param element {SVGElement} element to parse 114 * @param options {Object} options object 115 * @throws {Error} If value of `r` attribute is missing or invalid 116 * @return {Object} instance of fabric.Circle 117 */ 118 fabric.Circle.fromElement = function(element, options) { 119 options || (options = { }); 120 var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); 121 if (!isValidRadius(parsedAttributes)) { 122 throw Error('value of `r` attribute is required and can not be negative'); 123 } 124 if ('left' in parsedAttributes) { 125 parsedAttributes.left -= (options.width / 2) || 0; 126 } 127 if ('top' in parsedAttributes) { 128 parsedAttributes.top -= (options.height / 2) || 0; 129 } 130 return new fabric.Circle(extend(parsedAttributes, options)); 131 }; 132 133 /** 134 * @private 135 */ 136 function isValidRadius(attributes) { 137 return (('radius' in attributes) && (attributes.radius > 0)); 138 } 139 140 /** 141 * Returns {@link fabric.Circle} instance from an object representation 142 * @static 143 * @method fabric.Circle.fromObject 144 * @param {Object} object Object to create an instance from 145 * @return {Object} Instance of fabric.Circle 146 */ 147 fabric.Circle.fromObject = function(object) { 148 return new fabric.Circle(object); 149 }; 150 151 })(this);