(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 Circle * @extends fabric.Object */ fabric.Circle = fabric.util.createClass(fabric.Object, /** @scope fabric.Circle.prototype */ { /** * Type of an object * @property * @type String */ type: 'circle', /** * Constructor * @method initialize * @param {Object} [options] Options object * @return {fabric.Circle} thisArg */ initialize: function(options) { options = options || { }; this.set('radius', options.radius || 0); this.callSuper('initialize', options); var diameter = this.get('radius') * 2; this.set('width', diameter).set('height', diameter); }, /** * Returns object representation of an instance * @method toObject * @param {Array} propertiesToInclude * @return {Object} object representation of an instance */ toObject: function(propertiesToInclude) { return extend(this.callSuper('toObject', propertiesToInclude), { radius: this.get('radius') }); }, /** * Returns svg representation of an instance * @method toSVG * @return {String} svg representation of an instance */ toSVG: function() { return (''); }, /** * @private * @method _render * @param ctx {CanvasRenderingContext2D} context to render on */ _render: function(ctx, noTransform) { ctx.beginPath(); // multiply by currently set alpha (the one that was set by path group where this object is contained, for example) ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity; ctx.arc(noTransform ? this.left : 0, noTransform ? this.top : 0, this.radius, 0, piBy2, false); ctx.closePath(); if (this.fill) { ctx.fill(); } if (this.stroke) { ctx.stroke(); } }, /** * Returns horizontal radius of an object (according to how an object is scaled) * @method getRadiusX * @return {Number} */ getRadiusX: function() { return this.get('radius') * this.get('scaleX'); }, /** * Returns vertical radius of an object (according to how an object is scaled) * @method getRadiusY * @return {Number} */ getRadiusY: function() { return this.get('radius') * this.get('scaleY'); }, /** * Sets radius of an object (and updates width accordingly) * @method setRadius * @return {Number} */ setRadius: function(value) { this.radius = value; this.set('width', value * 2).set('height', value * 2); }, /** * Returns complexity of an instance * @method complexity * @return {Number} complexity of this instance */ complexity: function() { return 1; } }); /** * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement}) * @static * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement */ fabric.Circle.ATTRIBUTE_NAMES = 'cx cy r fill fill-opacity opacity stroke stroke-width transform'.split(' '); /** * Returns {@link fabric.Circle} instance from an SVG element * @static * @method fabric.Circle.fromElement * @param {SVGElement} element Element to parse * @param {Object} [options] Options object * @throws {Error} If value of `r` attribute is missing or invalid * @return {Object} 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'); } if ('left' in parsedAttributes) { parsedAttributes.left -= (options.width / 2) || 0; } if ('top' in parsedAttributes) { parsedAttributes.top -= (options.height / 2) || 0; } var obj = new fabric.Circle(extend(parsedAttributes, options)); obj.cx = parseFloat(element.getAttribute('cx')) || 0; obj.cy = parseFloat(element.getAttribute('cy')) || 0; return obj; }; /** * @private */ function isValidRadius(attributes) { return (('radius' in attributes) && (attributes.radius > 0)); } /** * Returns {@link fabric.Circle} instance from an object representation * @static * @method fabric.Circle.fromObject * @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);