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