dlibrary/dlibrary/static/viewer.js

202 lines
5.5 KiB
JavaScript

const PRELOAD_BACKWARD = 2;
const PRELOAD_FORWARD = 8;
document.addEventListener('DOMContentLoaded', () => {
const currentImage = document.getElementById('current-image');
const preloadImages = document.getElementById('preload-images');
let currentPage = parseInt(localStorage.getItem(`${WORK_ID}-currentPage`)) || 0;
let duration = parseInt(localStorage.getItem(`${WORK_ID}-duration`)) || 10;
let rtl = (localStorage.getItem(`${WORK_ID}-rtl`) !== "false");
let paused = true;
let elapsed = 0;
let timerLastRun = null;
let timerAnimationRequestID = null;
function requestTimer() {
timerAnimationRequestID = window.requestAnimationFrame(runTimer);
}
function runTimer(now) {
if (paused) {
return;
}
if (timerLastRun === null) {
elapsed = 0;
} else {
elapsed += now - timerLastRun;
}
timerLastRun = now;
if (elapsed >= duration*1000) {
changePage(currentPage + 1);
elapsed = 0;
}
updateBar();
requestTimer();
}
const progressBar = document.getElementById('progress');
function updateBar() {
progressBar.style.width = `${100*elapsed/(1000*duration)}%`;
}
function stopTimer() {
if (timerAnimationRequestID) {
window.cancelAnimationFrame(timerAnimationRequestID);
timerAnimationRequestID = null;
}
timerLastRun = null;
elapsed = 0;
updateBar();
}
function imageSrc(s) {
const img = new Image();
img.src = s;
return img;
}
function preload() {
if (!currentImage.getElementsByTagName('img')[0].complete) {
setTimeout(preload, 50);
return;
}
preloadImages.replaceChildren(...(
IMAGES.slice(
Math.max(currentPage - PRELOAD_BACKWARD, 0),
currentPage + PRELOAD_FORWARD + 1,
).map(imageSrc)
));
}
function changePage(pageNum) {
elapsed = 0;
updateBar();
const previous = IMAGES[currentPage];
const current = IMAGES[pageNum];
if (current == null) {
return;
}
currentPage = pageNum;
localStorage.setItem(`${WORK_ID}-currentPage`, currentPage);
currentImage.replaceChildren(imageSrc(current));
document.getElementById('current-page').innerText = (pageNum + 1).toLocaleString();
setTimeout(preload, 1);
}
const durationDisplay = document.getElementById('duration');
function changeDuration(secs, pause) {
duration = secs;
localStorage.setItem(`${WORK_ID}-duration`, duration);
paused = pause;
durationDisplay.textContent = duration.toLocaleString() + 's';
if (paused) {
durationDisplay.style.textDecoration = "line-through 2px";
stopTimer();
} else {
durationDisplay.style.textDecoration = "";
requestTimer();
}
}
function left() {
if (currentPage === 0) {
rtl = true;
localStorage.setItem(`${WORK_ID}-rtl`, rtl);
}
changePage(currentPage + (rtl ? 1 : -1));
}
function right() {
if (currentPage === 0) {
rtl = false;
localStorage.setItem(`${WORK_ID}-rtl`, rtl);
}
changePage(currentPage + (rtl ? -1 : 1));
}
function restart() {
changePage(0);
}
function exitToWork() {
changeDuration(duration, true);
if (currentPage === IMAGES.length - 1) {
localStorage.removeItem(`${WORK_ID}-currentPage`);
}
window.location.href = `../${INDEX}`;
}
function hideTapZones() {
document.getElementById('controls').style.opacity = 0;
}
changePage(currentPage);
changeDuration(duration, paused);
document.onkeydown = event => {
hideTapZones();
switch (event.key) {
case "ArrowLeft":
event.preventDefault();
left();
break;
case "ArrowRight":
event.preventDefault();
right();
break;
case " ":
event.preventDefault();
changeDuration(duration, !paused);
break;
case "ArrowUp":
event.preventDefault();
if (2 <= duration && duration <= 10) {
changeDuration(duration - 1, false);
} else if (10 < duration && duration <= 20) {
changeDuration(duration - 2.5, false);
} else if (20 < duration) {
changeDuration(duration - 5, false);
}
break;
case "ArrowDown":
event.preventDefault();
if (duration < 10) {
changeDuration(duration + 1, false);
} else if (10 <= duration && duration < 20) {
changeDuration(duration + 2.5, false);
} else if (20 <= duration) {
changeDuration(duration + 5, false);
}
break;
case "Enter":
event.preventDefault();
restart();
break;
case "Escape":
event.preventDefault();
exitToWork();
break;
}
};
document.onclick = hideTapZones;
document.getElementById("tap-left").onclick = left;
document.getElementById("tap-right").onclick = right;
document.getElementById("tap-restart").onclick = restart;
document.getElementById("tap-back").onclick = exitToWork;
});