// 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 // // This is a library of a few functions that make it easier to do // effects like fade-ins or expansion. // // // Initialise the various objects // RGraph = window.RGraph || {isrgraph:true,isRGraph: true,rgraph:true}; RGraph.Effects = RGraph.Effects || {}; RGraph.Effects.Common = {}; // Module pattern (function (win, doc, undefined) { var ua = navigator.userAgent; // // This functions adds the generic effects to thechart object // // @param object obj The chart object // RGraph.Effects.decorate = function (obj) { for (i in RGraph.Effects.Common) { if (typeof RGraph.Effects.Common[i] === 'function') { obj[i] = RGraph.Effects.Common[i]; } } }; // // A function used to replace the canvas with a DIV, which in turn holds the canvas. This way the page // layout doesn't shift in the canvas is resized. // // @param object canvas The canvas to replace. // RGraph.Effects.wrap = function (canvas) { if (!canvas.rgraph_wrapper) { // Create the place holder DIV var div = jQuery('
').css({ width: canvas.width + 'px', height: canvas.height + 'px', cssFloat: canvas.style.cssFloat, left: canvas.style.left, top: canvas.style.top, display: 'inline-block' }).get(0); // Add the new DIV to the DOM canvas.parentNode.insertBefore(div, canvas); // Remove the canvas from the document canvas.parentNode.removeChild(canvas); // Add it back in as a child of the place holder div.appendChild(canvas); // Reset the positioning information on the canvas canvas.style.position = 'relative'; canvas.style.left = (div.offsetWidth / 2) + 'px'; canvas.style.top = (div.offsetHeight / 2) + 'px'; canvas.style.cssFloat = ''; // Add a reference to the canvas to the DIV so that repeated plays of the anumation // don't keep replacing the canvas with a new DIV canvas.rgraph_wrapper = div; } var div = canvas.rgraph_wrapper; return div; }; // // fadeIn // // This function simply uses the CSS opacity property - initially set to zero and // increasing to 1 over the period of 0.5 second // RGraph.Effects.Common.fadeIn = function () { // This function gets added to the chart object - so the this // variable is the chart object var obj = this; var opt = arguments[0] || {}; var frames = opt.frames || 30; var duration = (frames / 60) * 1000; var frame = 0; var callback = arguments[1] || function () {}; // Initially the opacity should be zero obj.canvas.style.opacity = 0; // Draw the chart RGraph.redrawCanvas(obj.canvas); // Now fade the chart in for (var i=1; i<=frames; ++i) { (function (index) { setTimeout(function () { obj.canvas.style.opacity = (index / frames); if (index >= frames) { callback(obj); } }, (index / frames) * duration); })(i) } return obj; }; // // fadeOut // // This function is a reversal of the above function - fading out instead of in // RGraph.Effects.Common.fadeOut = function () { // This function gets added to the chart object - so the this // variable is the chart object var obj = this; var opt = arguments[0] || {}; var frames = opt.frames || 30; var duration = (frames / 60) * 1000; var frame = 0; var callback = arguments[1] || function () {}; // Now fade the chart out for (var i=1; i<=frames; ++i) { (function (index) { setTimeout(function () { obj.canvas.style.opacity = 1 - (index / frames); if (index >= frames) { callback(obj); } }, (index / frames) * duration); })(i) } return this; }; // // fadeSlideIn // // This function fades the canvas in in a sliding motion // RGraph.Effects.Common.fadeSlideIn = function () { // This function gets added to the chart object - so the this // variable is the chart object var obj = this, opt = arguments[0] || {}, frames = opt.frames || 30, frame = 0, pc = -20, step = (120 - pc) / frames, canvasXY = RGraph.getCanvasXY(obj.canvas), color = opt.color || 'white', callback = arguments[1] || function () {}; // Draw the chart RGraph.redrawCanvas(obj.canvas); // Create the cover jQuery('
').css({ background: 'linear-gradient(135deg, rgba(255,255,255,0) ' + pc + '%, ' + color + ' ' + (pc + 20) + '%)', width:obj.canvas.width + 'px', height: obj.canvas.height + 'px', top: canvasXY[1] + 'px', left: canvasXY[0] + 'px', position: 'absolute' }).appendTo(jQuery(obj.canvas.parentNode)); function iterator () { if (pc < 120) { jQuery('div#rgraph_fadeslide_cover_' + obj.id).css({ background: 'linear-gradient(135deg, rgba(255,255,255,0) ' + pc + '%, ' + color + ' ' + (pc + 20) + '%)' }); pc += step; RGraph.Effects.updateCanvas(iterator); } else { jQuery('div#rgraph_fadeslide_cover_' + obj.id).remove(); callback(obj); } } iterator(); }; // // fadeSlideOut // // Fades the canvas out in a sliding motion // RGraph.Effects.Common.fadeSlideOut = function () { // This function gets added to the chart object - so the this // variable is the chart object var obj = this; var opt = arguments[0] || {}; var frames = opt.frames || 30; var frame = 0; var pc = -20; var step = (120 - pc) / frames; var canvasXY = RGraph.getCanvasXY(obj.canvas); var color = opt.color || 'white'; var callback = arguments[1] || function () {}; // Draw the chart RGraph.redrawCanvas(obj.canvas); // Create the cover jQuery('
').css({ background: 'linear-gradient(135deg, ' + color + ' ' + pc + '%, rgba(255,255,255,0) ' + (pc + 20) + '%)', width:obj.canvas.width + 'px', height: obj.canvas.height + 'px', top: canvasXY[1] + 'px', left: canvasXY[0] + 'px', position: 'absolute' }).appendTo(jQuery(obj.canvas.parentNode)); function iterator () { if (pc < 120) { jQuery('div#rgraph_fadeslide_cover_' + obj.id).css({ background: 'linear-gradient(135deg, ' + color + ' ' + pc + '%, rgba(255,255,255,0) ' + (pc + 20) + '%)' }); pc += step; RGraph.Effects.updateCanvas(iterator); } else { RGraph.clear(obj.canvas, obj.get('clearto')) jQuery('div#rgraph_fadeslide_cover_' + obj.id).remove(); callback(obj); } } iterator(); }; // // fadeCircularIn // // This function uses radial CSS gradients to cover the canvas with a radial fade in effect // (from the center outwards) // RGraph.Effects.Common.fadeCircularInOutwards = function () { // This function gets added to the chart object - so the this // variable is the chart object var obj = this; var opt = arguments[0] || {}; var frames = opt.frames || 120; var frame = 0; var radius = 0; var canvasXY = RGraph.getCanvasXY(obj.canvas); var color = opt.color || 'white'; var callback = arguments[1] || function () {}; // Draw the chart RGraph.redrawCanvas(obj.canvas); // Create the cover jQuery('
').css({ background: 'radial-gradient(rgba(255,255,255,0) 0%, white ' + radius + '%)', width: obj.canvas.width + 'px', height: obj.canvas.height + 'px', top: canvasXY[1], left: canvasXY[0], position: 'absolute' }).appendTo(jQuery(obj.canvas.parentNode)); function iterator () { if (frame < frames) { jQuery('div#rgraph_fadeslide_cover_' + obj.id).css({ background: 'radial-gradient(rgba(255,255,255,0) ' + ((frame++ / frames) * 100) + '%, ' + color + ' ' + ((frame++ / frames) * 150) + '%)' }); RGraph.Effects.updateCanvas(iterator); } else { jQuery('div#rgraph_fadeslide_cover_' + obj.id).remove(); callback(obj); } } iterator(); }; // // fadeCircularOut // // This function uses radial CSS gradients to cover the canvas with a radial fade out effect // (from the center outwards) // RGraph.Effects.Common.fadeCircularOutOutwards = function () { // This function gets added to the chart object - so the this // variable is the chart object var obj = this; var opt = arguments[0] || {}; var frames = opt.frames || 120; var frame = 0; var canvasXY = RGraph.getCanvasXY(obj.canvas); var color = opt.color || 'white'; var callback = arguments[1] || function () {}; // Draw the chart RGraph.redrawCanvas(obj.canvas); // Create the cover jQuery('
').css({ background: 'radial-gradient(rgba(255,255,255,0) 0%, white 0%)', width: obj.canvas.width + 'px', height: obj.canvas.height + 'px', top: canvasXY[1], left: canvasXY[0], position: 'absolute' }).appendTo(jQuery(obj.canvas.parentNode)); function iterator () { if (frame < frames) { jQuery('div#rgraph_fadeslide_cover_' + obj.id).css({ background: 'radial-gradient(' + color + ' ' + ((frame++ / frames) * 100) + '%, rgba(255,255,255,0) ' + ((frame++ / frames) * 150) + '%)' }); RGraph.Effects.updateCanvas(iterator); } else { RGraph.clear(obj.canvas, color); jQuery('div#rgraph_fadeslide_cover_' + obj.id).remove(); callback(obj); } } iterator(); }; // // fadeCircularInInwards // RGraph.Effects.Common.fadeCircularInInwards = function () { // This function gets added to the chart object - so the this // variable is the chart object var obj = this; var opt = arguments[0] || {}; var frames = opt.frames || 120; var frame = 0; var radius = Math.max(obj.canvas.width, obj.canvas.height); var canvasXY = RGraph.getCanvasXY(obj.canvas); var color = opt.color || 'white'; var callback = arguments[1] || function () {}; // Draw the chart RGraph.redrawCanvas(obj.canvas); // Create the cover jQuery('
').css({ background: 'radial-gradient(rgba(255,255,255,0) 100%, rgba(255,255,255,0) 0%)', width:obj.canvas.width + 'px', height: obj.canvas.height + 'px', top: canvasXY[1] + 'px', left: canvasXY[0] + 'px', position: 'absolute' }).appendTo(jQuery(obj.canvas.parentNode)); function iterator () { if (frame < frames) { jQuery('div#rgraph_fadeslide_cover_' + obj.id).css({ background: 'radial-gradient(' + color + ' ' + (( (frames - frame++) / frames) * 100) + '%, rgba(255,255,255,0) ' + (( (frames - frame++) / frames) * 120) + '%)' }); RGraph.Effects.updateCanvas(iterator); } else { jQuery('div#rgraph_fadeslide_cover_' + obj.id).remove(); callback(obj); } } iterator(); }; // // fadeCircularOutReverse // RGraph.Effects.Common.fadeCircularOutInwards = function () { // This function gets added to the chart object - so the this // variable is the chart object var obj = this; var opt = arguments[0] || {}; var frames = opt.frames || 120; var frame = 0; var radius = Math.max(obj.canvas.width, obj.canvas.height); var canvasXY = RGraph.getCanvasXY(obj.canvas); var color = opt.color || 'white'; var callback = arguments[1] || function () {}; // Draw the chart RGraph.redrawCanvas(obj.canvas); // Create the cover jQuery('
').css({ background: 'radial-gradient(rgba(255,255,255,0) 0%, rgba(255,255,255,0) 0%)', width:obj.canvas.width + 'px', height: obj.canvas.height + 'px', top: canvasXY[1], left: canvasXY[0], position: 'absolute' }).appendTo(jQuery(obj.canvas.parentNode)); function iterator () { if (frame < frames) { jQuery('div#rgraph_fadeslide_cover_' + obj.id).css({ background: 'radial-gradient(rgba(255,255,255,0) ' + (( (frames - frame++) / frames) * 100) + '%, ' + color + ' ' + (( (frames - frame++) / frames) * 120) + '%)' }); RGraph.Effects.updateCanvas(iterator); } else { RGraph.clear(obj.canvas); jQuery('div#rgraph_fadeslide_cover_' + obj.id).remove(); callback(obj); } } iterator(); }; // // Expand // // This effect is like the tooltip effect of the same name. I starts in the middle // and expands out to full size. // // @param object obj The graph object // RGraph.Effects.Common.expand = function () { // This function gets added to the chart object - so the this // variable is the chart object var obj = this; var opt = arguments[0] || {}; var bounce = typeof opt.bounce === 'boolean' ? opt.bounce : true; var frames = opt.frames || 60; var duration = (frames / 60) * 1000; var callback = arguments[1] || function () {}; if (!this.canvas.rgraph_wrapper) { var div = RGraph.Effects.wrap(this.canvas); this.canvas.rgraph_wrapper = div; } else { div = this.canvas.rgraph_wrapper; } div.style.position = 'relative'; //this.canvas.style.position = 'relative'; // absolute should work here too - but doesn't in Chrome this.canvas.style.top = (this.canvas.height / 2) + 'px'; this.canvas.style.left = (this.canvas.width / 2) + 'px'; this.canvas.style.width = 0; this.canvas.style.height = 0; this.canvas.style.opacity = 0; RGraph.clear(this.canvas); RGraph.redrawCanvas(this.canvas); if (bounce) { jQuery('#' + obj.id).animate({opacity: 1, width: (obj.canvas.width * 1.2) + 'px', height: (obj.canvas.height * 1.2) + 'px', left: (obj.canvas.width * -0.1) + 'px', top: (obj.canvas.height * -0.1) + 'px'}, duration * 0.5, function () { jQuery('#' + obj.id).animate({width: (obj.canvas.width * 0.9) + 'px', height: (obj.canvas.height * 0.9) + 'px', top: (obj.canvas.height * 0.05) + 'px', left: (obj.canvas.width * 0.05) + 'px'}, duration * 0.25, function () { jQuery('#' + obj.id).animate({width: obj.canvas.width + 'px', height: obj.canvas.height + 'px', top: 0, left: 0}, duration * 0.25, function () {callback(obj);}); }); }); } else { jQuery(obj.canvas).animate({ opacity: 1, width: obj.canvas.width + 'px', height: obj.canvas.height + 'px', left: 0, top: 0 }, duration, function () {callback(obj);}) } return this; }; // // Contract // // This effect is a good one to use with the Expand effect to make a transition // // @param object You can specify frames here: {frames: 120} // @param function Optional callback to run when the effect is done. // RGraph.Effects.Common.contract = function () { // This function gets added to the chart object - so the this // variable is the chart object var obj = this; var opt = arguments[0] || {}; var frames = opt.frames || 60; var duration = (frames / 60) * 1000; var callback = arguments[1] || function () {}; if (!obj.canvas.rgraph_wrapper) { var div = RGraph.Effects.wrap(obj.canvas); obj.canvas.rgraph_wrapper = div; } else { div = obj.canvas.rgraph_wrapper; } div.style.position = 'relative'; //canvas.style.position = 'absolute'; // Chrome bug...? obj.canvas.style.top = 0; obj.canvas.style.left = 0; if (opt.bounce !== false) { jQuery('#' + obj.id).animate({ width: (obj.canvas.width * 1.2) + 'px', height: (obj.canvas.height * 1.2) + 'px', left: (obj.canvas.width * -0.1) + 'px', top: (obj.canvas.height * -0.1) + 'px' }, duration * 0.25, function () { jQuery('#' + obj.id).animate({ opacity: 0, width: 0, height: 0, left: (obj.canvas.width * 0.5) + 'px', top: (obj.canvas.height * 0.5) + 'px' }, duration * 0.75, function () {callback(obj);}); }); } else { jQuery('#' + obj.id).animate({ opacity: 0, width: 0, height: 0, left: (obj.canvas.width * 0.5) + 'px', top: (obj.canvas.height * 0.5) + 'px' }, duration * 0.75, function () {callback(obj);}); } return this; }; // // Reveal // // This effect issmilar to the Expand effect - the canvas is slowly revealed from // the centre outwards // // @param object Options for the effect. You can give frames here // @param function An optional callback function // RGraph.Effects.Common.reveal = function () { // This function gets added to the chart object - so the this // variable is the chart object var obj = this; var opt = arguments[0] || {}; var frames = opt.frames || 60; var duration = (frames / 60) * 1000; var callback = arguments[1] || function () {}; var xy = RGraph.getCanvasXY(obj.canvas); var divs = [ ['rgraph_reveal_left_' + obj.id, xy[0], xy[1], obj.canvas.width / 2, obj.canvas.height], ['rgraph_reveal_right_' + obj.id,(xy[0] + (obj.canvas.width / 2)),xy[1],(obj.canvas.width / 2),obj.canvas.height], ['rgraph_reveal_top_' + obj.id,xy[0],xy[1],obj.canvas.width,(obj.canvas.height / 2)], ['rgraph_reveal_bottom_' + obj.id,xy[0],(xy[1] + (obj.canvas.height / 2)),obj.canvas.width,(obj.canvas.height / 2)] ]; for (var i=0,len=divs.length; i 0) { RGraph.Effects.updateCanvas(iterator); // Optional callback } else { if (typeof callback === 'function') { callback(obj); } } } iterator(); } // End Module pattern })(window, document);