101 lines
2.9 KiB
JavaScript
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());
|
|
},
|
|
};
|
|
};
|