flash.moe/assets/makai.js/elems/head.js

101 lines
2.9 KiB
JavaScript

#include elem.js
#include xhr.js
const MakaiSiteHeaderImages = function() {
const url = '/header-bgs.json';
let headers;
const all = async () => {
if(!Array.isArray(headers))
headers = (await $x.get('/header-bgs.json')).json();
return headers;
};
return {
all: all,
random: async () => {
const images = await all();
if(images.length < 1)
return '/flonnerator.png';
return images[Math.floor(Math.random() * images.length)];
},
};
};
const MakaiSiteHeader = function(element) {
if(!(element instanceof Element))
throw 'element must be an instance of Element';
const images = new MakaiSiteHeaderImages;
const bgElem = element.querySelector('.js-header-background');
const getBgImgElem = () => bgElem.querySelector('img');
const setBackgroundImage = (url, duration) => {
return new Promise((resolve, reject) => {
if(typeof duration !== 'number')
duration = 500;
while(bgElem.childElementCount > 1)
bgElem.removeChild(bgElem.lastChild);
const prevImage = getBgImgElem();
if(prevImage.src === url) {
resolve();
return;
}
let startTimeStamp;
const updateTransition = timeStamp => {
if(startTimeStamp === undefined)
startTimeStamp = timeStamp;
const elapsed = timeStamp - startTimeStamp;
const t = Math.min(1, Math.max(0, elapsed / duration));
prevImage.style.opacity = 1 - t;
if(t < 1)
requestAnimationFrame(updateTransition);
else {
$r(prevImage);
resolve();
}
};
prevImage.style.zIndex = '2';
const nextImage = $e({
tag: 'img',
attrs: {
alt: url,
src: url,
onerror: () => {
prevImage.style.opacity = null;
prevImage.style.zIndex = null;
bgElem.removeChild(nextImage);
reject();
},
onload: () => {
requestAnimationFrame(updateTransition);
},
},
style: { zIndex: '1' },
});
bgElem.appendChild(nextImage);
});
};
return {
get images() { return images; },
get backgroundElement() { return bgElem; },
get backgroundImage() { return getBgImgElem().src; },
setBackgroundImage: setBackgroundImage,
randomBackgroundImage: async () => {
await setBackgroundImage(await images.random());
},
};
};