portfolio/assets/vendor/topbar.js

166 lines
5.2 KiB
JavaScript

/**
* @license MIT
* topbar 2.0.0, 2023-02-04
* https://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]
},
show: function (delay) {
if (showing) return
if (delay) {
if (delayTimerId) return
delayTimerId = setTimeout(() => topbar.show(), delay)
} else {
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)