cinemafoundation.in/icf.js

229 lines
6.8 KiB
JavaScript

let hashes = []
let movie, position, frames, timelineTiles, lastTimelineWidth
let timelineElement = document.getElementById('timeline')
let timelineElements = []
let timelineWidth = 1500
let timelinesLeft
let timelineLink = document.getElementById('link')
let timelineLinkEntered = false
let fps = 25
let fpsAnimation = 60
let paused = true
let speed = 0
let acceleration = 0
let maxSpeed = 2
let maxAcceleration = 1 / fpsAnimation
function api(action, data, callback) {
fetch('https://indiancine.ma/api/', {
body: JSON.stringify({action: action, data: data}),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json, text/plain, */*',
},
method: 'post'
}).then(function(result) {
return result.json()
}).then(callback)
}
function formatDuration(seconds) {
return [
Math.floor(seconds / 3600),
Math.floor(seconds % 3600 / 60),
Math.floor(seconds % 60)
].map(function(value, index) {
return (index > 0 && value < 10 ? '0' : '') + value
}).join(':')
}
function hashchange() {
let hash = document.location.hash.substr(1)
if (!hashes.includes(hash)) {
document.location.hash = hashes[0]
return
}
slice(document.querySelectorAll('#menu > a')).forEach(function(element) {
element.classList[
element.getAttribute('href') == '#' + hash ? 'add' : 'remove'
]('selected')
})
slice(document.querySelectorAll('.section')).forEach(function(element) {
element.classList[
element.getAttribute('id') == hash ? 'add' : 'remove'
]('selected')
})
}
function last(array) {
return array[array.length - 1]
}
function loadText(callback) {
let menu = document.getElementById('menu')
api('getDocument', {id: 'DWA'}, function(result) {
result.data.text.split('<h1>').slice(1).forEach(function(text, index) {
let split = text.split('</h1>')
let id = split[0].toLowerCase()
let element
if (index > 0) {
element = document.createElement('span')
element.innerHTML = ' &middot; '
menu.appendChild(element)
}
element = document.createElement('a')
element.href = '#' + id
element.innerHTML = split[0]
menu.appendChild(element)
element = document.createElement('div')
element.className = 'section'
element.id = id
element.innerHTML = split[1]
.replace(/<a /g, '<a target="_blank" ')
.replace(/<br>/g, '')
document.body.appendChild(element)
hashes.push(id)
})
callback()
})
}
function loadTimeline(callback) {
api('find', {
keys: ['director', 'duration', 'id', 'title', 'year'],
query: {
conditions: [{
key: 'list', operator: '==', value: 'rlx:cinemafoundation.in',
}],
operator: '&'
},
sort: [{key: 'year', operator: '+'}]
}, function(result) {
let movies = result.data.items
let time = new Date()
time -= time.getTimezoneOffset() * 60000
let mspd = 86400000
movie = movies[Math.floor(time / mspd) % movies.length]
position = Math.floor(time % mspd / mspd * movie.duration * fps) / fps
frames = Math.floor(movie.duration * fps)
timelineTiles = Math.ceil(frames / timelineWidth)
lastTimelineWidth = frames % timelineWidth
renderTimeline()
timelineLink.innerHTML = movie.title + ' (' + movie.year + ') '
+ movie.director.join(', ')
callback()
})
}
function mod(a, b) {
return (a % b + b) % b
}
function play() {
if (speed <= 0 && acceleration < 0) {
paused = true
if (!timelineLinkEntered) {
timelineLink.style.display = 'none'
}
return
}
position += speed / fpsAnimation
renderTimeline()
timelineLink.href = 'https://indiancine.ma/' + movie.id + '/'
+ formatDuration(position)
if (speed < maxSpeed || acceleration <= 0) {
speed += acceleration
}
setTimeout(play, 1000 / fpsAnimation)
}
function renderTimeline() {
let frame = Math.floor(position * fps)
let windowWidth = window.innerWidth
let timelines = [{
index: Math.floor(frame / timelineWidth),
left: (windowWidth / 2) - frame % timelineWidth
}]
while (timelines[0].left > 0) {
timelines.unshift({
index: mod(timelines[0].index - 1, timelineTiles),
left: timelines[0].left - (
timelines[0].index == 0 ? lastTimelineWidth : timelineWidth
)
})
}
while (last(timelines).left < windowWidth) {
timelines.push({
index: mod(last(timelines).index + 1, timelineTiles),
left: last(timelines).left + timelineWidth
})
}
let element = document.getElementById(
'timeline' + mod(timelines[0].index - 1, timelineTiles)
)
if (element) {
timelineElement.removeChild(element)
}
timelines.forEach(function(timeline) {
let element = document.getElementById('timeline' + timeline.index)
if (element) {
element.style.left = timeline.left + 'px'
} else {
element = document.createElement('img')
element.id = 'timeline' + timeline.index
element.src = 'https://media.indiancine.ma/' + movie.id
+ '/timelinekeyframes64p' + timeline.index + '.jpg'
element.style.left = timeline.left + 'px'
timelineElement.appendChild(element)
}
})
}
function slice(nodelist) {
return Array.prototype.slice.call(nodelist)
}
function start() {
acceleration = maxAcceleration
if (paused) {
paused = false
play()
setTimeout(function() {
if (acceleration > 0) {
timelineLink.style.display = 'block'
}
}, 250)
}
}
function stop() {
acceleration = -maxAcceleration
}
loadText(function() {
window.addEventListener('hashchange', hashchange)
hashchange()
loadTimeline(function() {
window.addEventListener('resize', renderTimeline)
timeline.addEventListener('dragstart', function() {
return false
})
timeline.addEventListener('mouseenter', start)
timeline.addEventListener('mouseleave', stop)
timelineLink.addEventListener('mouseenter', function() {
timelineLinkEntered = true
})
timelineLink.addEventListener('mouseleave', function() {
timelineLinkEntered = false
setTimeout(function() {
if (paused) {
timelineLink.style.display = 'none'
}
}, 1000)
})
})
})