feat: ✨ rewrite banner javascript system to accept custom banner data from PHP template
This commit is contained in:
parent
30019b4c47
commit
1b8bff401b
2 changed files with 150 additions and 55 deletions
|
@ -1,69 +1,160 @@
|
|||
|
||||
const banner_show_time = 600 * 1000.0
|
||||
const banner_animated_style = "opacity 0.8s linear, transform 0.1s linear"
|
||||
const BANNER_TIME = 600 * 1000.0
|
||||
const BANNER_ANIMATION = "opacity 0.8s linear, transform 0.1s linear"
|
||||
|
||||
var banner_current_src = localStorage.getItem('main_banner_img')
|
||||
class BannerHandler {
|
||||
constructor(banner_container, banner_image, banner_link) {
|
||||
this.bannerContainerDOM = banner_container
|
||||
this.bannerDOM = banner_image
|
||||
this.bannerLinkDOM = banner_link
|
||||
|
||||
function getBannerTime() {
|
||||
return (new Date()).getTime() / banner_show_time
|
||||
}
|
||||
function getBannerSrc() {
|
||||
return "/static/banner/" + Math.floor(getBannerTime() + 1000/banner_show_time) % 2 + ".png"
|
||||
}
|
||||
function update_banner_top(banner, banner_container) {
|
||||
const banner_top_max = 0
|
||||
const banner_top_min = -banner.clientHeight + banner_container.clientHeight
|
||||
this.bannerUpdateTimer = null
|
||||
this.currentPhase = 0
|
||||
|
||||
const banner_top = (1-(getBannerTime()%1)) * banner_top_min
|
||||
banner.style.transform = "translateY(" + banner_top + 'px' + ")"
|
||||
}
|
||||
this.currentBannerData = null
|
||||
try {
|
||||
this.currentBannerData = JSON.parse(localStorage.getItem('main_banner_img'))
|
||||
} catch(e) {}
|
||||
|
||||
let banner_update_src = banner_current_src
|
||||
function update_banner(banner, banner_container) {
|
||||
this.currentBannerData ||= {}
|
||||
|
||||
image_select = getBannerSrc()
|
||||
this.bannerDOM.onload=() => { this.onBannerLoaded() }
|
||||
this.bannerDOM.onerror=() => {
|
||||
this.fadeOut();
|
||||
setTimeout(() => this.loadNextBanner(), 1000);
|
||||
}
|
||||
}
|
||||
|
||||
update_banner_top(banner, banner_container)
|
||||
startUpdateTick() {
|
||||
if(this.bannerUpdateTimer !== null) {
|
||||
return
|
||||
}
|
||||
|
||||
if(image_select != banner_update_src) {
|
||||
banner.style.opacity = 0
|
||||
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 = 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(() => {
|
||||
banner.src = image_select
|
||||
}, 1000)
|
||||
this.animateOn()
|
||||
|
||||
banner_update_src = image_select
|
||||
localStorage.setItem('main_banner_img', image_select)
|
||||
this.startUpdateTick()
|
||||
}, 10)
|
||||
}
|
||||
|
||||
document.getElementById("main_banner_img_link").href = "/gallery/test"
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
const banner_container = document.getElementById("main_header")
|
||||
const banner = document.getElementById("main_banner_img")
|
||||
|
||||
|
||||
banner.addEventListener('load', () => {
|
||||
update_banner_top(banner, banner_container)
|
||||
|
||||
const next_banner_src = getBannerSrc()
|
||||
|
||||
if(banner_current_src != next_banner_src) {
|
||||
banner.style.transition = banner_animated_style
|
||||
setTimeout(() => banner.style.opacity = 0.3, 1000)
|
||||
}
|
||||
else {
|
||||
banner.style.opacity = 0.3
|
||||
setTimeout(() => banner.style.transition = banner_animated_style, 0)
|
||||
}
|
||||
|
||||
banner_current_src = next_banner_src
|
||||
})
|
||||
var bannerHandler = new BannerHandler(
|
||||
document.getElementById("main_header"),
|
||||
document.getElementById("main_banner_img"),
|
||||
document.getElementById("main_banner_img_link"))
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
banner.src = getBannerSrc()
|
||||
document.getElementById("main_banner_img_link").href = "/gallery/test"
|
||||
})
|
||||
bannerHandler.start()
|
||||
|
||||
setInterval(() => update_banner(banner, banner_container), 100)
|
||||
addEventListener("resize", () => update_banner(banner, banner_container));
|
||||
// addEventListener("resize", () => update_banner(banner, banner_container));
|
||||
|
|
|
@ -14,14 +14,18 @@
|
|||
{% block extra_head %}{% endblock %}
|
||||
|
||||
{% block opengraph_tags %}{% endblock %}
|
||||
|
||||
<script src="/static/banner.js" defer></script>
|
||||
</head>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.dergBannerOptions = JSON.parse('{{bannerJson|raw}}');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header id="main_header">
|
||||
<img id="main_banner_img"></img>
|
||||
<a id="main_banner_img_link" href="/gallery"> full picture</a>
|
||||
|
||||
<script src="/static/banner.js"></script>
|
||||
|
||||
<h1 id="big_title">{% block big_title %}The dergsite{%endblock%}</h1>
|
||||
{% block second_title %}{% endblock %}
|
||||
<div id="title_separator"></div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue