Last active
May 21, 2021 09:44
-
-
Save im-noob/90ca0f604531d2cf50cf71e2e5629ef8 to your computer and use it in GitHub Desktop.
Add Loader in page for download reqest
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// js | |
xhr: function() | |
{ | |
var xhr = new window.XMLHttpRequest(); | |
let duration_change = true; | |
//Download progress | |
xhr.addEventListener("progress", function(evt){ | |
if (evt.lengthComputable) { | |
var percentComplete = evt.loaded / evt.total; | |
//Do something with download progress | |
if (duration_change) { | |
progress_circle.circleProgress('duration', 100); | |
duration_change = false; | |
} | |
$('.progress-bar-info').text('We are almost there.'); | |
let percentage_to_show = 0.8 + percentComplete * 0.2; | |
// console.log(percentage_to_show); | |
progress_circle.circleProgress('value', percentage_to_show).on('circle-animation-progress', function(event, progress) { | |
$(this).find('strong').html(Math.round(percentage_to_show * 100 ) + '<i>%</i>'); | |
}); | |
} | |
}, false); | |
return xhr; | |
}, | |
// php | |
return $dataTables->withHeaders(['Content-Length' => strlen($dataTables->getContent())]); | |
// inital load | |
function progress_bar_start() { | |
console.log(calculated_estimated_time,total_cross_time); | |
progress_circle.circleProgress({ | |
value: 0.8, | |
animation: { | |
duration: calculated_estimated_time, | |
easing: 'circleProgressEasing' | |
}, | |
}).on('circle-animation-progress', function(event, progress) { | |
$(this).find('strong').html(Math.round(80 * progress) + '<i>%</i>'); | |
}); | |
} | |
progress_bar_start(); | |
// library | |
/** | |
* jquery-circle-progress - jQuery Plugin to draw animated circular progress bars: | |
* {@link http://kottenator.github.io/jquery-circle-progress/} | |
* | |
* @author Rostyslav Bryzgunov <[email protected]> | |
* @version 1.2.2 | |
* @licence MIT | |
* @preserve | |
*/ | |
// UMD factory - https://github.com/umdjs/umd/blob/d31bb6ee7098715e019f52bdfe27b3e4bfd2b97e/templates/jqueryPlugin.js | |
// Uses AMD, CommonJS or browser globals to create a jQuery plugin. | |
(function(factory) { | |
if (typeof define === 'function' && define.amd) { | |
// AMD - register as an anonymous module | |
define(['jquery'], factory); | |
} else if (typeof module === 'object' && module.exports) { | |
// Node/CommonJS | |
var $ = require('jquery'); | |
factory($); | |
module.exports = $; | |
} else { | |
// Browser globals | |
factory(jQuery); | |
} | |
})(function($) { | |
/** | |
* Inner implementation of the circle progress bar. | |
* The class is not exposed _yet_ but you can create an instance through jQuery method call. | |
* | |
* @param {object} config - You can customize any class member (property or method). | |
* @class | |
* @alias CircleProgress | |
*/ | |
function CircleProgress(config) { | |
this.init(config); | |
} | |
CircleProgress.prototype = { | |
//--------------------------------------- public options --------------------------------------- | |
/** | |
* This is the only required option. It should be from `0.0` to `1.0`. | |
* @type {number} | |
* @default 0.0 | |
*/ | |
value: 0.0, | |
/** | |
* Size of the canvas in pixels. | |
* It's a square so we need only one dimension. | |
* @type {number} | |
* @default 100.0 | |
*/ | |
size: 100.0, | |
/** | |
* Initial angle for `0.0` value in radians. | |
* @type {number} | |
* @default -Math.PI | |
*/ | |
startAngle: -Math.PI, | |
/** | |
* Width of the arc in pixels. | |
* If it's `'auto'` - the value is calculated as `[this.size]{@link CircleProgress#size} / 14`. | |
* @type {number|string} | |
* @default 'auto' | |
*/ | |
thickness: 'auto', | |
/** | |
* Fill of the arc. You may set it to: | |
* | |
* - solid color: | |
* - `'#3aeabb'` | |
* - `{ color: '#3aeabb' }` | |
* - `{ color: 'rgba(255, 255, 255, .3)' }` | |
* - linear gradient _(left to right)_: | |
* - `{ gradient: ['#3aeabb', '#fdd250'], gradientAngle: Math.PI / 4 }` | |
* - `{ gradient: ['red', 'green', 'blue'], gradientDirection: [x0, y0, x1, y1] }` | |
* - `{ gradient: [["red", .2], ["green", .3], ["blue", .8]] }` | |
* - image: | |
* - `{ image: 'http://i.imgur.com/pT0i89v.png' }` | |
* - `{ image: imageObject }` | |
* - `{ color: 'lime', image: 'http://i.imgur.com/pT0i89v.png' }` - | |
* color displayed until the image is loaded | |
* | |
* @default {gradient: ['#3aeabb', '#fdd250']} | |
*/ | |
fill: { | |
gradient: ['#3aeabb', '#fdd250'] | |
}, | |
/** | |
* Color of the "empty" arc. Only a color fill supported by now. | |
* @type {string} | |
* @default 'rgba(0, 0, 0, .1)' | |
*/ | |
emptyFill: 'rgba(0, 0, 0, .1)', | |
/** | |
* jQuery Animation config. | |
* You can pass `false` to disable the animation. | |
* @see http://api.jquery.com/animate/ | |
* @type {object|boolean} | |
* @default {duration: 1200, easing: 'circleProgressEasing'} | |
*/ | |
animation: { | |
duration: 1200, | |
easing: 'circleProgressEasing' | |
}, | |
/** | |
* Default animation starts at `0.0` and ends at specified `value`. Let's call this _direct animation_. | |
* If you want to make _reversed animation_ - set `animationStartValue: 1.0`. | |
* Also you may specify any other value from `0.0` to `1.0`. | |
* @type {number} | |
* @default 0.0 | |
*/ | |
animationStartValue: 0.0, | |
/** | |
* Reverse animation and arc draw. | |
* By default, the arc is filled from `0.0` to `value`, _clockwise_. | |
* With `reverse: true` the arc is filled from `1.0` to `value`, _counter-clockwise_. | |
* @type {boolean} | |
* @default false | |
*/ | |
reverse: false, | |
/** | |
* Arc line cap: `'butt'`, `'round'` or `'square'` - | |
* [read more]{@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.lineCap}. | |
* @type {string} | |
* @default 'butt' | |
*/ | |
lineCap: 'butt', | |
/** | |
* Canvas insertion mode: append or prepend it into the parent element? | |
* @type {string} | |
* @default 'prepend' | |
*/ | |
insertMode: 'prepend', | |
//------------------------------ protected properties and methods ------------------------------ | |
/** | |
* Link to {@link CircleProgress} constructor. | |
* @protected | |
*/ | |
constructor: CircleProgress, | |
/** | |
* Container element. Should be passed into constructor config. | |
* @protected | |
* @type {jQuery} | |
*/ | |
el: null, | |
/** | |
* Canvas element. Automatically generated and prepended to [this.el]{@link CircleProgress#el}. | |
* @protected | |
* @type {HTMLCanvasElement} | |
*/ | |
canvas: null, | |
/** | |
* 2D-context of [this.canvas]{@link CircleProgress#canvas}. | |
* @protected | |
* @type {CanvasRenderingContext2D} | |
*/ | |
ctx: null, | |
/** | |
* Radius of the outer circle. Automatically calculated as `[this.size]{@link CircleProgress#size} / 2`. | |
* @protected | |
* @type {number} | |
*/ | |
radius: 0.0, | |
/** | |
* Fill of the main arc. Automatically calculated, depending on [this.fill]{@link CircleProgress#fill} option. | |
* @protected | |
* @type {string|CanvasGradient|CanvasPattern} | |
*/ | |
arcFill: null, | |
/** | |
* Last rendered frame value. | |
* @protected | |
* @type {number} | |
*/ | |
lastFrameValue: 0.0, | |
/** | |
* Init/re-init the widget. | |
* | |
* Throws a jQuery event: | |
* | |
* - `circle-inited(jqEvent)` | |
* | |
* @param {object} config - You can customize any class member (property or method). | |
*/ | |
init: function(config) { | |
$.extend(this, config); | |
this.radius = this.size / 2; | |
this.initWidget(); | |
this.initFill(); | |
this.draw(); | |
// this.el.trigger('circle-inited'); | |
}, | |
/** | |
* Initialize `<canvas>`. | |
* @protected | |
*/ | |
initWidget: function() { | |
if (!this.canvas) | |
this.canvas = $('<canvas>')[this.insertMode == 'prepend' ? 'prependTo' : 'appendTo'](this.el)[0]; | |
var canvas = this.canvas; | |
canvas.width = this.size; | |
canvas.height = this.size; | |
this.ctx = canvas.getContext('2d'); | |
if (window.devicePixelRatio > 1) { | |
var scaleBy = window.devicePixelRatio; | |
canvas.style.width = canvas.style.height = this.size + 'px'; | |
canvas.width = canvas.height = this.size * scaleBy; | |
this.ctx.scale(scaleBy, scaleBy); | |
} | |
}, | |
/** | |
* This method sets [this.arcFill]{@link CircleProgress#arcFill}. | |
* It could do this async (on image load). | |
* @protected | |
*/ | |
initFill: function() { | |
var self = this, | |
fill = this.fill, | |
ctx = this.ctx, | |
size = this.size; | |
if (!fill) | |
throw Error("The fill is not specified!"); | |
if (typeof fill == 'string') | |
fill = {color: fill}; | |
if (fill.color) | |
this.arcFill = fill.color; | |
if (fill.gradient) { | |
var gr = fill.gradient; | |
if (gr.length == 1) { | |
this.arcFill = gr[0]; | |
} else if (gr.length > 1) { | |
var ga = fill.gradientAngle || 0, // gradient direction angle; 0 by default | |
gd = fill.gradientDirection || [ | |
size / 2 * (1 - Math.cos(ga)), // x0 | |
size / 2 * (1 + Math.sin(ga)), // y0 | |
size / 2 * (1 + Math.cos(ga)), // x1 | |
size / 2 * (1 - Math.sin(ga)) // y1 | |
]; | |
var lg = ctx.createLinearGradient.apply(ctx, gd); | |
for (var i = 0; i < gr.length; i++) { | |
var color = gr[i], | |
pos = i / (gr.length - 1); | |
if ($.isArray(color)) { | |
pos = color[1]; | |
color = color[0]; | |
} | |
lg.addColorStop(pos, color); | |
} | |
this.arcFill = lg; | |
} | |
} | |
if (fill.image) { | |
var img; | |
if (fill.image instanceof Image) { | |
img = fill.image; | |
} else { | |
img = new Image(); | |
img.src = fill.image; | |
} | |
if (img.complete) | |
setImageFill(); | |
else | |
img.onload = setImageFill; | |
} | |
function setImageFill() { | |
var bg = $('<canvas>')[0]; | |
bg.width = self.size; | |
bg.height = self.size; | |
bg.getContext('2d').drawImage(img, 0, 0, size, size); | |
self.arcFill = self.ctx.createPattern(bg, 'no-repeat'); | |
self.drawFrame(self.lastFrameValue); | |
} | |
}, | |
/** | |
* Draw the circle. | |
* @protected | |
*/ | |
draw: function() { | |
if (this.animation) | |
this.drawAnimated(this.value); | |
else | |
this.drawFrame(this.value); | |
}, | |
/** | |
* Draw a single animation frame. | |
* @protected | |
* @param {number} v - Frame value. | |
*/ | |
drawFrame: function(v) { | |
this.lastFrameValue = v; | |
this.ctx.clearRect(0, 0, this.size, this.size); | |
this.drawEmptyArc(v); | |
this.drawArc(v); | |
}, | |
/** | |
* Draw the arc (part of the circle). | |
* @protected | |
* @param {number} v - Frame value. | |
*/ | |
drawArc: function(v) { | |
if (v === 0) | |
return; | |
var ctx = this.ctx, | |
r = this.radius, | |
t = this.getThickness(), | |
a = this.startAngle; | |
ctx.save(); | |
ctx.beginPath(); | |
if (!this.reverse) { | |
ctx.arc(r, r, r - t / 2, a, a + Math.PI * 2 * v); | |
} else { | |
ctx.arc(r, r, r - t / 2, a - Math.PI * 2 * v, a); | |
} | |
ctx.lineWidth = t; | |
ctx.lineCap = this.lineCap; | |
ctx.strokeStyle = this.arcFill; | |
ctx.stroke(); | |
ctx.restore(); | |
}, | |
/** | |
* Draw the _empty (background)_ arc (part of the circle). | |
* @protected | |
* @param {number} v - Frame value. | |
*/ | |
drawEmptyArc: function(v) { | |
var ctx = this.ctx, | |
r = this.radius, | |
t = this.getThickness(), | |
a = this.startAngle; | |
if (v < 1) { | |
ctx.save(); | |
ctx.beginPath(); | |
if (v <= 0) { | |
ctx.arc(r, r, r - t / 2, 0, Math.PI * 2); | |
} else { | |
if (!this.reverse) { | |
ctx.arc(r, r, r - t / 2, a + Math.PI * 2 * v, a); | |
} else { | |
ctx.arc(r, r, r - t / 2, a, a - Math.PI * 2 * v); | |
} | |
} | |
ctx.lineWidth = t; | |
ctx.strokeStyle = this.emptyFill; | |
ctx.stroke(); | |
ctx.restore(); | |
} | |
}, | |
/** | |
* Animate the progress bar. | |
* | |
* Throws 3 jQuery events: | |
* | |
* - `circle-animation-start(jqEvent)` | |
* - `circle-animation-progress(jqEvent, animationProgress, stepValue)` - multiple event | |
* animationProgress: from `0.0` to `1.0`; stepValue: from `0.0` to `value` | |
* - `circle-animation-end(jqEvent)` | |
* | |
* @protected | |
* @param {number} v - Final value. | |
*/ | |
drawAnimated: function(v) { | |
var self = this, | |
el = this.el, | |
canvas = $(this.canvas); | |
// stop previous animation before new "start" event is triggered | |
canvas.stop(true, false); | |
el.trigger('circle-animation-start'); | |
canvas | |
.css({animationProgress: 0}) | |
.animate({animationProgress: 1}, $.extend({}, this.animation, { | |
step: function(animationProgress) { | |
var stepValue = self.animationStartValue * (1 - animationProgress) + v * animationProgress; | |
self.drawFrame(stepValue); | |
el.trigger('circle-animation-progress', [animationProgress, stepValue]); | |
} | |
})) | |
.promise() | |
.always(function() { | |
// trigger on both successful & failure animation end | |
el.trigger('circle-animation-end'); | |
}); | |
}, | |
/** | |
* Get the circle thickness. | |
* @see CircleProgress#thickness | |
* @protected | |
* @returns {number} | |
*/ | |
getThickness: function() { | |
return $.isNumeric(this.thickness) ? this.thickness : this.size / 14; | |
}, | |
/** | |
* Get current value. | |
* @protected | |
* @return {number} | |
*/ | |
getValue: function() { | |
return this.value; | |
}, | |
/** | |
* Set current value (with smooth animation transition). | |
* @protected | |
* @param {number} newValue | |
*/ | |
setValue: function(newValue) { | |
if (this.animation) | |
this.animationStartValue = this.lastFrameValue; | |
this.value = newValue; | |
this.draw(); | |
}, | |
setDuration: function(newValue) { | |
if (this.animation) | |
this.animationStartValue = this.lastFrameValue; | |
this.animation.duration = newValue; | |
this.draw(); | |
} | |
}; | |
//----------------------------------- Initiating jQuery plugin ----------------------------------- | |
$.circleProgress = { | |
// Default options (you may override them) | |
defaults: CircleProgress.prototype | |
}; | |
// ease-in-out-cubic | |
$.easing.circleProgressEasing = function(x) { | |
if (x < 0.5) { | |
x = 2 * x; | |
return 0.5 * x * x * x; | |
} else { | |
x = 2 - 2 * x; | |
return 1 - 0.5 * x * x * x; | |
} | |
}; | |
/** | |
* Creates an instance of {@link CircleProgress}. | |
* Produces [init event]{@link CircleProgress#init} and [animation events]{@link CircleProgress#drawAnimated}. | |
* | |
* @param {object} [configOrCommand] - Config object or command name. | |
* | |
* Config example (you can specify any {@link CircleProgress} property): | |
* | |
* ```js | |
* { value: 0.75, size: 50, animation: false } | |
* ``` | |
* | |
* Commands: | |
* | |
* ```js | |
* el.circleProgress('widget'); // get the <canvas> | |
* el.circleProgress('value'); // get the value | |
* el.circleProgress('value', newValue); // update the value | |
* el.circleProgress('redraw'); // redraw the circle | |
* el.circleProgress(); // the same as 'redraw' | |
* ``` | |
* | |
* @param {string} [commandArgument] - Some commands (like `'value'`) may require an argument. | |
* @see CircleProgress | |
* @alias "$(...).circleProgress" | |
*/ | |
$.fn.circleProgress = function(configOrCommand, commandArgument) { | |
var dataName = 'circle-progress', | |
firstInstance = this.data(dataName); | |
if (configOrCommand == 'widget') { | |
if (!firstInstance) | |
throw Error('Calling "widget" method on not initialized instance is forbidden'); | |
return firstInstance.canvas; | |
} | |
if (configOrCommand == 'value') { | |
if (!firstInstance) | |
throw Error('Calling "value" method on not initialized instance is forbidden'); | |
if (typeof commandArgument == 'undefined') { | |
return firstInstance.getValue(); | |
} else { | |
var newValue = arguments[1]; | |
return this.each(function() { | |
$(this).data(dataName).setValue(newValue); | |
}); | |
} | |
} | |
if (configOrCommand == 'duration') { | |
if (!firstInstance) | |
throw Error('Calling "value" method on not initialized instance is forbidden'); | |
if (typeof commandArgument == 'undefined') { | |
return firstInstance.getValue(); | |
} else { | |
var newValue = arguments[1]; | |
return this.each(function() { | |
$(this).data(dataName).setDuration(newValue); | |
}); | |
} | |
} | |
return this.each(function() { | |
var el = $(this), | |
instance = el.data(dataName), | |
config = $.isPlainObject(configOrCommand) ? configOrCommand : {}; | |
if (instance) { | |
instance.init(config); | |
} else { | |
var initialConfig = $.extend({}, el.data()); | |
if (typeof initialConfig.fill == 'string') | |
initialConfig.fill = JSON.parse(initialConfig.fill); | |
if (typeof initialConfig.animation == 'string') | |
initialConfig.animation = JSON.parse(initialConfig.animation); | |
config = $.extend(initialConfig, config); | |
config.el = el; | |
instance = new CircleProgress(config); | |
el.data(dataName, instance); | |
} | |
}); | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment