inital version of scroll view, burger menu, css reset
This commit is contained in:
parent
0508d8cd9a
commit
4faf546335
20 changed files with 438 additions and 42 deletions
34
app/static/css/partials/_ascroll.scss
Normal file
34
app/static/css/partials/_ascroll.scss
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#ascroll {
|
||||
font-family: "Noton Sans";
|
||||
width: 100vw;
|
||||
|
||||
h1 {
|
||||
margin: 4px;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 64px;
|
||||
font-size: 24px;
|
||||
letter-spacing: 1px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.player {
|
||||
position: absolute;
|
||||
display: none;
|
||||
width: 100vw;
|
||||
height: auto;
|
||||
//transition: opacity 0.4s;
|
||||
|
||||
}
|
||||
.annotation {
|
||||
.frame {
|
||||
img {
|
||||
width: 100vw;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
.text {
|
||||
margin: 20px 20px;
|
||||
font-size: 22px;
|
||||
line-height: 26px;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
app/static/css/partials/_layout.scss
Normal file
18
app/static/css/partials/_layout.scss
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
body {
|
||||
background: #d3d;
|
||||
color: #eee;
|
||||
font-family: "Noto Sans";
|
||||
font-size: 20px;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
main {
|
||||
line-height: 1.2em;
|
||||
|
||||
}
|
||||
|
||||
nav {
|
||||
a {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
48
app/static/css/partials/_reset.scss
Normal file
48
app/static/css/partials/_reset.scss
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
53
app/static/css/partials/burger.scss
Normal file
53
app/static/css/partials/burger.scss
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
.topnav {
|
||||
background-color: #333;
|
||||
position: relative;
|
||||
height: 72px;
|
||||
padding-left: 16px;
|
||||
padding-top: 16px;
|
||||
@media screen and (max-width: 799px) {
|
||||
overflow: hidden;
|
||||
z-index: 100;
|
||||
height: initial;
|
||||
padding-left: initial;
|
||||
padding-top: initial;
|
||||
}
|
||||
|
||||
nav {
|
||||
display: block;
|
||||
text-align: right;
|
||||
margin-right: 16px;
|
||||
@media screen and (max-width: 799px) {
|
||||
display: none;
|
||||
text-align: initial;
|
||||
margin-right: initial;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-size: 17px;
|
||||
@media screen and (max-width: 799px) {
|
||||
padding: 14px 16px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.icon {
|
||||
display: none;
|
||||
@media screen and (max-width: 799px) {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #ddd;
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,12 +1,4 @@
|
|||
body {
|
||||
background: #000;
|
||||
color: #fff;
|
||||
font-family: "Noto Sans";
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
nav {
|
||||
a {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
@import "partials/reset";
|
||||
@import "partials/layout";
|
||||
@import "partials/burger";
|
||||
@import "partials/ascroll";
|
||||
|
|
|
|||
121
app/static/js/ascroll.js
Normal file
121
app/static/js/ascroll.js
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
var cache = cache || {}
|
||||
var layer = 'descriptions'
|
||||
var baseURL = 'https://pad.ma'
|
||||
var imageResolution = 480
|
||||
|
||||
let lastKnownScrollPosition = 0
|
||||
let ticking = false;
|
||||
|
||||
|
||||
async function pandoraAPI(action, data) {
|
||||
var url = baseURL + '/api/'
|
||||
//var url = '/pandoraAPI/'
|
||||
var key = JSON.stringify([action, data])
|
||||
if (!cache[key]) {
|
||||
var response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
action: action,
|
||||
data: data
|
||||
})
|
||||
})
|
||||
cache[key] = await response.json()
|
||||
}
|
||||
return cache[key]
|
||||
}
|
||||
|
||||
function updatePlayerPosition(video, lastKnownScrollPosition) {
|
||||
console.log('update', lastKnownScrollPosition)
|
||||
video.style.top = lastKnownScrollPosition + 'px'
|
||||
video.style.display = 'block';
|
||||
}
|
||||
|
||||
function updatePlayer(video, frame, currentTime) {
|
||||
var rect = frame.getBoundingClientRect();
|
||||
video.style.opacity = 0
|
||||
console.log('update player', rect)
|
||||
video.style.top = (rect.top + window.scrollY) + 'px'
|
||||
video.style.display = 'block';
|
||||
//video.poster = frame.querySelector('img').src
|
||||
video.currentTime = currentTime
|
||||
video.controls = true
|
||||
video.play()
|
||||
video.style.opacity = 1
|
||||
}
|
||||
|
||||
function isElementInViewport (el) {
|
||||
var rect = el.getBoundingClientRect();
|
||||
return (
|
||||
rect.top >= 0 &&
|
||||
rect.left >= 0 &&
|
||||
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /* or $(window).height() */
|
||||
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */
|
||||
);
|
||||
}
|
||||
|
||||
function onVisibilityChange(el, callback) {
|
||||
var old_visible;
|
||||
return function () {
|
||||
var visible = isElementInViewport(el);
|
||||
if (visible != old_visible) {
|
||||
old_visible = visible;
|
||||
if (typeof callback == 'function') {
|
||||
callback(visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pandoraAPI('get', {id: film.id, keys: ['id', 'title', 'layers']}).then(response => {
|
||||
var ascroll = document.querySelector('#ascroll')
|
||||
var loaded = false
|
||||
|
||||
var video = document.createElement('video')
|
||||
video.classList.add('player')
|
||||
video.muted = true
|
||||
video.src = `${baseURL}/${film.id}/480p.webm`
|
||||
ascroll.appendChild(video)
|
||||
|
||||
var h1 = document.createElement('h1')
|
||||
h1.innerHTML = response.data.title
|
||||
ascroll.appendChild(h1)
|
||||
|
||||
response.data.layers[layer].forEach(annotation => {
|
||||
var div = document.createElement('div')
|
||||
div.classList.add('annotation')
|
||||
div.innerHTML = `
|
||||
<div class="frame"><img src="${baseURL}/${annotation.id.split('/')[0]}/${imageResolution}p${annotation.in}.jpg"></div>
|
||||
<div class="text">${annotation.value}</div>
|
||||
|
||||
`
|
||||
ascroll.appendChild(div)
|
||||
var frame = div.querySelector('.frame')
|
||||
document.addEventListener('scroll', onVisibilityChange(div.querySelector('.frame'), function(visible) {
|
||||
if (loaded && visible)
|
||||
updatePlayer(video, frame, annotation['in'])
|
||||
|
||||
}))
|
||||
})
|
||||
loaded = true
|
||||
let frame = ascroll.querySelector('.annotation .frame')
|
||||
if (frame) {
|
||||
updatePlayer(video, frame, 0)
|
||||
}
|
||||
|
||||
/*
|
||||
document.addEventListener('scroll', function(e) {
|
||||
lastKnownScrollPosition = window.scrollY;
|
||||
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(function() {
|
||||
updatePlayerPosition(video, lastKnownScrollPosition);
|
||||
ticking = false;
|
||||
});
|
||||
|
||||
ticking = true;
|
||||
}
|
||||
})
|
||||
*/
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue