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 ctx.arc(noTransform ? this.left : 0, noTransform ? this.top : 0, this.radius, 0, piBy2, false); 63 ctx.closePath(); 64 if (this.fill) { 65 ctx.fill(); 66 } 67 if (this.stroke) { 68 ctx.stroke(); 69 } 70 }, 71 72 73 /** 74 * Returns complexity of an instance 75 * @method complexity 76 * @return {Number} complexity of this instance 77 */ 78 complexity: function() { 79 return 1; 80 } 81 }); 82 83 /** 84 * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement}) 85 * @static 86 * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement 87 */ 88 fabric.Circle.ATTRIBUTE_NAMES = 'cx cy r fill fill-opacity stroke stroke-width transform'.split(' '); 89 90 /** 91 * Returns {@link fabric.Circle} instance from an SVG element 92 * @static 93 * @method fabric.Circle.fromElement 94 * @param element {SVGElement} element to parse 95 * @param options {Object} options object 96 * @throws {Error} If value of `r` attribute is missing or invalid 97 * @return {Object} instance of fabric.Circle 98 */ 99 fabric.Circle.fromElement = function(element, options) { 100 options || (options = { }); 101 var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); 102 if (!isValidRadius(parsedAttributes)) { 103 throw Error('value of `r` attribute is required and can not be negative'); 104 } 105 if ('left' in parsedAttributes) { 106 parsedAttributes.left -= (options.width / 2) || 0; 107 } 108 if ('top' in parsedAttributes) { 109 parsedAttributes.top -= (options.height / 2) || 0; 110 } 111 return new fabric.Circle(extend(parsedAttributes, options)); 112 }; 113 114 /** 115 * @private 116 */ 117 function isValidRadius(attributes) { 118 return (('radius' in attributes) && (attributes.radius > 0)); 119 } 120 121 /** 122 * Returns {@link fabric.Circle} instance from an object representation 123 * @static 124 * @method fabric.Circle.fromObject 125 * @param {Object} object Object to create an instance from 126 * @return {Object} Instance of fabric.Circle 127 */ 128 fabric.Circle.fromObject = function(object) { 129 return new fabric.Circle(object); 130 } 131 })(this);