|
|
@@ -0,0 +1,157 @@
|
|
|
+/**
|
|
|
+ * @license MIT
|
|
|
+ * topbar 1.0.0, 2021-01-06
|
|
|
+ * 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,
|
|
|
+ progressTimerId,
|
|
|
+ fadeTimerId,
|
|
|
+ currentProgress,
|
|
|
+ showing,
|
|
|
+ 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];
|
|
|
+ },
|
|
|
+ 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 () {
|
|
|
+ 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));
|