www.franconian.net/static/bauchbinde/assets/script.js

307 lines
10 KiB
JavaScript
Raw Normal View History

2020-12-23 19:37:15 +01:00
(() => {
2020-12-25 16:04:10 +01:00
const scheduleUrl = 'https://schedule2.broken.equipment/everything.schedule.json';
2020-12-25 15:44:57 +01:00
2020-12-27 13:32:40 +01:00
let data = null;
2020-12-23 19:37:15 +01:00
let textEl;
2020-12-27 13:32:40 +01:00
let headline = null;
let speaker = null;
2020-12-23 19:37:15 +01:00
let isIntro = false;
2020-12-27 21:17:37 +01:00
let holdDuration = 10;
2020-12-25 15:44:57 +01:00
let room = null;
let time = null;
2020-12-27 21:17:37 +01:00
let startDelay = 1;
let gracePeriod = 360;
2020-12-27 20:36:52 +01:00
let interval = null;
2020-12-25 15:44:57 +01:00
2020-12-27 13:32:40 +01:00
async function getCurrentTalkByRoomName(roomName, offset) {
if (!offset) {
offset = 0;
}
let now = Date.now() + offset;
2020-12-25 15:44:57 +01:00
if (time) {
2020-12-27 13:32:40 +01:00
now = Date.parse(time) + offset;
}
2020-12-27 21:17:37 +01:00
if (!offset || !data) {
2020-12-27 13:32:40 +01:00
const response = await fetch(scheduleUrl);
data = await response.json();
2020-12-25 15:44:57 +01:00
}
const days = data.schedule.conference.days;
const today = days.find(day => {
const start = Date.parse(day.day_start);
const end = Date.parse(day.day_end);
return now >= start && now <= end;
});
if (!today) return false;
2020-12-23 19:37:15 +01:00
2020-12-25 15:44:57 +01:00
const room = today.rooms[roomName];
if (!room) return false;
const talk = room.find(talk => {
const start = Date.parse(talk.date);
const [hours, minutes] = talk.duration.split(':');
const duration = (hours * 60 + minutes) * 60 * 1000;
const end = start + duration;
return now >= start && now <= end;
})
if (!talk) return false;
return talk;
}
async function init() {
2020-12-25 23:17:55 +01:00
const root = document.querySelector('html');
2020-12-23 19:37:15 +01:00
textEl = document.querySelector('.text');
textEl.innerHTML = '';
if (window.location.search) {
2020-12-25 15:44:57 +01:00
const pairs = window.location.search.slice(1).split('&').map(x => x.split('='));
for (let pair of pairs) {
const key = pair.shift();
const value = decodeURIComponent(pair.join('='));
2020-12-23 19:37:15 +01:00
if (key === 'headline') {
2020-12-25 20:47:40 +01:00
headline = value;
2020-12-23 19:37:15 +01:00
}
if (key === 'speaker') {
2020-12-25 15:44:57 +01:00
speaker = value;
2020-12-23 19:37:15 +01:00
}
if (key === 'intro') {
2020-12-24 00:39:14 +01:00
isIntro = !!parseInt(value, 10)
2020-12-23 19:37:15 +01:00
}
if (key === 'hold') {
2020-12-24 00:39:14 +01:00
holdDuration = parseInt(value, 10);
2020-12-23 19:37:15 +01:00
}
2020-12-24 17:53:14 +01:00
if (key === 'theme') {
2020-12-25 15:44:57 +01:00
root.className = '';
root.classList.add(`theme-${value}`)
}
if (key === 'room') {
room = value;
}
if (key === 'time') {
time = value;
}
2020-12-25 23:17:55 +01:00
if (key === 'startdelay') {
startDelay = parseInt(value, 10);
}
if (key === 'left') {
root.style.setProperty('--left', value);
}
if (key === 'bottom') {
root.style.setProperty('--bottom', value);
}
2020-12-27 23:50:47 +01:00
if (key === 'top') {
root.style.setProperty('--top', value);
}
2020-12-25 23:17:55 +01:00
if (key === 'width') {
root.style.setProperty('--width', value);
}
2020-12-27 13:32:40 +01:00
if (key === 'gracePeriod') {
2020-12-27 20:36:52 +01:00
gracePeriod = parseInt(value, 10);
}
if (key === 'interval') {
interval = parseInt(value, 10);
2020-12-27 13:32:40 +01:00
}
2020-12-25 15:44:57 +01:00
}
}
if (room) {
2020-12-27 21:17:37 +01:00
let offset = gracePeriod * 1000;
2020-12-27 13:32:40 +01:00
let talk = await getCurrentTalkByRoomName(room);
2020-12-25 15:44:57 +01:00
if (!talk) {
2020-12-27 13:32:40 +01:00
talk = await getCurrentTalkByRoomName(room, -offset);
}
if (!talk) {
talk = await getCurrentTalkByRoomName(room, offset);
}
if (!talk) {
headline = null;
speaker = null;
2020-12-25 15:44:57 +01:00
} else {
headline = talk.title;
if (talk.persons) {
speaker = talk.persons.map(person => person.public_name).join(' / ');
2020-12-24 17:53:14 +01:00
}
2020-12-25 15:44:57 +01:00
}
2020-12-23 19:37:15 +01:00
}
2020-12-25 23:17:55 +01:00
2020-12-27 13:32:40 +01:00
if (!headline) {
return false;
}
if (speaker && headline) {
2020-12-25 20:47:40 +01:00
headline += ',';
}
2020-12-23 19:37:15 +01:00
const headlineEl = document.createElement('span');
headlineEl.classList.add('headline');
const speakerEl = document.createElement('span');
speakerEl.classList.add('speaker');
2020-12-27 13:32:40 +01:00
if (headline) {
Array.from(headline).forEach(letter => {
const letterEl = document.createElement('span');
letterEl.classList.add('letter');
letterEl.innerText = letter;
headlineEl.appendChild(letterEl);
})
}
if (speaker) {
Array.from(speaker).forEach(letter => {
const letterEl = document.createElement('span');
letterEl.classList.add('letter');
letterEl.innerText = letter;
speakerEl.appendChild(letterEl);
})
}
2020-12-23 19:37:15 +01:00
textEl.appendChild(headlineEl);
textEl.appendChild(document.createTextNode(' '));
textEl.appendChild(speakerEl);
const mainTilesEl = document.querySelector('.background .main-tiles');
mainTilesEl.innerHTML = '';
for (let i = 0; i < 16; i++) {
const tile = document.createElement('div');
2020-12-24 17:53:14 +01:00
tile.classList.add('tile', 'large');
2020-12-23 19:37:15 +01:00
mainTilesEl.appendChild(tile);
}
const secondaryTilesEl = document.querySelector('.background .secondary-tiles');
secondaryTilesEl.innerHTML = '';
for (let i = 0; i < 17; i++) {
const tile = document.createElement('div');
tile.classList.add('tile');
if (i === 0 || Math.random() > 0.5) {
2020-12-24 17:53:14 +01:00
tile.classList.add('medium');
2020-12-23 19:37:15 +01:00
} else {
2020-12-24 17:53:14 +01:00
tile.classList.add('small');
2020-12-23 19:37:15 +01:00
}
secondaryTilesEl.appendChild(tile);
}
2020-12-27 13:32:40 +01:00
return true;
2020-12-23 19:37:15 +01:00
}
async function animate() {
if (isIntro) {
await Promise.all([
slideIn(),
fadeInText(),
]);
} else {
await Promise.all([
fadeIn(),
fadeInText(),
]);
}
2020-12-27 21:17:37 +01:00
await new Promise(r => setTimeout(r, holdDuration * 1000));
2020-12-23 19:37:15 +01:00
await Promise.all([
fadeOut(),
fadeOutText(),
])
}
async function slideIn() {
const tiles = document.querySelectorAll('.tile');
for (const tile of tiles) {
tile.style.animationName = `slide-in-${Math.floor(Math.random() * 10)}`;
tile.style.animationDelay = `${Math.random() * 0.4}s`;
tile.style.animationDuration = `${0.8 + Math.random() * 0.4}s`;
2020-12-25 15:44:57 +01:00
tile.style.animationIterationCount = '1';
2020-12-23 19:37:15 +01:00
tile.style.animationTimingFunction = 'ease-in';
}
await new Promise(r => setTimeout(r, 600));
for (const tile of tiles) {
tile.classList.add('visible');
}
await new Promise(r => setTimeout(r, 1000));
}
async function fadeIn() {
const tiles = document.querySelectorAll('.tile');
for (const tile of tiles) {
tile.style.animationName = `fade-in`;
tile.style.animationDelay = `${Math.random() * 0.4}s`;
tile.style.animationDuration = `${0.8 + Math.random() * 0.4}s`;
2020-12-25 15:44:57 +01:00
tile.style.animationIterationCount = '1';
2020-12-23 19:37:15 +01:00
tile.style.animationTimingFunction = 'ease-in';
}
await new Promise(r => setTimeout(r, 600));
for (const tile of tiles) {
tile.classList.add('visible');
}
await new Promise(r => setTimeout(r, 1000));
}
async function fadeOut() {
const tiles = document.querySelectorAll('.tile');
for (const tile of tiles) {
tile.style.animationName = `fade-out`;
tile.style.animationDelay = `${Math.random() * 0.4}s`;
tile.style.animationDuration = `${0.8 + Math.random() * 0.4}s`;
2020-12-25 15:44:57 +01:00
tile.style.animationIterationCount = '1';
2020-12-23 19:37:15 +01:00
tile.style.animationTimingFunction = 'ease-in';
}
await new Promise(r => setTimeout(r, 600));
for (const tile of tiles) {
tile.classList.remove('visible');
}
await new Promise(r => setTimeout(r, 1000));
}
async function fadeInText() {
const letters = document.querySelectorAll('.letter');
for (const letter of letters) {
letter.style.animationName = `fade-in`;
letter.style.animationDelay = `${Math.random() * 0.4}s`;
letter.style.animationDuration = `${0.8 + Math.random() * 0.4}s`;
letter.style.animationIterationCount = 1;
letter.style.animationTimingFunction = 'ease-in';
}
await new Promise(r => setTimeout(r, 600));
for (const tile of letters) {
tile.classList.add('visible');
}
await new Promise(r => setTimeout(r, 1000));
}
async function fadeOutText() {
const letters = document.querySelectorAll('.letter');
for (const letter of letters) {
letter.style.animationName = `fade-out`;
letter.style.animationDelay = `${Math.random() * 0.4}s`;
letter.style.animationDuration = `${0.8 + Math.random() * 0.4}s`;
2020-12-25 15:44:57 +01:00
letter.style.animationIterationCount = '1';
2020-12-23 19:37:15 +01:00
letter.style.animationTimingFunction = 'ease-in';
}
await new Promise(r => setTimeout(r, 600));
for (const tile of letters) {
tile.classList.remove('visible');
}
await new Promise(r => setTimeout(r, 1000));
}
2020-12-27 20:36:52 +01:00
async function cycle() {
2020-12-27 13:32:40 +01:00
if (await init()) {
2020-12-27 21:17:37 +01:00
await new Promise(r => setTimeout(r, startDelay * 1000));
2020-12-27 13:32:40 +01:00
await animate();
}
2020-12-27 20:36:52 +01:00
if (interval) {
setTimeout(cycle, interval * 1000);
}
}
window.addEventListener('load', () => {
cycle();
2020-12-23 19:37:15 +01:00
});
})();