160 lines
4.5 KiB
JavaScript
160 lines
4.5 KiB
JavaScript
var H5P = H5P || {};
|
|
|
|
/**
|
|
* Class responsible for creating a circular progress bar
|
|
*/
|
|
|
|
H5P.JoubelProgressCircle = (function ($) {
|
|
|
|
/**
|
|
* Constructor for the Progress Circle
|
|
*
|
|
* @param {Number} number The amount of progress to display
|
|
* @param {string} progressColor Color for the progress meter
|
|
* @param {string} backgroundColor Color behind the progress meter
|
|
*/
|
|
function ProgressCircle(number, progressColor, fillColor, backgroundColor) {
|
|
progressColor = progressColor || '#1a73d9';
|
|
fillColor = fillColor || '#f0f0f0';
|
|
backgroundColor = backgroundColor || '#ffffff';
|
|
var progressColorRGB = this.hexToRgb(progressColor);
|
|
|
|
//Verify number
|
|
try {
|
|
number = Number(number);
|
|
if (number === '') {
|
|
throw 'is empty';
|
|
}
|
|
if (isNaN(number)) {
|
|
throw 'is not a number';
|
|
}
|
|
} catch (e) {
|
|
number = 'err';
|
|
}
|
|
|
|
//Draw circle
|
|
if (number > 100) {
|
|
number = 100;
|
|
}
|
|
|
|
// We can not use rgba, since they will stack on top of each other.
|
|
// Instead we create the equivalent of the rgba color
|
|
// and applies this to the activeborder and background color.
|
|
var progressColorString = 'rgb(' + parseInt(progressColorRGB.r, 10) +
|
|
',' + parseInt(progressColorRGB.g, 10) +
|
|
',' + parseInt(progressColorRGB.b, 10) + ')';
|
|
|
|
// Circle wrapper
|
|
var $wrapper = $('<div/>', {
|
|
'class': "joubel-progress-circle-wrapper"
|
|
});
|
|
|
|
//Active border indicates progress
|
|
var $activeBorder = $('<div/>', {
|
|
'class': "joubel-progress-circle-active-border"
|
|
}).appendTo($wrapper);
|
|
|
|
//Background circle
|
|
var $backgroundCircle = $('<div/>', {
|
|
'class': "joubel-progress-circle-circle"
|
|
}).appendTo($activeBorder);
|
|
|
|
//Progress text/number
|
|
$('<span/>', {
|
|
'text': number + '%',
|
|
'class': "joubel-progress-circle-percentage"
|
|
}).appendTo($backgroundCircle);
|
|
|
|
var deg = number * 3.6;
|
|
if (deg <= 180) {
|
|
$activeBorder.css('background-image',
|
|
'linear-gradient(' + (90 + deg) + 'deg, transparent 50%, ' + fillColor + ' 50%),' +
|
|
'linear-gradient(90deg, ' + fillColor + ' 50%, transparent 50%)')
|
|
.css('border', '2px solid' + backgroundColor)
|
|
.css('background-color', progressColorString);
|
|
} else {
|
|
$activeBorder.css('background-image',
|
|
'linear-gradient(' + (deg - 90) + 'deg, transparent 50%, ' + progressColorString + ' 50%),' +
|
|
'linear-gradient(90deg, ' + fillColor + ' 50%, transparent 50%)')
|
|
.css('border', '2px solid' + backgroundColor)
|
|
.css('background-color', progressColorString);
|
|
}
|
|
|
|
this.$activeBorder = $activeBorder;
|
|
this.$backgroundCircle = $backgroundCircle;
|
|
this.$wrapper = $wrapper;
|
|
|
|
this.initResizeFunctionality();
|
|
|
|
return $wrapper;
|
|
}
|
|
|
|
/**
|
|
* Initializes resize functionality for the progress circle
|
|
*/
|
|
ProgressCircle.prototype.initResizeFunctionality = function () {
|
|
var self = this;
|
|
|
|
$(window).resize(function () {
|
|
// Queue resize
|
|
setTimeout(function () {
|
|
self.resize();
|
|
});
|
|
});
|
|
|
|
// First resize
|
|
setTimeout(function () {
|
|
self.resize();
|
|
}, 0);
|
|
};
|
|
|
|
/**
|
|
* Resize function makes progress circle grow or shrink relative to parent container
|
|
*/
|
|
ProgressCircle.prototype.resize = function () {
|
|
var $parent = this.$wrapper.parent();
|
|
|
|
if ($parent !== undefined && $parent) {
|
|
|
|
// Measurements
|
|
var fontSize = parseInt($parent.css('font-size'), 10);
|
|
|
|
// Static sizes
|
|
var fontSizeMultiplum = 3.75;
|
|
var progressCircleWidthPx = parseInt((fontSize / 4.5), 10) % 2 === 0 ? parseInt((fontSize / 4.5), 10) + 4 : parseInt((fontSize / 4.5), 10) + 5;
|
|
var progressCircleOffset = progressCircleWidthPx / 2;
|
|
|
|
var width = fontSize * fontSizeMultiplum;
|
|
var height = fontSize * fontSizeMultiplum;
|
|
this.$activeBorder.css({
|
|
'width': width,
|
|
'height': height
|
|
});
|
|
|
|
this.$backgroundCircle.css({
|
|
'width': width - progressCircleWidthPx,
|
|
'height': height - progressCircleWidthPx,
|
|
'top': progressCircleOffset,
|
|
'left': progressCircleOffset
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Hex to RGB conversion
|
|
* @param hex
|
|
* @returns {{r: Number, g: Number, b: Number}}
|
|
*/
|
|
ProgressCircle.prototype.hexToRgb = function (hex) {
|
|
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
return result ? {
|
|
r: parseInt(result[1], 16),
|
|
g: parseInt(result[2], 16),
|
|
b: parseInt(result[3], 16)
|
|
} : null;
|
|
};
|
|
|
|
return ProgressCircle;
|
|
|
|
}(H5P.jQuery));
|