split utils, fix pandora-scroll element
This commit is contained in:
parent
a1eec24f17
commit
b1cd3e292b
5 changed files with 260 additions and 213 deletions
|
@ -4,6 +4,9 @@
|
||||||
min-height: calc(100vh - 64px);
|
min-height: calc(100vh - 64px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#video-overlay {
|
||||||
|
z-index: 11;
|
||||||
|
}
|
||||||
#ascroll {
|
#ascroll {
|
||||||
font-family: "noto_sans";
|
font-family: "noto_sans";
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -46,8 +49,18 @@
|
||||||
max-height: 88vh;
|
max-height: 88vh;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
//transition: opacity 0.4s;
|
//transition: opacity 0.4s;
|
||||||
|
z-index: 10;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
.left {
|
||||||
|
float: left;
|
||||||
|
padding-right: 1vw;
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
.clearpara {
|
||||||
|
clear: left;
|
||||||
|
padding-top: 1vh;
|
||||||
|
}
|
||||||
.annotation {
|
.annotation {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
.frame {
|
.frame {
|
||||||
|
|
|
@ -1,35 +1,22 @@
|
||||||
var layer = 'keywords'
|
var layer = 'keywords'
|
||||||
var imageResolution = 480
|
var imageResolution = 480
|
||||||
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]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
src = src.replace('.webm', videoExtension)
|
|
||||||
if (src != video.src) {
|
|
||||||
video.src = src
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resize() {
|
function resize() {
|
||||||
var video = document.querySelector('video')
|
var video = document.querySelector('video')
|
||||||
if (video && video._frame) {
|
if (video && video._frame) {
|
||||||
var rect = video._frame.getBoundingClientRect();
|
var top, rect = video._frame.getBoundingClientRect();
|
||||||
video.style.top = (rect.top + window.scrollY) + 'px'
|
if (video._root) {
|
||||||
|
var root_rect = video._root.getBoundingClientRect();
|
||||||
|
top = rect.top - root_rect.top
|
||||||
|
} else {
|
||||||
|
top = rect.top + window.scrollY
|
||||||
|
}
|
||||||
|
video.style.top = top + 'px'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePlayer(video, frame, currentTime, out, src, config) {
|
function updatePlayer(video, frame, currentTime, out, src, config) {
|
||||||
|
//console.log('update player', currentTime, out, src)
|
||||||
var top, rect = frame.getBoundingClientRect();
|
var top, rect = frame.getBoundingClientRect();
|
||||||
video.style.opacity = 0
|
video.style.opacity = 0
|
||||||
if (config.root) {
|
if (config.root) {
|
||||||
|
@ -41,6 +28,7 @@ function updatePlayer(video, frame, currentTime, out, src, config) {
|
||||||
}
|
}
|
||||||
video.style.top = top + 'px'
|
video.style.top = top + 'px'
|
||||||
video.style.display = 'block';
|
video.style.display = 'block';
|
||||||
|
video.style.maxWidth = rect.width + 'px'
|
||||||
if (src) {
|
if (src) {
|
||||||
setVideoSrc(video, src)
|
setVideoSrc(video, src)
|
||||||
}
|
}
|
||||||
|
@ -50,6 +38,7 @@ function updatePlayer(video, frame, currentTime, out, src, config) {
|
||||||
video.currentTime = currentTime
|
video.currentTime = currentTime
|
||||||
video.dataset.in = currentTime
|
video.dataset.in = currentTime
|
||||||
video.dataset.out = out
|
video.dataset.out = out
|
||||||
|
video._root = config.root
|
||||||
video._frame = frame
|
video._frame = frame
|
||||||
const show = event => {
|
const show = event => {
|
||||||
video.style.opacity = 1
|
video.style.opacity = 1
|
||||||
|
@ -60,51 +49,6 @@ function updatePlayer(video, frame, currentTime, out, src, config) {
|
||||||
video.play()
|
video.play()
|
||||||
}
|
}
|
||||||
|
|
||||||
function isElementInViewport (el) {
|
|
||||||
var rect = el.getBoundingClientRect();
|
|
||||||
return (
|
|
||||||
rect.top >= 0 &&
|
|
||||||
rect.left >= 0 &&
|
|
||||||
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /* or $(window).height() */
|
|
||||||
Math.floor(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 (visible) {
|
|
||||||
el.classList.add('visible')
|
|
||||||
} else {
|
|
||||||
el.classList.remove('visible')
|
|
||||||
}
|
|
||||||
if (typeof callback == 'function') {
|
|
||||||
callback(visible);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function scrollTo(element) {
|
|
||||||
var delta = element.offsetTop - document.scrollingElement.scrollTop,
|
|
||||||
duration = 1000, t = 40, n = duration / t,
|
|
||||||
step = delta / n;
|
|
||||||
|
|
||||||
function scroll() {
|
|
||||||
if (document.scrollingElement.scrollTop + step > element.offsetTop) {
|
|
||||||
document.scrollingElement.scrollTop = element.offsetTop
|
|
||||||
n = 0
|
|
||||||
} else {
|
|
||||||
document.scrollingElement.scrollTop += step
|
|
||||||
}
|
|
||||||
n--
|
|
||||||
if (n) setTimeout(scroll, t)
|
|
||||||
}
|
|
||||||
scroll()
|
|
||||||
}
|
|
||||||
|
|
||||||
function timeupdate(event) {
|
function timeupdate(event) {
|
||||||
if (event.target.dataset.out && event.target.dataset.in) {
|
if (event.target.dataset.out && event.target.dataset.in) {
|
||||||
|
@ -156,59 +100,7 @@ function formatInfo(config, ascroll) {
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
function showOverlay(event) {
|
function renderAnnotation(config, video, root, clip) {
|
||||||
event.stopPropagation()
|
|
||||||
event.preventDefault()
|
|
||||||
document.querySelectorAll('#video-overlay').forEach(element => element.remove())
|
|
||||||
var video = event.target
|
|
||||||
var rect = video.getBoundingClientRect();
|
|
||||||
var overlay = document.createElement('div')
|
|
||||||
overlay.id = 'video-overlay'
|
|
||||||
overlay.style.top = video.style.top
|
|
||||||
overlay.style.width = rect.width + 'px'
|
|
||||||
overlay.style.height = rect.height + 'px'
|
|
||||||
overlay.style.position = 'absolute'
|
|
||||||
overlay.style.display = 'flex'
|
|
||||||
overlay.style.alignItems = 'center'
|
|
||||||
overlay.style.justifyContent = 'center'
|
|
||||||
//overlay.style.fontSize = '45px'
|
|
||||||
video.controls = false
|
|
||||||
|
|
||||||
var off = `<span class="annotation-icon-wrapper animated"><span class="text f-icon-volume_off annotation-icon"></span>`
|
|
||||||
var on = `<span class="annotation-icon-wrapper"><span class="f-icon-volume_down annotation-icon"></span></span>`
|
|
||||||
|
|
||||||
if (video.muted) {
|
|
||||||
overlay.innerHTML = off
|
|
||||||
} else {
|
|
||||||
overlay.innerHTML = on
|
|
||||||
}
|
|
||||||
overlay.addEventListener('click', event=> {
|
|
||||||
const muted = video.muted
|
|
||||||
document.querySelectorAll('pandora-scroll').forEach(el => el.mute() )
|
|
||||||
video.muted = !muted
|
|
||||||
if (video.muted) {
|
|
||||||
overlay.innerHTML = off
|
|
||||||
} else {
|
|
||||||
overlay.innerHTML = on
|
|
||||||
}
|
|
||||||
})
|
|
||||||
var timeout = setTimeout(() => {
|
|
||||||
video.controls = false
|
|
||||||
overlay.remove()
|
|
||||||
}, 3000)
|
|
||||||
overlay.addEventListener('mousemove', event=> {
|
|
||||||
clearTimeout(timeout)
|
|
||||||
timeout = setTimeout(() => {
|
|
||||||
video.controls = false
|
|
||||||
overlay.remove()
|
|
||||||
}, 500)
|
|
||||||
})
|
|
||||||
video.parentElement.appendChild(overlay)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderAnnotation(config, video, ascroll, clip) {
|
|
||||||
console.log("renderAnnotation", clip)
|
|
||||||
var div = document.createElement('div')
|
var div = document.createElement('div')
|
||||||
div.classList.add('annotation')
|
div.classList.add('annotation')
|
||||||
var annotation = clip.annotations[0]
|
var annotation = clip.annotations[0]
|
||||||
|
@ -239,22 +131,23 @@ function renderAnnotation(config, video, ascroll, clip) {
|
||||||
</div>
|
</div>
|
||||||
<div class="text">${values}</div>
|
<div class="text">${values}</div>
|
||||||
`
|
`
|
||||||
ascroll.appendChild(div)
|
root.appendChild(div)
|
||||||
var frame = div.querySelector('.frame')
|
var frame = div.querySelector('.frame')
|
||||||
document.addEventListener('scroll', onVisibilityChange(div.querySelector('.frame'), function(visible) {
|
document.addEventListener('scroll', onVisibilityChange(div.querySelector('.frame'), function(visible) {
|
||||||
var src
|
var src
|
||||||
if (config.edit) {
|
if (clip.src) {
|
||||||
|
src = clip.src
|
||||||
|
} else if (config.edit) {
|
||||||
src = `${streamPrefix}/${annotation.id.split('/')[0]}/480p.webm`
|
src = `${streamPrefix}/${annotation.id.split('/')[0]}/480p.webm`
|
||||||
}
|
}
|
||||||
if (config.loaded && visible) {
|
if (config.loaded && visible) {
|
||||||
updatePlayer(video, frame, annotation['in'], annotation['out'], src, config)
|
updatePlayer(video, frame, annotation['in'], annotation['out'], src, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderAnnotations(config) {
|
function renderAnnotations(config) {
|
||||||
console.log('renderAnnotations', config.item, config.annotations.length)
|
//console.log('renderAnnotations', config.item, config.annotations.length)
|
||||||
var ascroll = config.root ? config.root : document.querySelector('#ascroll')
|
var ascroll = config.root ? config.root : document.querySelector('#ascroll')
|
||||||
config.loaded = false
|
config.loaded = false
|
||||||
var video = document.createElement('video')
|
var video = document.createElement('video')
|
||||||
|
@ -292,22 +185,9 @@ function renderAnnotations(config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isInside(config, annotation) {
|
|
||||||
if (!config['in'] && !config['out']) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (annotation['in'] < config['out'] && annotation['out'] > config['in']) {
|
|
||||||
annotation['in'] = Math.min(annotation['in'], config['in'])
|
|
||||||
annotation['out'] = Math.min(annotation['out'], config['out'])
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
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)]
|
||||||
console.log('loadClips', annotations, items)
|
|
||||||
return pandoraAPI('findClips', {itemsQuery: {
|
return pandoraAPI('findClips', {itemsQuery: {
|
||||||
conditions: [{key: 'id', operator: '&', value: items}]
|
conditions: [{key: 'id', operator: '&', value: items}]
|
||||||
}, range: [0, 10000], keys: [
|
}, range: [0, 10000], keys: [
|
||||||
|
@ -348,7 +228,7 @@ async function loadClips(annotations) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadAnnotations(config) {
|
async function loadAnnotations(config) {
|
||||||
var layers = config.layer || config.layers || []
|
var layers = config.layer || config.layers || []
|
||||||
if (!Array.isArray(layers)) {
|
if (!Array.isArray(layers)) {
|
||||||
layers = [layers]
|
layers = [layers]
|
||||||
|
@ -370,9 +250,9 @@ function loadAnnotations(config) {
|
||||||
"color2": "",
|
"color2": "",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
renderAnnotations(config)
|
return config
|
||||||
} else if (config.item) {
|
} else if (config.item) {
|
||||||
pandoraAPI('get', {id: config.item, keys: [
|
return pandoraAPI('get', {id: config.item, keys: [
|
||||||
'layers'
|
'layers'
|
||||||
]}).then(response => {
|
]}).then(response => {
|
||||||
var annotations = []
|
var annotations = []
|
||||||
|
@ -386,8 +266,7 @@ function loadAnnotations(config) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
loadClips(annotations).then(annotations => {
|
return loadClips(annotations).then(annotations => {
|
||||||
console.log('got', annotations)
|
|
||||||
config.annotations = annotations.filter(annotation => {
|
config.annotations = annotations.filter(annotation => {
|
||||||
if (config.only_e) {
|
if (config.only_e) {
|
||||||
if (annotation.value.slice(0, 2) == 'E:') {
|
if (annotation.value.slice(0, 2) == 'E:') {
|
||||||
|
@ -400,13 +279,13 @@ function loadAnnotations(config) {
|
||||||
return annotation
|
return annotation
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
renderAnnotations(config)
|
return config
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
var cited = {}
|
var cited = {}
|
||||||
if (config.edit) {
|
if (config.edit) {
|
||||||
pandoraAPI('getEdit', {id: config.edit, keys: []}).then(response => {
|
return pandoraAPI('getEdit', {id: config.edit, keys: []}).then(response => {
|
||||||
var annotations = []
|
var annotations = []
|
||||||
response.data.clips.forEach(clip => {
|
response.data.clips.forEach(clip => {
|
||||||
cited[clip.item] = {
|
cited[clip.item] = {
|
||||||
|
@ -435,17 +314,17 @@ function loadAnnotations(config) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
loadClips(annotations).then(annotations => {
|
return loadClips(annotations).then(annotations => {
|
||||||
config.annotations = annotations
|
config.annotations = annotations
|
||||||
config.cited = Object.values(cited)
|
config.cited = Object.values(cited)
|
||||||
renderAnnotations(config)
|
return config
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if (!config.annotations) {
|
if (!config.annotations) {
|
||||||
config.annotations = []
|
config.annotations = []
|
||||||
}
|
}
|
||||||
renderAnnotations(config)
|
return config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,7 +334,7 @@ config.layer = config.layer || layer
|
||||||
if (false && config.annotations) {
|
if (false && config.annotations) {
|
||||||
renderAnnotations(config)
|
renderAnnotations(config)
|
||||||
} else {
|
} else {
|
||||||
loadAnnotations(config)
|
loadAnnotations(config).then(renderAnnotations)
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('resize', resize, false);
|
window.addEventListener('resize', resize, false);
|
||||||
|
|
|
@ -20,6 +20,10 @@ class PandoraScroll extends HTMLElement {
|
||||||
shadow.appendChild(link)
|
shadow.appendChild(link)
|
||||||
shadow.appendChild(style)
|
shadow.appendChild(style)
|
||||||
shadow.appendChild(body)
|
shadow.appendChild(body)
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
this._resize()
|
||||||
|
}, false)
|
||||||
|
|
||||||
this.mute = function() {
|
this.mute = function() {
|
||||||
shadow.querySelectorAll('video').forEach(video => {
|
shadow.querySelectorAll('video').forEach(video => {
|
||||||
video.muted = true
|
video.muted = true
|
||||||
|
@ -31,19 +35,18 @@ class PandoraScroll extends HTMLElement {
|
||||||
static get observedAttributes() { return ['muted']; }
|
static get observedAttributes() { return ['muted']; }
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
console.log('scroll connected')
|
|
||||||
this._loadAnnotations()
|
this._loadAnnotations()
|
||||||
this._updateStyle()
|
this._updateStyle()
|
||||||
}
|
}
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
console.log('scroll disconnected')
|
//console.log('scroll disconnected')
|
||||||
}
|
}
|
||||||
adoptedCallback() {
|
adoptedCallback() {
|
||||||
console.log('Custom square element moved to new page.');
|
//console.log('element moved to new page.');
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeChangedCallback(name, oldValue, newValue) {
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
console.log('value changed', name, oldValue, newValue);
|
//console.log('value changed', name, oldValue, newValue);
|
||||||
this._updateStyle()
|
this._updateStyle()
|
||||||
}
|
}
|
||||||
_updateStyle() {
|
_updateStyle() {
|
||||||
|
@ -79,29 +82,42 @@ class PandoraScroll extends HTMLElement {
|
||||||
_loadAnnotations() {
|
_loadAnnotations() {
|
||||||
var config = this._config()
|
var config = this._config()
|
||||||
config.root = this.shadowRoot.querySelector('.pandora-scroll')
|
config.root = this.shadowRoot.querySelector('.pandora-scroll')
|
||||||
console.log(config)
|
config.video = document.querySelector('video')
|
||||||
loadAnnotations(config)
|
loadAnnotations(config).then(config => {
|
||||||
|
config.annotations.forEach(annotation => {
|
||||||
|
annotation.src = `${streamPrefix}/${annotation.id.split('/')[0]}/480p.webm`
|
||||||
|
renderAnnotation(window.config, config.video, config.root, annotation)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
_resize() {
|
||||||
|
var video = this.shadowRoot.querySelector('video')
|
||||||
|
if (video && video._frame) {
|
||||||
|
var rect = video._frame.getBoundingClientRect(),
|
||||||
|
root_rect = video._root.getBoundingClientRect(),
|
||||||
|
top = rect.top - root_rect.top;
|
||||||
|
video.style.top = top + 'px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PandoraItem extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class PandoraEdit extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("pandora-scroll", PandoraScroll);
|
customElements.define("pandora-scroll", PandoraScroll);
|
||||||
|
customElements.define("pandora-item", PandoraItem);
|
||||||
|
customElements.define("pandora-edit", PandoraEdit);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function parseTime(value) {
|
|
||||||
return value.split(":").map(p => parseFloat(p)).reduce((c, p) => { return c*60 + p}, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
function isInside(config, annotation) {
|
|
||||||
if (!config['in'] && !config['out']) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (annotation['in'] < config['out'] && annotation['out'] > config['in']) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseIframeURL(value) {
|
function parseIframeURL(value) {
|
||||||
var config = {}
|
var config = {}
|
||||||
value = value.replace('/player/', '/')
|
value = value.replace('/player/', '/')
|
||||||
|
@ -114,7 +130,7 @@ function parseIframeURL(value) {
|
||||||
}
|
}
|
||||||
var args = data[1].replace('&', '&').split('&').map(kv => {
|
var args = data[1].replace('&', '&').split('&').map(kv => {
|
||||||
kv = kv.split('=')
|
kv = kv.split('=')
|
||||||
console.log(kv, decodeValue(kv[1]))
|
//console.log(kv, decodeValue(kv[1]))
|
||||||
return [kv[0], JSON.parse(decodeValue(kv[1]))]
|
return [kv[0], JSON.parse(decodeValue(kv[1]))]
|
||||||
}).reduce((k, v) => {
|
}).reduce((k, v) => {
|
||||||
k[v[0]] = v[1]
|
k[v[0]] = v[1]
|
||||||
|
|
138
app/static/js/utils.js
Normal file
138
app/static/js/utils.js
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
src = src.replace('.webm', videoExtension)
|
||||||
|
if (src != video.src) {
|
||||||
|
video.src = src
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function scrollTo(element) {
|
||||||
|
var delta = element.offsetTop - document.scrollingElement.scrollTop,
|
||||||
|
duration = 1000, t = 40, n = duration / t,
|
||||||
|
step = delta / n;
|
||||||
|
|
||||||
|
function scroll() {
|
||||||
|
if (document.scrollingElement.scrollTop + step > element.offsetTop) {
|
||||||
|
document.scrollingElement.scrollTop = element.offsetTop
|
||||||
|
n = 0
|
||||||
|
} else {
|
||||||
|
document.scrollingElement.scrollTop += step
|
||||||
|
}
|
||||||
|
n--
|
||||||
|
if (n) setTimeout(scroll, t)
|
||||||
|
}
|
||||||
|
scroll()
|
||||||
|
}
|
||||||
|
|
||||||
|
function showOverlay(event) {
|
||||||
|
console.log('show overlay', event.target, event)
|
||||||
|
event.stopPropagation()
|
||||||
|
event.preventDefault()
|
||||||
|
document.querySelectorAll('#video-overlay').forEach(element => element.remove())
|
||||||
|
var video = event.target
|
||||||
|
var rect = video.getBoundingClientRect();
|
||||||
|
if (video._frame) {
|
||||||
|
rect = video._frame.getBoundingClientRect();
|
||||||
|
}
|
||||||
|
var overlay = document.createElement('div')
|
||||||
|
overlay.id = 'video-overlay'
|
||||||
|
overlay.style.top = video.style.top
|
||||||
|
overlay.style.width = rect.width + 'px'
|
||||||
|
overlay.style.height = rect.height + 'px'
|
||||||
|
overlay.style.position = 'absolute'
|
||||||
|
overlay.style.display = 'flex'
|
||||||
|
overlay.style.alignItems = 'center'
|
||||||
|
overlay.style.justifyContent = 'center'
|
||||||
|
//overlay.style.fontSize = '45px'
|
||||||
|
video.controls = false
|
||||||
|
|
||||||
|
var off = `<span class="annotation-icon-wrapper animated"><span class="text f-icon-volume_off annotation-icon"></span>`
|
||||||
|
var on = `<span class="annotation-icon-wrapper"><span class="f-icon-volume_down annotation-icon"></span></span>`
|
||||||
|
|
||||||
|
if (video.muted) {
|
||||||
|
overlay.innerHTML = off
|
||||||
|
} else {
|
||||||
|
overlay.innerHTML = on
|
||||||
|
}
|
||||||
|
overlay.addEventListener('click', event=> {
|
||||||
|
const muted = video.muted
|
||||||
|
document.querySelectorAll('pandora-scroll').forEach(el => el.mute() )
|
||||||
|
video.muted = !muted
|
||||||
|
if (video.muted) {
|
||||||
|
overlay.innerHTML = off
|
||||||
|
} else {
|
||||||
|
overlay.innerHTML = on
|
||||||
|
}
|
||||||
|
})
|
||||||
|
var timeout = setTimeout(() => {
|
||||||
|
video.controls = false
|
||||||
|
overlay.remove()
|
||||||
|
}, 3000)
|
||||||
|
overlay.addEventListener('mousemove', event=> {
|
||||||
|
clearTimeout(timeout)
|
||||||
|
timeout = setTimeout(() => {
|
||||||
|
video.controls = false
|
||||||
|
overlay.remove()
|
||||||
|
}, 500)
|
||||||
|
})
|
||||||
|
video.parentElement.appendChild(overlay)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function isInside(config, annotation) {
|
||||||
|
if (!config['in'] && !config['out']) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (annotation['in'] < config['out'] && annotation['out'] > config['in']) {
|
||||||
|
annotation['in'] = Math.min(annotation['in'], config['in'])
|
||||||
|
annotation['out'] = Math.min(annotation['out'], config['out'])
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function isElementInViewport (el) {
|
||||||
|
var rect = el.getBoundingClientRect();
|
||||||
|
return (
|
||||||
|
rect.top >= 0 &&
|
||||||
|
rect.left >= 0 &&
|
||||||
|
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /* or $(window).height() */
|
||||||
|
Math.floor(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 (visible) {
|
||||||
|
el.classList.add('visible')
|
||||||
|
} else {
|
||||||
|
el.classList.remove('visible')
|
||||||
|
}
|
||||||
|
if (typeof callback == 'function') {
|
||||||
|
callback(visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseTime(value) {
|
||||||
|
return value.split(":").map(p => parseFloat(p)).reduce((c, p) => { return c*60 + p}, 0)
|
||||||
|
}
|
|
@ -33,6 +33,7 @@
|
||||||
{% if text.data.view == 'player' %}
|
{% if text.data.view == 'player' %}
|
||||||
<script src="/static/js/player.js?2021112223"></script>
|
<script src="/static/js/player.js?2021112223"></script>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
<script src="/static/js/utils.js?2021112223"></script>
|
||||||
<script src="/static/js/pandora-scroll.js?2021112223"></script>
|
<script src="/static/js/pandora-scroll.js?2021112223"></script>
|
||||||
<script src="/static/js/ascroll.js?2021112223"></script>
|
<script src="/static/js/ascroll.js?2021112223"></script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
Loading…
Reference in a new issue