atlas/web/_js/time.js

357 lines
11 KiB
JavaScript
Raw Normal View History

/*
========================================================================
The 2022 /r/place Atlas
An Atlas of Reddit's 2022 /r/place, with information to each
artwork of the canvas provided by the community.
Copyright (c) 2017 Roland Rytz <roland@draemm.li>
Copyright (c) 2022 r/placeAtlas2 contributors
Licensed under the GNU Affero General Public License Version 3
https://place-atlas.stefanocoding.me/license.txt
========================================================================
*/
2022-04-16 14:51:51 +02:00
const variationsConfig = {
default: {
name: "r/place",
code: "",
default: 14,
versions: [
{
timestamp: 1648822500,
url: "./_img/place/1648822500.png",
image: null
},
{
timestamp: 1648847036,
url: "./_img/place/1648847036.png",
image: null
},
{
timestamp: 1648870452,
url: "./_img/place/1648870452.png",
image: null
},
{
timestamp: 1648893666,
url: "./_img/place/1648893666.png",
image: null
},
{
timestamp: 1648917500,
url: "./_img/place/1648917500.png",
image: null
},
{
timestamp: 1648942113,
url: "./_img/place/1648942113.png",
image: null
},
{
timestamp: 1648956234,
url: "./_img/place/1648956234.png",
image: null
},
{
timestamp: 1648968061,
url: "./_img/place/1648968061.png",
image: null
},
{
timestamp: 1648979987,
url: "./_img/place/1648979987.png",
image: null
},
{
timestamp: 1648992274,
url: "./_img/place/1648992274.png",
image: null
},
{
timestamp: 1649012915,
url: "./_img/place/1649012915.png",
image: null
},
{
timestamp: 1649037182,
url: "./_img/place/1649037182.png",
image: null
},
{
timestamp: 1649060793,
url: "./_img/place/1649060793.png",
image: null
},
{
timestamp: 1649084741,
url: "./_img/place/1649084741.png",
image: null
},
{
timestamp: 1649113199,
url: "./_img/place/final.png",
image: null,
}
]
}
}
2022-04-05 20:17:39 +02:00
const timeConfig = [
{
2022-04-06 19:04:07 +02:00
timestamp: 1648822500,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1648822500.png",
2022-04-05 20:17:39 +02:00
image: null
},
{
2022-04-06 19:04:07 +02:00
timestamp: 1648847036,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1648847036.png",
2022-04-05 20:17:39 +02:00
image: null
},
{
2022-04-06 19:04:07 +02:00
timestamp: 1648870452,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1648870452.png",
2022-04-06 19:04:07 +02:00
image: null
},
{
timestamp: 1648893666,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1648893666.png",
2022-04-06 19:04:07 +02:00
image: null
},
{
timestamp: 1648917500,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1648917500.png",
2022-04-06 19:04:07 +02:00
image: null
},
{
timestamp: 1648942113,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1648942113.png",
2022-04-06 19:04:07 +02:00
image: null
},
{
timestamp: 1648956234,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1648956234.png",
2022-04-06 19:04:07 +02:00
image: null
},
{
timestamp: 1648968061,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1648968061.png",
2022-04-06 19:04:07 +02:00
image: null
},
{
timestamp: 1648979987,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1648979987.png",
2022-04-06 19:04:07 +02:00
image: null
},
{
timestamp: 1648992274,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1648992274.png",
2022-04-06 19:04:07 +02:00
image: null
},
{
timestamp: 1649012915,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1649012915.png",
2022-04-06 19:04:07 +02:00
image: null
},
{
timestamp: 1649037182,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1649037182.png",
2022-04-06 19:04:07 +02:00
image: null
},
{
timestamp: 1649060793,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1649060793.png",
2022-04-06 19:04:07 +02:00
image: null
},
{
timestamp: 1649084741,
2022-04-08 06:47:59 +02:00
url: "./_img/place/1649084741.png",
2022-04-05 20:17:39 +02:00
image: null
},
2022-04-08 00:06:24 +02:00
{
timestamp: 1649113199,
2022-04-08 06:47:59 +02:00
url: "./_img/place/final.png",
2022-04-08 01:11:29 +02:00
image: null,
2022-04-10 09:03:08 +02:00
}
2022-04-05 20:17:39 +02:00
];
2022-04-16 14:51:51 +02:00
const codeReference = {}
const variantsEl = document.getElementById("variants")
for (let variation in variationsConfig) {
codeReference[variationsConfig[variation].code] = variation
const optionEl = document.createElement('option')
optionEl.value = variation
optionEl.textContent = variationsConfig[variation].name
variantsEl.appendChild(optionEl)
}
const timelineSlider = document.getElementById("timeControlsSlider");
const tooltip = document.getElementById("timeControlsTooltip")
const image = document.getElementById("image");
let abortController = new AbortController()
let currentUpdateIndex = 0
let updateTimeout = setTimeout(null, 0)
2022-04-05 20:17:39 +02:00
2022-04-14 08:41:13 +02:00
let defaultPeriod = timeConfig.length - 1
let maxPeriod = timeConfig.length - 1
let currentPeriod = defaultPeriod
let currentVariation = "default"
window.currentPeriod = currentPeriod
window.currentVariation = currentVariation
2022-04-08 01:11:29 +02:00
2022-04-05 20:17:39 +02:00
// SETUP
timelineSlider.max = timeConfig.length - 1;
timelineSlider.value = currentPeriod;
2022-04-05 20:17:39 +02:00
timelineSlider.addEventListener("input", (event) => {
updateTooltip(parseInt(event.target.value), currentVariation)
clearTimeout(updateTimeout)
updateTimeout = setTimeout(() => {
updateTime(parseInt(event.target.value), currentVariation)
}, 100)
2022-04-16 14:51:51 +02:00
})
variantsEl.addEventListener("input", (event) => {
updateTime(currentPeriod, event.target.value)
2022-04-10 09:03:08 +02:00
})
2022-04-05 20:17:39 +02:00
2022-04-14 08:41:13 +02:00
// document.querySelector('#period-group .period-start').oninput = (event) => {
// slider.value = parseInt(event.target.value)
// updateTime(parseInt(event.target.value))
// };
2022-04-10 11:11:34 +02:00
2022-04-14 08:41:13 +02:00
// document.querySelector('#period-group .period-end').oninput = (event) => {
// slider.value = parseInt(event.target.value)
// updateTime(parseInt(event.target.value))
// };
2022-04-10 11:11:34 +02:00
const dispatchTimeUpdateEvent = (period = timelineSlider.value, atlas = atlas) => {
2022-04-10 11:11:34 +02:00
const timeUpdateEvent = new CustomEvent('timeupdate', {
detail: {
period: period,
atlas: atlas
}
});
document.dispatchEvent(timeUpdateEvent);
}
async function updateBackground(newPeriod = currentPeriod, newVariation = currentVariation) {
abortController.abort()
abortController = new AbortController()
currentUpdateIndex++
let myUpdateIndex = currentUpdateIndex
currentPeriod = newPeriod
2022-04-15 19:21:39 +02:00
// console.log(newPeriod, newVariation)
2022-04-16 14:51:51 +02:00
const variationConfig = variationsConfig[newVariation]
if (currentVariation !== newVariation) {
currentVariation = newVariation
2022-04-16 14:51:51 +02:00
timelineSlider.max = variationConfig.versions.length - 1;
currentPeriod = variationConfig.default;
newPeriod = currentPeriod
timelineSlider.value = currentPeriod
2022-04-16 14:51:51 +02:00
}
const configObject = variationConfig.versions[currentPeriod];
2022-04-05 20:17:39 +02:00
if (!configObject.image) {
console.log("fetching");
let fetchResult = await fetch(configObject.url, {
signal: abortController.signal
});
if (currentUpdateIndex !== myUpdateIndex) {
hideLoading()
return
}
let imageBlob = await fetchResult.blob();
2022-04-05 20:17:39 +02:00
configObject.image = URL.createObjectURL(imageBlob);
}
image.src = configObject.image;
2022-04-16 14:51:51 +02:00
return [configObject, newPeriod, newVariation]
}
async function updateTime(newPeriod = currentPeriod, newVariation = currentVariation) {
document.body.dataset.canvasLoading = true
2022-04-16 14:51:51 +02:00
let configObject
[configObject, newPeriod, newVariation] = await updateBackground(newPeriod, newVariation)
2022-04-10 11:11:34 +02:00
atlas = []
for ( var atlasIndex in atlasAll ) {
2022-04-16 14:51:51 +02:00
let pathChosen, centerChosen, chosenIndex
let validPeriods2 = Object.keys(atlasAll[atlasIndex].path)
2022-04-14 16:03:17 +02:00
// console.log(chosenIndex)
for (let i in validPeriods2) {
let validPeriods = validPeriods2[i].split(', ')
for (let j in validPeriods) {
2022-04-16 14:51:51 +02:00
let [start, end, variation] = parsePeriod(validPeriods[j])
// console.log(start, end, variation, newPeriod, newVariation)
2022-04-16 14:51:51 +02:00
if (isOnPeriod(start, end, variation, newPeriod, newVariation)) {
// console.log("match", start, end, variation, newPeriod, newVariation, i)
chosenIndex = i
break
2022-04-10 11:11:34 +02:00
}
2022-04-14 16:03:17 +02:00
}
2022-04-16 14:51:51 +02:00
if (chosenIndex !== undefined) break
2022-04-10 11:11:34 +02:00
}
2022-04-14 16:03:17 +02:00
2022-04-16 14:51:51 +02:00
// console.log(testMatches)
// console.log(chosenIndex)
if (chosenIndex === undefined) continue
pathChosen = Object.values(atlasAll[atlasIndex].path)[chosenIndex]
centerChosen = Object.values(atlasAll[atlasIndex].center)[chosenIndex]
2022-04-14 16:03:17 +02:00
if (pathChosen === undefined) continue
2022-04-16 14:51:51 +02:00
// console.log(123)
2022-04-14 16:03:17 +02:00
atlas.push({
...atlasAll[atlasIndex],
path: pathChosen,
center: centerChosen,
})
2022-04-08 01:11:29 +02:00
}
// console.log(atlas)
2022-04-16 14:51:51 +02:00
dispatchTimeUpdateEvent(newPeriod, atlas)
document.body.dataset.canvasLoading = false
}
function updateTooltip(newPeriod, newVariation) {
var configObject = variationsConfig[newVariation].versions[newPeriod]
2022-04-10 09:03:08 +02:00
if (typeof configObject.timestamp === "number") tooltip.querySelector('p').textContent = new Date(configObject.timestamp*1000).toUTCString()
else tooltip.querySelector('p').textContent = configObject.timestamp
tooltip.style.left = Math.max(((timelineSlider.offsetWidth)*(timelineSlider.value >= 1 ? timelineSlider.value - 1:0)/(timelineSlider.max-1)) - tooltip.offsetWidth/2, 0) + "px"
2022-04-10 09:03:08 +02:00
}
// tooltip.parentElement.addEventListener('mouseenter', () => updateTooltip(parseInt(timelineSlider.value), currentVariation))
2022-04-10 11:11:34 +02:00
window.addEventListener('resize', () => updateTooltip(parseInt(timelineSlider.value), currentVariation))
2022-04-10 09:03:08 +02:00
2022-04-16 14:51:51 +02:00
function isOnPeriod(start, end, variation, currentPeriod, currentVariation) {
return currentPeriod >= start && currentPeriod <= end && variation === currentVariation
2022-04-14 16:03:17 +02:00
}
function parsePeriod(periodString) {
// console.log(periodString)
2022-04-16 14:51:51 +02:00
let variation = "default"
2022-04-14 16:03:17 +02:00
periodString = periodString + ""
2022-04-16 14:51:51 +02:00
if (periodString.split(':').length > 1) {
let split = periodString.split(':')
variation = codeReference[split[0]]
periodString = split[1]
2022-04-16 14:51:51 +02:00
}
2022-04-14 16:03:17 +02:00
if (periodString.search('-') + 1) {
var [start, end] = periodString.split('-').map(i => parseInt(i))
2022-04-16 14:51:51 +02:00
return [start, end, variation]
2022-04-14 16:03:17 +02:00
} else {
let periodNew = parseInt(periodString)
2022-04-16 14:51:51 +02:00
return [periodNew, periodNew, variation]
2022-04-14 16:03:17 +02:00
}
}