topbar.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /**
  2. * @license MIT
  3. * topbar 1.0.0, 2021-01-06
  4. * http://buunguyen.github.io/topbar
  5. * Copyright (c) 2021 Buu Nguyen
  6. */
  7. (function (window, document) {
  8. "use strict";
  9. // https://gist.github.com/paulirish/1579671
  10. (function () {
  11. var lastTime = 0;
  12. var vendors = ["ms", "moz", "webkit", "o"];
  13. for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
  14. window.requestAnimationFrame =
  15. window[vendors[x] + "RequestAnimationFrame"];
  16. window.cancelAnimationFrame =
  17. window[vendors[x] + "CancelAnimationFrame"] ||
  18. window[vendors[x] + "CancelRequestAnimationFrame"];
  19. }
  20. if (!window.requestAnimationFrame)
  21. window.requestAnimationFrame = function (callback, element) {
  22. var currTime = new Date().getTime();
  23. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  24. var id = window.setTimeout(function () {
  25. callback(currTime + timeToCall);
  26. }, timeToCall);
  27. lastTime = currTime + timeToCall;
  28. return id;
  29. };
  30. if (!window.cancelAnimationFrame)
  31. window.cancelAnimationFrame = function (id) {
  32. clearTimeout(id);
  33. };
  34. })();
  35. var canvas,
  36. progressTimerId,
  37. fadeTimerId,
  38. currentProgress,
  39. showing,
  40. addEvent = function (elem, type, handler) {
  41. if (elem.addEventListener) elem.addEventListener(type, handler, false);
  42. else if (elem.attachEvent) elem.attachEvent("on" + type, handler);
  43. else elem["on" + type] = handler;
  44. },
  45. options = {
  46. autoRun: true,
  47. barThickness: 3,
  48. barColors: {
  49. 0: "rgba(26, 188, 156, .9)",
  50. ".25": "rgba(52, 152, 219, .9)",
  51. ".50": "rgba(241, 196, 15, .9)",
  52. ".75": "rgba(230, 126, 34, .9)",
  53. "1.0": "rgba(211, 84, 0, .9)",
  54. },
  55. shadowBlur: 10,
  56. shadowColor: "rgba(0, 0, 0, .6)",
  57. className: null,
  58. },
  59. repaint = function () {
  60. canvas.width = window.innerWidth;
  61. canvas.height = options.barThickness * 5; // need space for shadow
  62. var ctx = canvas.getContext("2d");
  63. ctx.shadowBlur = options.shadowBlur;
  64. ctx.shadowColor = options.shadowColor;
  65. var lineGradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
  66. for (var stop in options.barColors)
  67. lineGradient.addColorStop(stop, options.barColors[stop]);
  68. ctx.lineWidth = options.barThickness;
  69. ctx.beginPath();
  70. ctx.moveTo(0, options.barThickness / 2);
  71. ctx.lineTo(
  72. Math.ceil(currentProgress * canvas.width),
  73. options.barThickness / 2
  74. );
  75. ctx.strokeStyle = lineGradient;
  76. ctx.stroke();
  77. },
  78. createCanvas = function () {
  79. canvas = document.createElement("canvas");
  80. var style = canvas.style;
  81. style.position = "fixed";
  82. style.top = style.left = style.right = style.margin = style.padding = 0;
  83. style.zIndex = 100001;
  84. style.display = "none";
  85. if (options.className) canvas.classList.add(options.className);
  86. document.body.appendChild(canvas);
  87. addEvent(window, "resize", repaint);
  88. },
  89. topbar = {
  90. config: function (opts) {
  91. for (var key in opts)
  92. if (options.hasOwnProperty(key)) options[key] = opts[key];
  93. },
  94. show: function () {
  95. if (showing) return;
  96. showing = true;
  97. if (fadeTimerId !== null) window.cancelAnimationFrame(fadeTimerId);
  98. if (!canvas) createCanvas();
  99. canvas.style.opacity = 1;
  100. canvas.style.display = "block";
  101. topbar.progress(0);
  102. if (options.autoRun) {
  103. (function loop() {
  104. progressTimerId = window.requestAnimationFrame(loop);
  105. topbar.progress(
  106. "+" + 0.05 * Math.pow(1 - Math.sqrt(currentProgress), 2)
  107. );
  108. })();
  109. }
  110. },
  111. progress: function (to) {
  112. if (typeof to === "undefined") return currentProgress;
  113. if (typeof to === "string") {
  114. to =
  115. (to.indexOf("+") >= 0 || to.indexOf("-") >= 0
  116. ? currentProgress
  117. : 0) + parseFloat(to);
  118. }
  119. currentProgress = to > 1 ? 1 : to;
  120. repaint();
  121. return currentProgress;
  122. },
  123. hide: function () {
  124. if (!showing) return;
  125. showing = false;
  126. if (progressTimerId != null) {
  127. window.cancelAnimationFrame(progressTimerId);
  128. progressTimerId = null;
  129. }
  130. (function loop() {
  131. if (topbar.progress("+.1") >= 1) {
  132. canvas.style.opacity -= 0.05;
  133. if (canvas.style.opacity <= 0.05) {
  134. canvas.style.display = "none";
  135. fadeTimerId = null;
  136. return;
  137. }
  138. }
  139. fadeTimerId = window.requestAnimationFrame(loop);
  140. })();
  141. },
  142. };
  143. if (typeof module === "object" && typeof module.exports === "object") {
  144. module.exports = topbar;
  145. } else if (typeof define === "function" && define.amd) {
  146. define(function () {
  147. return topbar;
  148. });
  149. } else {
  150. this.topbar = topbar;
  151. }
  152. }.call(this, window, document));