(function(global) { 'use strict'; var fabric = global.fabric || (global.fabric = { }), piBy2 = Math.PI * 2, extend = fabric.util.object.extend; if (fabric.Circle) { fabric.warn('fabric.Circle is already defined.'); return; } /** * Circle class * @class fabric.Circle * @extends fabric.Object * @see {@link fabric.Circle#initialize} for constructor definition */ fabric.Circle = fabric.util.createClass(fabric.Object, /** @lends fabric.Circle.prototype */ { /** * Type of an object * @type String * @default */ type: 'circle', /** * Radius of this circle * @type Number * @default */ radius: 0, /** * Constructor * @param {Object} [options] Options object * @return {fabric.Circle} thisArg */ initialize: function(options) { options = options || { }; this.callSuper('initialize', options); this.set('radius', options.radius || 0); }, /** * @private * @param {String} key * @param {Any} value * @return {fabric.Circle} thisArg */ _set: function(key, value) { this.callSuper('_set', key, value); if (key === 'radius') { this.setRadius(value); } return this; }, /** * Returns object representation of an instance * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output * @return {Object} object representation of an instance */ toObject: function(propertiesToInclude) { return extend(this.callSuper('toObject', propertiesToInclude), { radius: this.get('radius') }); }, /* _TO_SVG_START_ */ /** * Returns svg representation of an instance * @param {Function} [reviver] Method for further parsing of svg representation. * @return {String} svg representation of an instance */ toSVG: function(reviver) { var markup = this._createBaseSVGMarkup(), x = 0, y = 0; if (this.group) { x = this.left + this.radius; y = this.top + this.radius; } markup.push( '\n' ); return reviver ? reviver(markup.join('')) : markup.join(''); }, /* _TO_SVG_END_ */ /** * @private * @param {CanvasRenderingContext2D} ctx context to render on * @param {Boolean} [noTransform] When true, context is not transformed */ _render: function(ctx, noTransform) { ctx.beginPath(); ctx.arc(noTransform ? this.left + this.radius : 0, noTransform ? this.top + this.radius : 0, this.radius, 0, piBy2, false); this._renderFill(ctx); this._renderStroke(ctx); }, /** * Returns horizontal radius of an object (according to how an object is scaled) * @return {Number} */ getRadiusX: function() { return this.get('radius') * this.get('scaleX'); }, /** * Returns vertical radius of an object (according to how an object is scaled) * @return {Number} */ getRadiusY: function() { return this.get('radius') * this.get('scaleY'); }, /** * Sets radius of an object (and updates width accordingly) * @return {Number} */ setRadius: function(value) { this.radius = value; this.set('width', value * 2).set('height', value * 2); }, /** * Returns complexity of an instance * @return {Number} complexity of this instance */ complexity: function() { return 1; } }); /* _FROM_SVG_START_ */ /** * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement}) * @static * @memberOf fabric.Circle * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement */ fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' ')); /** * Returns {@link fabric.Circle} instance from an SVG element * @static * @memberOf fabric.Circle * @param {SVGElement} element Element to parse * @param {Object} [options] Options object * @throws {Error} If value of `r` attribute is missing or invalid * @return {fabric.Circle} Instance of fabric.Circle */ fabric.Circle.fromElement = function(element, options) { options || (options = { }); var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); if (!isValidRadius(parsedAttributes)) { throw new Error('value of `r` attribute is required and can not be negative'); } parsedAttributes.left = parsedAttributes.left || 0; parsedAttributes.top = parsedAttributes.top || 0; var obj = new fabric.Circle(extend(parsedAttributes, options)); obj.left -= obj.radius; obj.top -= obj.radius; return obj; }; /** * @private */ function isValidRadius(attributes) { return (('radius' in attributes) && (attributes.radius > 0)); } /* _FROM_SVG_END_ */ /** * Returns {@link fabric.Circle} instance from an object representation * @static * @memberOf fabric.Circle * @param {Object} object Object to create an instance from * @return {Object} Instance of fabric.Circle */ fabric.Circle.fromObject = function(object) { return new fabric.Circle(object); }; })(typeof exports !== 'undefined' ? exports : this);