const BANNER_TIME = 600 * 1000.0 const BANNER_ANIMATION = "opacity 0.8s linear, transform 0.1s linear" class BannerHandler { constructor(banner_container, banner_image, banner_link) { this.bannerContainerDOM = banner_container this.bannerDOM = banner_image this.bannerLinkDOM = banner_link this.bannerUpdateTimer = null this.currentPhase = 0 this.currentBannerData = null try { this.currentBannerData = JSON.parse(localStorage.getItem('main_banner_img')) } catch(e) {} this.currentBannerData ||= {} this.bannerDOM.onload=() => { this.onBannerLoaded() } this.bannerDOM.onerror=() => { this.fadeOut(); setTimeout(() => this.loadNextBanner(), 1000); } } startUpdateTick() { if(this.bannerUpdateTimer !== null) { return } console.log("Starting tick") this.bannerUpdateTimer = setInterval(() => { this.updateTick() }, 100); } stopUpdateTick() { if(this.bannerUpdateTimer === null) { return } console.log("Stopping tick!") clearInterval(this.bannerUpdateTimer); this.bannerUpdateTimer = null } getPhase() { return (new Date()).getTime() / BANNER_TIME; } getTargetBanner() { if(window.dergBannerOptions == null) { return {} } var banner_index = Math.floor(this.getPhase()) % window.dergBannerOptions.length var banner_choice = window.dergBannerOptions[banner_index] return banner_choice } updateTranslation() { const bannerTranslateMax = -this.bannerDOM.clientHeight + this.bannerContainerDOM.clientHeight const bannerPercentageFrom = this.currentBannerData.from || 0; const bannerPercentageTo = this.currentBannerData.to || 1; const bannerPercentage = (bannerPercentageFrom + (bannerPercentageTo - bannerPercentageFrom) * this.currentPhase) const banner_top = (1-bannerPercentage) * bannerTranslateMax this.bannerDOM.style.transform = "translateY(" + banner_top + 'px' + ")" } fadeOut() { this.bannerDOM.style.opacity = 0; } fadeIn() { this.bannerDOM.style.opacity = this.currentBannerData.opacity || 0.3; } loadNextBanner() { this.currentBannerData = this.getTargetBanner() this.currentBannerData.bannerTime = new Date() this.loadBanner() } loadBanner() { console.log("Target banner:"); console.log(this.currentBannerData); localStorage.setItem("main_banner_img", JSON.stringify(this.currentBannerData)) this.currentPhase = 0 if((this.currentBannerData === null) || (this.currentBannerData.src === undefined)) { this.onBannerLoaded() return } this.bannerDOM.src = this.currentBannerData.src this.bannerLinkDOM.href = this.currentBannerData.href || this.currentBannerData.src } onBannerLoaded() { console.log("Loaded?"); this.currentPhase = this.getPhase() % 1 this.updateTranslation() this.fadeIn() setTimeout(() => { this.animateOn() this.startUpdateTick() }, 10) } updateTick() { console.log("tick") const nextPhase = this.getPhase() % 1; if((nextPhase > this.currentPhase) && (this.currentBannerData.src == this.getTargetBanner().src)) { this.currentPhase = nextPhase; this.updateTranslation(); } else { this.fadeOut() setTimeout(() => { this.loadNextBanner() }, 1000); this.stopUpdateTick() } } animateOn() { this.bannerDOM.style.transition = BANNER_ANIMATION } start() { this.fadeIn() this.loadBanner() } } var bannerHandler = new BannerHandler( document.getElementById("main_header"), document.getElementById("main_banner_img"), document.getElementById("main_banner_img_link")) bannerHandler.start() // addEventListener("resize", () => update_banner(banner, banner_container));