You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
5.3 KiB
167 lines
5.3 KiB
/** |
|
* @license MIT |
|
* topbar 1.0.0, 2021-01-06 |
|
* Modifications: |
|
* - add delayedShow(time) (2022-09-21) |
|
* http://buunguyen.github.io/topbar |
|
* Copyright (c) 2021 Buu Nguyen |
|
*/ |
|
(function (window, document) { |
|
"use strict"; |
|
|
|
// https://gist.github.com/paulirish/1579671 |
|
(function () { |
|
var lastTime = 0; |
|
var vendors = ["ms", "moz", "webkit", "o"]; |
|
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { |
|
window.requestAnimationFrame = |
|
window[vendors[x] + "RequestAnimationFrame"]; |
|
window.cancelAnimationFrame = |
|
window[vendors[x] + "CancelAnimationFrame"] || |
|
window[vendors[x] + "CancelRequestAnimationFrame"]; |
|
} |
|
if (!window.requestAnimationFrame) |
|
window.requestAnimationFrame = function (callback, element) { |
|
var currTime = new Date().getTime(); |
|
var timeToCall = Math.max(0, 16 - (currTime - lastTime)); |
|
var id = window.setTimeout(function () { |
|
callback(currTime + timeToCall); |
|
}, timeToCall); |
|
lastTime = currTime + timeToCall; |
|
return id; |
|
}; |
|
if (!window.cancelAnimationFrame) |
|
window.cancelAnimationFrame = function (id) { |
|
clearTimeout(id); |
|
}; |
|
})(); |
|
|
|
var canvas, |
|
currentProgress, |
|
showing, |
|
progressTimerId = null, |
|
fadeTimerId = null, |
|
delayTimerId = null, |
|
addEvent = function (elem, type, handler) { |
|
if (elem.addEventListener) elem.addEventListener(type, handler, false); |
|
else if (elem.attachEvent) elem.attachEvent("on" + type, handler); |
|
else elem["on" + type] = handler; |
|
}, |
|
options = { |
|
autoRun: true, |
|
barThickness: 3, |
|
barColors: { |
|
0: "rgba(26, 188, 156, .9)", |
|
".25": "rgba(52, 152, 219, .9)", |
|
".50": "rgba(241, 196, 15, .9)", |
|
".75": "rgba(230, 126, 34, .9)", |
|
"1.0": "rgba(211, 84, 0, .9)", |
|
}, |
|
shadowBlur: 10, |
|
shadowColor: "rgba(0, 0, 0, .6)", |
|
className: null, |
|
}, |
|
repaint = function () { |
|
canvas.width = window.innerWidth; |
|
canvas.height = options.barThickness * 5; // need space for shadow |
|
|
|
var ctx = canvas.getContext("2d"); |
|
ctx.shadowBlur = options.shadowBlur; |
|
ctx.shadowColor = options.shadowColor; |
|
|
|
var lineGradient = ctx.createLinearGradient(0, 0, canvas.width, 0); |
|
for (var stop in options.barColors) |
|
lineGradient.addColorStop(stop, options.barColors[stop]); |
|
ctx.lineWidth = options.barThickness; |
|
ctx.beginPath(); |
|
ctx.moveTo(0, options.barThickness / 2); |
|
ctx.lineTo( |
|
Math.ceil(currentProgress * canvas.width), |
|
options.barThickness / 2 |
|
); |
|
ctx.strokeStyle = lineGradient; |
|
ctx.stroke(); |
|
}, |
|
createCanvas = function () { |
|
canvas = document.createElement("canvas"); |
|
var style = canvas.style; |
|
style.position = "fixed"; |
|
style.top = style.left = style.right = style.margin = style.padding = 0; |
|
style.zIndex = 100001; |
|
style.display = "none"; |
|
if (options.className) canvas.classList.add(options.className); |
|
document.body.appendChild(canvas); |
|
addEvent(window, "resize", repaint); |
|
}, |
|
topbar = { |
|
config: function (opts) { |
|
for (var key in opts) |
|
if (options.hasOwnProperty(key)) options[key] = opts[key]; |
|
}, |
|
delayedShow: function(time) { |
|
if (showing) return; |
|
if (delayTimerId) return; |
|
delayTimerId = setTimeout(() => topbar.show(), time); |
|
}, |
|
show: function () { |
|
if (showing) return; |
|
showing = true; |
|
if (fadeTimerId !== null) window.cancelAnimationFrame(fadeTimerId); |
|
if (!canvas) createCanvas(); |
|
canvas.style.opacity = 1; |
|
canvas.style.display = "block"; |
|
topbar.progress(0); |
|
if (options.autoRun) { |
|
(function loop() { |
|
progressTimerId = window.requestAnimationFrame(loop); |
|
topbar.progress( |
|
"+" + 0.05 * Math.pow(1 - Math.sqrt(currentProgress), 2) |
|
); |
|
})(); |
|
} |
|
}, |
|
progress: function (to) { |
|
if (typeof to === "undefined") return currentProgress; |
|
if (typeof to === "string") { |
|
to = |
|
(to.indexOf("+") >= 0 || to.indexOf("-") >= 0 |
|
? currentProgress |
|
: 0) + parseFloat(to); |
|
} |
|
currentProgress = to > 1 ? 1 : to; |
|
repaint(); |
|
return currentProgress; |
|
}, |
|
hide: function () { |
|
clearTimeout(delayTimerId); |
|
delayTimerId = null; |
|
if (!showing) return; |
|
showing = false; |
|
if (progressTimerId != null) { |
|
window.cancelAnimationFrame(progressTimerId); |
|
progressTimerId = null; |
|
} |
|
(function loop() { |
|
if (topbar.progress("+.1") >= 1) { |
|
canvas.style.opacity -= 0.05; |
|
if (canvas.style.opacity <= 0.05) { |
|
canvas.style.display = "none"; |
|
fadeTimerId = null; |
|
return; |
|
} |
|
} |
|
fadeTimerId = window.requestAnimationFrame(loop); |
|
})(); |
|
}, |
|
}; |
|
|
|
if (typeof module === "object" && typeof module.exports === "object") { |
|
module.exports = topbar; |
|
} else if (typeof define === "function" && define.amd) { |
|
define(function () { |
|
return topbar; |
|
}); |
|
} else { |
|
this.topbar = topbar; |
|
} |
|
}.call(this, window, document));
|
|
|