fix merge conflicts with About page
This commit is contained in:
commit
323a86a5e9
14 changed files with 326 additions and 266 deletions
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
.films {
|
.films {
|
||||||
margin: var(--spacing-2);
|
margin: var(--spacing-2);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -33,24 +31,25 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
main > .film {
|
main > .film {
|
||||||
max-width: var(--container-width);
|
max-width: var(--container-width);
|
||||||
margin: auto;
|
margin: auto;
|
||||||
.info {
|
.info {
|
||||||
margin: var(--spacing) var(--spacing-2);
|
|
||||||
margin-bottom: 32px;
|
margin-bottom: 32px;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 24px;
|
font-size: 20px;
|
||||||
margin: 24px 0;
|
margin: 0 0 24px 0;
|
||||||
}
|
}
|
||||||
h2 {
|
h2 {
|
||||||
|
font-size: 18px;
|
||||||
margin: 24px 0;
|
margin: 24px 0;
|
||||||
}
|
}
|
||||||
.details {
|
.details {
|
||||||
|
font-size: 18px;
|
||||||
margin-top: var(--spacing-2);
|
margin-top: var(--spacing-2);
|
||||||
}
|
}
|
||||||
.bio {
|
.bio {
|
||||||
|
@ -60,14 +59,12 @@ main > .film {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
video {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.play {
|
.play {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: var(--spacing);
|
|
||||||
margin-top: var(--spacing-2);
|
margin-top: var(--spacing-2);
|
||||||
margin-bottom: var(--spacing-2);
|
margin-bottom: var(--spacing-2);
|
||||||
|
max-width: 250px;
|
||||||
|
|
||||||
.texts {
|
.texts {
|
||||||
padding-top: var(--spacing-2);
|
padding-top: var(--spacing-2);
|
||||||
|
@ -85,3 +82,88 @@ main > .film {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.info-meta {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: absolute;
|
||||||
|
max-width: 600px;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
animation: fade_in 1s linear 0.4s forwards;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-meta, .bio-block, .play, .summary-block {
|
||||||
|
background: rgba(0, 0, 0, 0.55);
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.6);
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
padding: 20px;
|
||||||
|
font-size: 18px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--color-link);
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-block {
|
||||||
|
max-width: 1080px;
|
||||||
|
margin-top: 350px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bio-block {
|
||||||
|
max-width: 1080px;
|
||||||
|
margin-top: 30px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-block {
|
||||||
|
height: 100vh;
|
||||||
|
padding-bottom: 50px;
|
||||||
|
padding-top: 50px;
|
||||||
|
|
||||||
|
video {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: -9999;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
object-fit: fill;
|
||||||
|
//height: 100vh;
|
||||||
|
//width: auto;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-play {
|
||||||
|
color: #fff;
|
||||||
|
border: 3px solid var(--color-link);
|
||||||
|
border-radius: 50%;
|
||||||
|
font-size: 32px;
|
||||||
|
text-decoration: none;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.film-play-block {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.film-play-spacer {
|
||||||
|
padding: var(--spacing);
|
||||||
|
margin-top: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
|
@ -4,6 +4,8 @@
|
||||||
--bg-color-3: #ffff00;
|
--bg-color-3: #ffff00;
|
||||||
--bg-color-4: #ff3399;
|
--bg-color-4: #ff3399;
|
||||||
|
|
||||||
|
--color-link: #ee0;
|
||||||
|
|
||||||
--spacing: 8px;
|
--spacing: 8px;
|
||||||
--spacing-2: calc(var(--spacing) * 2);
|
--spacing-2: calc(var(--spacing) * 2);
|
||||||
|
|
||||||
|
@ -14,14 +16,23 @@
|
||||||
@keyframes background_animation {
|
@keyframes background_animation {
|
||||||
0%,100% {
|
0%,100% {
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
color: #ddd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
50% {
|
50% {
|
||||||
background-position: 100% 0;
|
background-position: 100% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes text_animation {
|
||||||
|
0%,100% {
|
||||||
|
color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body.animated {
|
body.animated {
|
||||||
background: linear-gradient(to right, var(--bg-color-1), var(--bg-color-2) , var(--bg-color-3), var(--bg-color-4));
|
background: linear-gradient(to right, var(--bg-color-1), var(--bg-color-2) , var(--bg-color-3), var(--bg-color-4));
|
||||||
//animation: background_animation 60s ease-in-out infinite;
|
//animation: background_animation 60s ease-in-out infinite;
|
||||||
|
@ -29,6 +40,10 @@ body.animated {
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.animated-text {
|
||||||
|
animation: text_animation 60s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
font-family: "noto_sans", sans-serif;
|
font-family: "noto_sans", sans-serif;
|
||||||
|
@ -63,3 +78,14 @@ nav {
|
||||||
padding-left: var(--spacing-2);
|
padding-left: var(--spacing-2);
|
||||||
padding-right: var(--spacing-2);
|
padding-right: var(--spacing-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Animations: Fade In
|
||||||
|
@keyframes fade_in {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
.topnav {
|
.topnav {
|
||||||
background-color: #333;
|
background-color: #333e;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 68px;
|
height: 68px;
|
||||||
padding: var(--spacing-2);
|
padding: var(--spacing-2);
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
|
:root {
|
||||||
|
--animated-title-color-1: #6666ff;
|
||||||
|
--animated-title-color-2: #0099ff;
|
||||||
|
--animated-title-color-3: #ffff00;
|
||||||
|
--animated-title-color-4: #ff3399;
|
||||||
|
}
|
||||||
@keyframes animated_title_animation {
|
@keyframes animated_title_animation {
|
||||||
0%,100% {
|
0%,100% {
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
|
@ -11,8 +16,7 @@
|
||||||
|
|
||||||
.animated-title {
|
.animated-title {
|
||||||
.text {
|
.text {
|
||||||
//background: linear-gradient(to right, #6666ff, #0099ff , #00ff00, #ff3399, #6666ff);
|
background: linear-gradient(to right, var(--animated-title-color-1), var(--animated-title-color-2) , var(--animated-title-color-3), var(--animated-title-color-4));
|
||||||
background: linear-gradient(to right, var(--bg-color-1), var(--bg-color-2) , var(--bg-color-3), var(--bg-color-4));
|
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
color: transparent;
|
color: transparent;
|
||||||
|
|
|
@ -8,5 +8,5 @@ document.querySelectorAll('.animated-title').forEach(element => {
|
||||||
var randomDuration = Math.random() * animationDuration;
|
var randomDuration = Math.random() * animationDuration;
|
||||||
element.querySelectorAll('.text').forEach(text => {
|
element.querySelectorAll('.text').forEach(text => {
|
||||||
text.style.animationDelay = -randomDuration + 's';
|
text.style.animationDelay = -randomDuration + 's';
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,6 +2,7 @@ var cache = cache || {}
|
||||||
var layer = 'descriptions'
|
var layer = 'descriptions'
|
||||||
var baseURL = 'https://pad.ma'
|
var baseURL = 'https://pad.ma'
|
||||||
var imageResolution = 480
|
var imageResolution = 480
|
||||||
|
var videoExtension
|
||||||
|
|
||||||
async function pandoraAPI(action, data) {
|
async function pandoraAPI(action, data) {
|
||||||
var url = baseURL + '/api/'
|
var url = baseURL + '/api/'
|
||||||
|
@ -21,13 +22,29 @@ async function pandoraAPI(action, data) {
|
||||||
return cache[key]
|
return cache[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setVideoSrc(video, src) {
|
||||||
|
var ext
|
||||||
|
if (!videoExtension) {
|
||||||
|
[
|
||||||
|
['video/mp4; codecs="avc1.42E01E, mp4a.40.2"', '.mp4'],
|
||||||
|
['video/webm; codecs="vp8, vorbis"', '.webm'],
|
||||||
|
].forEach(opt => {
|
||||||
|
if (videoExtension) { return }
|
||||||
|
if (video.canPlayType(opt[0]).replace('no', '')) {
|
||||||
|
videoExtension = opt[1]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
video.src = src.replace('.webm', videoExtension)
|
||||||
|
}
|
||||||
|
|
||||||
function updatePlayer(video, frame, currentTime, out, src) {
|
function updatePlayer(video, frame, currentTime, out, src) {
|
||||||
var rect = frame.getBoundingClientRect();
|
var rect = frame.getBoundingClientRect();
|
||||||
video.style.opacity = 0
|
video.style.opacity = 0
|
||||||
video.style.top = (rect.top + window.scrollY) + 'px'
|
video.style.top = (rect.top + window.scrollY) + 'px'
|
||||||
video.style.display = 'block';
|
video.style.display = 'block';
|
||||||
if (src) {
|
if (src) {
|
||||||
video.src = src
|
setVideoSrc(video, src)
|
||||||
}
|
}
|
||||||
//video.poster = frame.querySelector('img').src
|
//video.poster = frame.querySelector('img').src
|
||||||
var muted = video.muted
|
var muted = video.muted
|
||||||
|
@ -184,6 +201,79 @@ function showOverlay(event) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderAnnotation(config, video, ascroll, annotation) {
|
||||||
|
var div = document.createElement('div')
|
||||||
|
div.classList.add('annotation')
|
||||||
|
|
||||||
|
var color1 = `hsl(${annotation.color1.hue}, 70%, 75%)`
|
||||||
|
var color2 = `hsl(${annotation.color2.hue}, 70%, 75%)`
|
||||||
|
if (!config.first) {
|
||||||
|
config.first = annotation
|
||||||
|
config.info.style.background = color1
|
||||||
|
}
|
||||||
|
div.style.background = `linear-gradient(to bottom, ${color1}, ${color2})`;
|
||||||
|
var figcaption = ''
|
||||||
|
if (annotation.title) {
|
||||||
|
figcaption = `<figcaption><a href="${baseURL}/${annotation.id}" target="_blank">${annotation.title}</a></figcaption>`
|
||||||
|
}
|
||||||
|
div.innerHTML = `
|
||||||
|
<div class="frame">
|
||||||
|
<figure>
|
||||||
|
<img src="${baseURL}/${annotation.id.split('/')[0]}/${imageResolution}p${annotation.in}.jpg">
|
||||||
|
${figcaption}
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
<div class="text">${annotation.value}</div>
|
||||||
|
`
|
||||||
|
ascroll.appendChild(div)
|
||||||
|
var frame = div.querySelector('.frame')
|
||||||
|
document.addEventListener('scroll', onVisibilityChange(div.querySelector('.frame'), function(visible) {
|
||||||
|
var src
|
||||||
|
if (config.edit) {
|
||||||
|
src = `${baseURL}/${annotation.id.split('/')[0]}/480p.webm`
|
||||||
|
}
|
||||||
|
if (config.loaded && visible) {
|
||||||
|
updatePlayer(video, frame, annotation['in'], annotation['out'], src)
|
||||||
|
}
|
||||||
|
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderAnnotations(config) {
|
||||||
|
var ascroll = document.querySelector('#ascroll')
|
||||||
|
config.loaded = false
|
||||||
|
var video = document.createElement('video')
|
||||||
|
video.classList.add('player')
|
||||||
|
video.playsinline = true
|
||||||
|
video.muted = true
|
||||||
|
if (config.item) {
|
||||||
|
setVideoSrc(video, `${baseURL}/${config.item}/480p.webm`)
|
||||||
|
}
|
||||||
|
video.addEventListener('timeupdate', timeupdate)
|
||||||
|
video.addEventListener('touchstart', showOverlay)
|
||||||
|
video.addEventListener('mouseover', showOverlay)
|
||||||
|
var box = document.createElement('div')
|
||||||
|
box.classList.add('vbox')
|
||||||
|
box.appendChild(video)
|
||||||
|
ascroll.appendChild(box)
|
||||||
|
|
||||||
|
config.info = formatInfo(config, ascroll)
|
||||||
|
config.annotations.forEach(annotation => {
|
||||||
|
renderAnnotation(config, video, ascroll, annotation)
|
||||||
|
})
|
||||||
|
config.loaded = true
|
||||||
|
if (config.first) {
|
||||||
|
let frame = ascroll.querySelector('.annotation .frame')
|
||||||
|
if (frame) {
|
||||||
|
var src
|
||||||
|
if (config.edit) {
|
||||||
|
src = `${baseURL}/${config.first.id.split('/')[0]}/480p.webm`
|
||||||
|
}
|
||||||
|
updatePlayer(video, frame, config.first['in'], config.first['out'], src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function loadClips(annotations) {
|
async function loadClips(annotations) {
|
||||||
var items = annotations.map(annotation => annotation.id.split('/')[0])
|
var items = annotations.map(annotation => annotation.id.split('/')[0])
|
||||||
items = [...new Set(items)]
|
items = [...new Set(items)]
|
||||||
|
@ -212,140 +302,41 @@ async function loadClips(annotations) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadItem(config) {
|
function loadAnnotations(config) {
|
||||||
pandoraAPI('get', {id: config.item, keys: [
|
if (config.item) {
|
||||||
'id', 'title', 'layers', 'hue', 'saturation', 'lightness'
|
pandoraAPI('get', {id: config.item, keys: ['layers']}).then(response => {
|
||||||
]}).then(response => {
|
var annotations = response.data.layers[config.layer].filter(annotation => {
|
||||||
//var color = `hsl(${response.data.hue}, ${response.data.saturation * 100}%, ${response.data.lightness * 100}%)`
|
return !(config.user && annotation.user != config.user)
|
||||||
var color = `hsl(${response.data.hue}, 70%, 50%)`
|
})
|
||||||
//document.body.style.background = color
|
loadClips(annotations).then(annotations => {
|
||||||
var ascroll = document.querySelector('#ascroll')
|
config.annotations = annotations
|
||||||
var loaded = false
|
renderAnnotations(config)
|
||||||
|
})
|
||||||
var video = document.createElement('video')
|
|
||||||
video.classList.add('player')
|
|
||||||
video.muted = true
|
|
||||||
video.src = `${baseURL}/${config.item}/480p.webm`
|
|
||||||
video.addEventListener('timeupdate', timeupdate)
|
|
||||||
video.addEventListener('touchstart', showOverlay)
|
|
||||||
video.addEventListener('mouseover', showOverlay)
|
|
||||||
var box = document.createElement('div')
|
|
||||||
box.classList.add('vbox')
|
|
||||||
box.appendChild(video)
|
|
||||||
ascroll.appendChild(box)
|
|
||||||
|
|
||||||
var first
|
|
||||||
var info = formatInfo(config, ascroll)
|
|
||||||
var annotations = response.data.layers[config.layer].filter(annotation => {
|
|
||||||
return !(config.user && annotation.user != config.user)
|
|
||||||
})
|
})
|
||||||
loadClips(annotations).then(annotations => {
|
} else {
|
||||||
annotations.forEach(annotation => {
|
pandoraAPI('getEdit', {id: config.edit, keys: []}).then(response => {
|
||||||
var div = document.createElement('div')
|
var annotations = []
|
||||||
div.classList.add('annotation')
|
response.data.clips.forEach(clip => {
|
||||||
|
clip.layers[config.layer].forEach(annotation => {
|
||||||
var color1 = `hsl(${annotation.color1.hue}, 70%, 75%)`
|
if (config.user && annotation.user != config.user) {
|
||||||
var color2 = `hsl(${annotation.color2.hue}, 70%, 75%)`
|
return
|
||||||
if (!first) {
|
|
||||||
first = annotation
|
|
||||||
info.style.background = color1
|
|
||||||
}
|
|
||||||
div.style.background = `linear-gradient(to bottom, ${color1}, ${color2})`;
|
|
||||||
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'], annotation['out'])
|
|
||||||
}
|
}
|
||||||
|
annotation.title = clip.title
|
||||||
}))
|
annotations.push(annotation)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
loaded = true
|
loadClips(annotations).then(annotations => {
|
||||||
let frame = ascroll.querySelector('.annotation .frame')
|
config.annotations = annotations
|
||||||
if (frame) {
|
renderAnnotations(config)
|
||||||
updatePlayer(video, frame, first['in'], first['out'])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
function loadEdit(config) {
|
|
||||||
pandoraAPI('getEdit', {id: config.edit, keys: []}).then(response => {
|
|
||||||
var ascroll = document.querySelector('#ascroll')
|
|
||||||
var loaded = false
|
|
||||||
|
|
||||||
var video = document.createElement('video')
|
|
||||||
video.classList.add('player')
|
|
||||||
video.muted = true
|
|
||||||
video.addEventListener('timeupdate', timeupdate)
|
|
||||||
ascroll.appendChild(video)
|
|
||||||
|
|
||||||
var first
|
|
||||||
var info = formatInfo(config, ascroll)
|
|
||||||
var previous
|
|
||||||
|
|
||||||
var annotations = []
|
|
||||||
|
|
||||||
response.data.clips.forEach(clip => {
|
|
||||||
clip.layers[config.layer].forEach(annotation => {
|
|
||||||
if (config.user && annotation.user != config.user) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
annotation.title = clip.title
|
|
||||||
annotations.push(annotation)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
loadClips(annotations).then(annotations => {
|
}
|
||||||
annotations.forEach(annotation => {
|
|
||||||
var div = document.createElement('div')
|
|
||||||
div.classList.add('annotation')
|
|
||||||
|
|
||||||
var color1 = `hsl(${annotation.color1.hue}, 70%, 75%)`
|
|
||||||
var color2 = `hsl(${annotation.color2.hue}, 70%, 75%)`
|
|
||||||
if (!first) {
|
|
||||||
first = annotation
|
|
||||||
info.style.background = color1
|
|
||||||
}
|
|
||||||
div.style.background = `linear-gradient(to bottom, ${color1}, ${color2})`;
|
|
||||||
div.innerHTML = `
|
|
||||||
<div class="frame">
|
|
||||||
<figure>
|
|
||||||
<img src="${baseURL}/${annotation.id.split('/')[0]}/${imageResolution}p${annotation.in}.jpg">
|
|
||||||
<figcaption><a href="${baseURL}/${annotation.id}" target="_blank">${annotation.title}</a></figcaption>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="text">${annotation.value}</div>
|
|
||||||
|
|
||||||
`
|
|
||||||
ascroll.appendChild(div)
|
|
||||||
var frame = div.querySelector('.frame')
|
|
||||||
document.addEventListener('scroll', onVisibilityChange(div.querySelector('.frame'), function(visible) {
|
|
||||||
var src = `${baseURL}/${annotation.id.split('/')[0]}/480p.webm`
|
|
||||||
if (loaded && visible) {
|
|
||||||
updatePlayer(video, frame, annotation['in'], annotation['out'], src)
|
|
||||||
}
|
|
||||||
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
loaded = true
|
|
||||||
let frame = ascroll.querySelector('.annotation .frame')
|
|
||||||
if (frame) {
|
|
||||||
var src = `${baseURL}/${first.id.split('/')[0]}/480p.webm`
|
|
||||||
updatePlayer(video, frame, first['in'], first['out'], src)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.layer = config.layer || layer
|
config.layer = config.layer || layer
|
||||||
|
|
||||||
if (config.item) {
|
if (config.annotations) {
|
||||||
loadItem(config)
|
renderAnnotations(config)
|
||||||
} else if (config.edit) {
|
} else {
|
||||||
loadEdit(config)
|
loadAnnotations(config)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,28 @@
|
||||||
|
var videoExtension
|
||||||
|
|
||||||
|
function setVideoSrc(video, src) {
|
||||||
|
var ext
|
||||||
|
if (!videoExtension) {
|
||||||
|
[
|
||||||
|
['video/mp4; codecs="avc1.42E01E, mp4a.40.2"', '.mp4'],
|
||||||
|
['video/webm; codecs="vp8, vorbis"', '.webm'],
|
||||||
|
].forEach(opt => {
|
||||||
|
if (videoExtension) { return }
|
||||||
|
if (video.canPlayType(opt[0]).replace('no', '')) {
|
||||||
|
videoExtension = opt[1]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
video.src = src.replace('.webm', videoExtension)
|
||||||
|
}
|
||||||
|
|
||||||
document.querySelector('a#play-fullscreen').addEventListener('click', event => {
|
document.querySelector('a#play-fullscreen').addEventListener('click', event => {
|
||||||
|
event.preventDefault()
|
||||||
|
event.stopPropagation()
|
||||||
var video = document.createElement('video')
|
var video = document.createElement('video')
|
||||||
video.classList.add('player')
|
video.classList.add('player')
|
||||||
video.src = 'https://pad.ma/' + film.id + '/480p.webm'
|
setVideoSrc(video, 'https://pad.ma/' + film.id + '/480p.webm')
|
||||||
|
console.log(video.src)
|
||||||
video.controls = true
|
video.controls = true
|
||||||
document.querySelector('main').appendChild(video)
|
document.querySelector('main').appendChild(video)
|
||||||
video.style.display = 'none'
|
video.style.display = 'none'
|
||||||
|
@ -32,7 +53,4 @@ document.querySelector('a#play-fullscreen').addEventListener('click', event => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
video.play()
|
video.play()
|
||||||
|
|
||||||
event.preventDefault()
|
|
||||||
event.stopPropagation()
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -176,85 +176,12 @@
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<!-- <h3>Anushka RAJENDRAN</h3>
|
|
||||||
<p>
|
|
||||||
is a curator and art writer based in New Delhi. She is the curator for the Prameya Art Foundation (PRAF), a non-profit arts organization based in New Delhi committed to approaches that enable audience-thinking for contemporary art in India. She is also the Festival Curator of the 2021 edition of Colomboscope and was assistant curator for Kochi-Muziris Biennale 2018. As a research scholar, Anushka is completing her PhD in Visual Studies at the School of Arts and Aesthetics, Jawaharlal Nehru University, New Delhi. Her research traces how the notion of ‘public’ has acquired alternative significance to contemporary Indian art. Her previous MPhil research focused on the adoption of installation art by artists in India in the early 1990s to address collective and personal trauma. For her curatorial practice, she has been awarded fellowships that supported residencies with Fundación Sandretto Re Rebaudengo Madrid; Aomori Contemporary Art Center, Aomori, Japan; the International Studio & Curatorial Program (ISCP), New York (by Inlaks Shivdasani Foundation); and Theertha International Artists’ Collective, Colombo.
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
安努舒卡.拉堅德蘭,現居於新德里的獨立策展人、藝術評論者。曾為2018年柯欽雙年展(Kochi Biennale)之助理策展人,同時也是現任普拉美亞藝術基金會(Prameya Art Foundation) 策展人,這是個非營利的藝術組織,致力作為印度當代藝術與觀眾之橋樑。Anushka現正於印度新德里國立尼赫魯大學(Jawaharlal Nehru University)研讀視覺研究博士學位,她的研究領域包括:追溯2004年迄今當代印度藝術中公共意義的轉變,以及1990年代初期印度藝術家如何透過繪畫、雕塑回應個人及集體的創傷。安努舒卡曾於日本青森當代藝術中心、紐約國際工作室策展計畫(簡稱ISCP)及哥倫波等地駐村。2021年將擔任斯里蘭卡哥倫坡三年展(Colomboscope)之共同策展人。
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Pad.ma</h3>
|
|
||||||
<p>
|
|
||||||
is an artist-run online archive of densely text-annotated video material, primarily footage and not finished films contributed by filmmakers, artists and cultural workers. It was set up in 2008 as a collaboration between CAMP, 0x2620 and the Alternative Law Forum and Majlis. Pad.ma has remained at the forefront of radical and future-oriented thinking and engagement with both material and theory of archives, and their team members have lectured and conducted workshops worldwide on the same.
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
<h3>Pad.ma</h3>
|
|
||||||
<br>
|
|
||||||
公眾存取數位媒體檔案庫(Public Access Digital Media Archive ,簡稱Pad.ma)是一個為密集文字標注影片素材所設立的線上檔案庫。其營運團隊成員皆為藝術家,彙整內容主要為電影創作者、藝術家、文化工作者提供的影片資料帶和未完成的影片。2008年正式上線的Pad.ma為CAMP、0x2620、另類法律論壇、Majlis共同合作而成,而其激進、以未來為導向的思考模式多年來始終如一,並積極投入檔案資料的素材與理論的研究,團隊成員亦常於世界各地發表演講或舉辦工作坊。
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
|
|
||||||
<h3>CAMP</h3>
|
|
||||||
<p>
|
|
||||||
is a collaborative studio founded in Bombay in 2007. It has been producing fundamental new work in film and video, electronic media, and public art forms, in a practice characterised by a hand-dirtying, non-alienated relation to technology. From their home base in Mumbai, they co-host the online archives pad.ma and indiancine.ma and run a rooftop cinema for the past 14 years.
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
|
|
||||||
<h3>CAMP</h3>
|
|
||||||
<br>
|
|
||||||
為2007年成立於孟買的合作型工作室。其創作一向與技術維持近距親身的接觸,和不排斥不疏離的關係,並秉持此一精神與作法,不斷推出電影及錄像、電子媒體、公共藝術等類型的全新作品。他們以設址於孟買的總部為據點,執行線上資料庫 Pad.ma和 Indiancine.ma的聯合運作,其於14年前開辦的屋頂電影院至今依舊照常營運。
|
|
||||||
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
<h3>0x2620</h3>
|
|
||||||
<br>
|
|
||||||
Founded in 2010 in Berlin, is an artist-run agency for the advancement of the international exchange of information, and usually operates at the intersections of art, politics and technology. Its activities include extensive research on intellectual property and piracy, the development of open-source software tools and web applications, and the production of both technological and social infrastructure for the collaborative creation, maintenance and use of relatively large data sets.
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
<h3>0x2620</h3>
|
|
||||||
<br>
|
|
||||||
2010年成立於柏林,是一個為促進國際資訊交流而建立的藝術家營運機構,擅長處理藝術、政治、技術之間所產生的交集與碰撞塊。活動包括在智慧財產與盜版、開放源軟體工具及網路應用程式的開發、合作性創作、相對巨量數據集的維護及使用等多方面的研究。
|
|
||||||
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
<h3>Annotation Collaborators:</h3> <br>
|
|
||||||
影片評論共筆:
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
<strong>Yang Yu-Chiao</strong> is a researcher on oral literature, narratology and folktale poetics, and is also a narrator of Taiwanese folktales in the oral tradition. Yu-Chiao also created several performances drawing from storytelling, poetry, writing actions, and experimental sounds with artists working with different media including digital, film, and classical music since 2017. Yu-Chiao has published several works including a series of tales that demonstrate characters in oracle bone script.
|
|
||||||
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
楊雨樵,喜歡散步,喜歡樹的屍骨。專職為口頭傳統民間譚的言說藝術表演者與獨立撰稿人,並從事口傳文學、戲劇與電影的敘事學、故事詩學與比較故事學研究。除開設「世界民間譚」展演式講座外,2017 年開始以言說藝術表演者身份,和聲音、影像領域的藝術家合作,發展如《聲熔質變——Anamorphosis & Anatexis》的實驗性系列演出至今。出版過數本以甲骨文為對象的文學創作,其他文章散見於紙本刊物與網路平台。
|
|
||||||
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
<strong>Chen Wan-Yin</strong> is an art critic and a writer. She is currently a Ph.D. researcher on media aesthetics and East Asian contemporary art at Vrije Universiteit Amsterdam. She previously worked as an editor of Artist Magazine (Taipei) from 2014 to 2017 and since 2015, she has also been working as a scriptwriter with video artist Hsu Che-Yu.
|
|
||||||
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
陳琬尹,現為阿姆斯特丹自由大學藝術史與文化學系博士生,研究關注東亞現當代藝術史與媒介美學,曾任多年藝術雜誌編輯。
|
|
||||||
|
|
||||||
</p> -->
|
|
||||||
<br>
|
<br>
|
||||||
<h2>Acknowledgements:</h2>
|
<h2>Acknowledgements:</h2>
|
||||||
<p>Nobuo Takamori, Zinnia Ambapardiwala, Karen Menezes, Sanjay Bhangar, Ho Yu-Kuan, Renyu Ye please add here Chia-cheng Liao*
|
<p>Nobuo Takamori, Zinnia Ambapardiwala, Karen Menezes, Sanjay Bhangar, Ho Yu-Kuan, Renyu Ye please add here Chia-cheng Liao*</p>
|
||||||
</p><p>
|
<p>致謝:高森信男、Zinnia Ambapardiwala、Karen Menezes、Sanjay Bhangar、葉人瑜</p>
|
||||||
|
<p>Project "Phantas.ma/polis" is organized by National Taiwan Museum of Fine Arts, supervised by the Ministry of Culture, and is co-organized by the Cultural Taiwan Foundation and in partnership with SEA Plateau.</p>
|
||||||
|
<p>本計畫由國立臺灣美術館策劃,文化部指導、財團法人文化臺灣基金會支持、SEA plateaus協力。
|
||||||
致謝:高森信男、Zinnia Ambapardiwala、Karen Menezes、Sanjay Bhangar、葉人瑜
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Project "Phantas.ma/polis" is organized by National Taiwan Museum of Fine Arts, supervised by the Ministry of Culture, and is co-organized by the Cultural Taiwan Foundation and in partnership with SEA Plateau.
|
|
||||||
|
|
||||||
</p><p>
|
|
||||||
|
|
||||||
本計畫由國立臺灣美術館策劃,文化部指導、財團法人文化臺灣基金會支持、SEA plateaus協力。
|
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
0
app/templates/base.html
Executable file → Normal file
0
app/templates/base.html
Executable file → Normal file
|
@ -9,51 +9,63 @@
|
||||||
--bg-color-4: {{ film.color_4 }};
|
--bg-color-4: {{ film.color_4 }};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-attachment: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="film">
|
<div class="film">
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<h1>
|
<div class="info-meta">
|
||||||
<span>{{ film.data.title | safe }}</span>
|
<h1>
|
||||||
<span>{{ film.data.title_zh | safe }}</span>
|
<span class="font-bold">{{ film.data.title | safe }}</span>
|
||||||
</h1>
|
<span>{{ film.data.title_zh | safe }}</span>
|
||||||
<h2>
|
</h1>
|
||||||
{% for director in film.data.director %}
|
<h2>
|
||||||
{{ director|safe }}<br>
|
{% for director in film.data.director %}
|
||||||
{% endfor %}
|
{{ director|safe }}<br>
|
||||||
</h2>
|
{% endfor %}
|
||||||
<div class="details">
|
</h2>
|
||||||
{{ film.data.date }}, {{ film.duration }}
|
<div class="details">
|
||||||
|
{{ film.data.date}}, {{ film.duration }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="video-block">
|
||||||
|
<video src="{{ settings.TIMELINE_PREFIX }}{{ film.padma_id }}/loop.mp4" autoplay loop muted playsinline></video>
|
||||||
</div>
|
</div>
|
||||||
<video src="{{ settings.TIMELINE_PREFIX }}{{ film.padma_id }}/loop.mp4" autoplay loop muted></video>
|
<div class="summary-block">
|
||||||
<p>{{ film.data.summary|safe }}</p>
|
<p>{{ film.data.summary|safe }}</p>
|
||||||
<br>
|
<br>
|
||||||
<p>{{ film.data.summary_zh|safe }}</p>
|
<p>{{ film.data.summary_zh|safe }}</p>
|
||||||
<div class="bio">
|
</div>
|
||||||
<div class="en">
|
<div class="bio-block">
|
||||||
{{film.data.director.0}}: {{ film.data.bio|safe }}
|
<div class="bio">
|
||||||
</div>
|
<div class="en">
|
||||||
<div class="zh">
|
{{film.data.director.0}}: {{ film.data.bio|safe }}
|
||||||
{{film.data.director.1}}: {{ film.data.bio_zh|safe }}
|
</div>
|
||||||
|
<div class="zh">
|
||||||
|
{{film.data.director.1}}: {{ film.data.bio_zh|safe }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="play">
|
||||||
<div class="play">
|
<div class="texts">
|
||||||
<div>
|
{% for text in film.related_texts %}
|
||||||
<a href="" id="play-fullscreen">Play</a>
|
<div class="text">
|
||||||
</div>
|
<a href="{{ text.get_absolute_url }}">
|
||||||
<div class="texts">
|
{{ text.title }}<br>
|
||||||
{% for text in film.related_texts %}
|
{{ text.byline }}
|
||||||
<div class="text">
|
</a>
|
||||||
<a href="{{ text.get_absolute_url }}">
|
</div>
|
||||||
{{ text.title }}<br>
|
{% endfor %}
|
||||||
{{ text.byline }}
|
</div>
|
||||||
</a>
|
<div class="film-play-block">
|
||||||
|
<div><a href="" id="play-fullscreen" class="icon-play"><span>▶</span></a></div>
|
||||||
|
<div class="film-play-spacer">OR</div>
|
||||||
|
<div><a href="https://pad.ma/{{ film.padma_id }}/info" target="_blank">watch on pad.ma</a></div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a href="https://pad.ma/{{ film.padma_id }}/info" target="_blank">Open on pad.ma</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block body_class%}animated{% endblock %}
|
{% block body_class%}animated animated-text{% endblock %}
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<div class="films">
|
<div class="films">
|
||||||
{% for film in films %}
|
{% for film in films %}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block body_class%}animated{% endblock %}
|
{% block body_class%}animated animated-text{% endblock %}
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<div class="index">
|
<div class="index">
|
||||||
Phantasmapolis<br>
|
Phantasmapolis<br>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}{{ page.title }}– Phantas.ma/polis{% endblock title %}
|
{% block title %}{{ page.title }}– Phantas.ma/polis{% endblock title %}
|
||||||
{% block body_class%}animated{% endblock %}
|
{% block body_class%}animated animated-text{% endblock %}
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<div class="page {{ page.slug }}">
|
<div class="page {{ page.slug }}">
|
||||||
{{ page.body | safe }}
|
{{ page.body | safe }}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block body_class%}animated{% endblock %}
|
{% block body_class%}animated animated-text{% endblock %}
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
|
||||||
<div class="texts">
|
<div class="texts">
|
||||||
|
|
Loading…
Reference in a new issue