// o---------------------------------------------------------------------------------o // | This file is part of the RGraph package - you can learn more at: | // | | // | https://www.rgraph.net/license.html | // | | // | RGraph is dual-licensed under the Open Source GPL license. That means that it's | // | free to use and there are no restrictions on what you can use RGraph for! | // | If the GPL license does not suit you however, then there's an inexpensive | // | commercial license option available. See the URL above for more details. | // o---------------------------------------------------------------------------------o // // Initialise the various objects // RGraph = window.RGraph || {isrgraph:true,isRGraph: true,rgraph:true}; // // The constructor // RGraph.starburst = RGraph.Starburst = RGraph.StarBurst = function (conf) { var id = conf.id, canvas = document.getElementById(id); // Get the canvas and context objects this.id = id; this.canvas = canvas; this.context = this.canvas.getContext('2d'); this.type = 'starburst'; this.imageCache = []; this.frame = 1; this.rotatedAngle = (0 - (Math.PI / 2)); this.isRGraph = true; this.isrgraph = true; this.rgraph = true; this.properties = { colors: ['white','#666'], radius: 500, delay: null, segments: 12, centerx: null, centery: null, callback: null, animationStep: 0.0005, radiusMultiplier: 0, radiusIncrement: 0.01, image: null, imageHalign: 'center', imageValign: 'center', imageScale: 1, imageX: null, imageY: null, imageW: null, imageH: null, imageShadow: false, imageShadowOffsetx: 3, imageShadowOffsety: 3, imageShadowColor: '#666', imageShadowBlur: 3, }; var prop = this.properties; var properties = this.properties; // // A setter // // @param name string The name of the property to set // @param value mixed The value of the property // this.set = function (name) { var value = typeof arguments[1] === 'undefined' ? null : arguments[1]; // the number of arguments is only one and it's an // object - parse it for configuration data and return. if (arguments.length === 1 && typeof arguments[0] === 'object') { for (i in arguments[0]) { if (typeof i === 'string') { this.set(i, arguments[0][i]); } } return this; } properties[name] = value; return this; }; // Returns the requested property this.get = function (name) { return properties[name]; } // // The main draw function that gets everything going // this.draw = function () { // Determine the starting angle var start = (0 - (Math.PI / 2)) + ((properties.frame / (180 / Math.PI) / 10)); if (this.isNull(properties.centerx)) properties.centerx = canvas.width / 2; if (this.isNull(properties.centery)) properties.centery = canvas.height / 2; // Start by clearing the canvas this.context.clearRect(-5,-5, this.canvas.width + 10, this.canvas.height + 10); var grad = this.context.createRadialGradient(properties.centerx, properties.centery, 0, properties.centerx, properties.centery, properties.radius); grad.addColorStop(0,properties.colors[0]); for (var i=1,len=properties.colors.length; i<len; ++i) { grad.addColorStop((1 / (len - 1)) * i, properties.colors[i]); } // The main loop that does the drawing for (var i=0; i<(properties.segments * 2); ++i) { this.startAngle = this.rotatedAngle + (((360 / (properties.segments * 2)) * i) / (180 / Math.PI) ); this.endAngle = this.startAngle + (((360 / (properties.segments * 2))) / (180 / Math.PI) ), color = (i % 2 === 0 ? grad : 'rgba(0,0,0,0)'); this.startAngle += this.frame * properties.animationStep; this.endAngle += this.frame * properties.animationStep; // This draws an arm of the StarBurst this.context.beginPath(); this.context.fillStyle = color; this.context.moveTo(properties.centerx, properties.centery); this.context.arc( properties.centerx, properties.centery, properties.radius * (properties.animationStep === 0 ? 1 : properties.radiusMultiplier), this.startAngle, this.endAngle, false ); this.context.fill(); } // // Draw an image if one is specified // if (properties.image) { // // If there was an image specified then load it if it isn't // cached and then draw it on the canvas // if (properties.image && !this.imageCache[properties.image]) { this.imageCache[properties.image] = new Image(); this.imageCache[properties.image].src = properties.image; var obj = this; this.imageCache[properties.image].onload = function () { obj.draw(); }; return; } var frameMultiplier = Math.min(1, properties.frame); // Work out the image coordinates if (!this.imageCoordsCalculated) { // // Centered alignment // var imageX = properties.centerx, imageY = properties.centery, imageW = this.imageCache[properties.image].width * properties.imageScale, imageH = this.imageCache[properties.image].height * properties.imageScale; // Custom coords given if (typeof properties.imageX === 'number') imageX = properties.imageX; if (typeof properties.imageY === 'number') imageY = properties.imageY; if (typeof properties.imageW === 'number') imageW = properties.imageW; if (typeof properties.imageH === 'number') imageH = properties.imageH; if (properties.imageHalign === 'right') { imageX = imageX - imageW; } else if (properties.imageHalign === 'left') { imageX = imageX; } else { imageX = imageX - (imageW / 2); } // Handle valign being top or bottom if (properties.imageValign === 'bottom') { imageY = imageY - imageH; } else if (properties.imageValign === 'top') { imageY = imageY; } else { imageY = imageY - (imageH / 2); } properties.imageX = imageX; properties.imageY = imageY; properties.imageW = imageW; properties.imageH = imageH; // Don't do this again this.imageCoordsCalculated = true; } // Add shadow if necessary if (properties.imageShadow) { this.context.shadowOffsetX = properties.imageShadowOffsetx; this.context.shadowOffsetY = properties.imageShadowOffsety; this.context.shadowColor = properties.imageShadowColor; this.context.shadowBlur = properties.imageShadowBlur; } // Call the canvas API drawImage function this.context.drawImage( this.imageCache[properties.image], properties.imageX, properties.imageY, properties.imageW, properties.imageH ); // If the shadow is enabled turn it off if (properties.imageShadow) { this.context.shadowOffsetX = 0; this.context.shadowOffsetY = 0; this.context.shadowColor = 'rgba(0,0,0,0)'; this.context.shadowBlur = 0; } } // Call the user defined function that was passed into the // function. The callback. if (typeof properties.callback === 'function') { var callbackReturn = properties.callback(this); } // Increment the frame counter this.frame = ++this.frame; // Update the radiusMultiplier if (properties.radiusMultiplier < 1) { properties.radiusMultiplier += properties.radiusIncrement; } // Call the StarBurst() function again after a small delay if (callbackReturn !== false && properties.animationStep !== 0) { var obj = this; if (window.requestAnimationFrame && this.isNull(properties.delay)) { window.requestAnimationFrame(function () { obj.draw(); }) } else { setTimeout(function () { obj.draw(); }, properties.delay); } // end if } // end if // Facilitate chaining return this; } // end draw function // // Returns true/false as to whether the given variable is null or not // // @param mixed arg The argument to check // this.isNull = function (arg) { // MUST BE DOUBLE EQUALS FOR THE FIRST TEST - NOT TRIPLE if (arg == null || typeof arg === 'object' && !arg) { return true; } return false; }; // End RGraph.isNull function // Set the configuration properties for (var i in conf.options) { if (typeof i === 'string') { this.set(i, conf.options[i]); } } // This facilitates chaining return this; }; // end RGraph.StarBurst function