feat(MediaModal): add navigation between medias
This commit is contained in:
parent
a8bed7c7de
commit
d29d1a0212
3 changed files with 152 additions and 45 deletions
|
@ -49,8 +49,6 @@ if (description !== null) {
|
||||||
/**
|
/**
|
||||||
* Gallery modal to view media in large
|
* Gallery modal to view media in large
|
||||||
*/
|
*/
|
||||||
let mediaModal = document.querySelector('#media-modal')
|
|
||||||
let mediaModalContent = document.querySelector('#media-modal-content')
|
|
||||||
// let mediaModalImage = document.querySelector('#media-modal img')
|
// let mediaModalImage = document.querySelector('#media-modal img')
|
||||||
// let mediaModalVideo = document.querySelector('#media-modal video')
|
// let mediaModalVideo = document.querySelector('#media-modal video')
|
||||||
// let mediaModalSource = document.querySelector('#media-modal video source')
|
// let mediaModalSource = document.querySelector('#media-modal video source')
|
||||||
|
@ -66,26 +64,72 @@ let mediaModalContent = document.querySelector('#media-modal-content')
|
||||||
// };
|
// };
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// function enableScroll() {
|
// function enableScroll() {
|
||||||
// window.onscroll = function() {};
|
// window.onscroll = function() {};
|
||||||
// }
|
// }
|
||||||
|
let mediaModal = document.querySelector('#media-modal')
|
||||||
|
let mediaModalContent = document.querySelector('#media-modal-content')
|
||||||
|
let navLeft = document.getElementById('media-nav-left')
|
||||||
|
let navRight = document.getElementById('media-nav-right')
|
||||||
|
|
||||||
|
let currentMedia = {}
|
||||||
|
let mediaData = []
|
||||||
|
|
||||||
let openModal = (url, isVideo) => {
|
let loadMedias = () => {
|
||||||
|
let list = document.querySelectorAll('.media-container')
|
||||||
|
//console.log(list)
|
||||||
|
list.forEach(m => {
|
||||||
|
mediaData.push({
|
||||||
|
isVideo: m.getAttribute('data-video') == 'true',
|
||||||
|
location: m.getAttribute('data-location')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
loadMedias()
|
||||||
|
|
||||||
|
let openModal = (index) => {
|
||||||
mediaModal.style.visibility = 'visible'
|
mediaModal.style.visibility = 'visible'
|
||||||
mediaModal.style.opacity = 1
|
mediaModal.style.opacity = 1
|
||||||
mediaModalContent.innerHTML = ""
|
|
||||||
|
currentMedia = mediaData[index]
|
||||||
|
fillModal(currentMedia)
|
||||||
|
|
||||||
|
//document.body.style.height = '100vh'
|
||||||
|
document.body.style.overflow = 'hidden'
|
||||||
|
document.body.style.userSelect = 'none'
|
||||||
|
document.body.style.touchAction = 'none'
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const outsideClickListener = event => {
|
||||||
|
if (
|
||||||
|
!mediaModalContent.contains(event.target) && isVisible(mediaModalContent) &&
|
||||||
|
navLeft.querySelector(':hover') === null &&
|
||||||
|
navRight.querySelector(':hover') === null
|
||||||
|
) {
|
||||||
|
closeModal()
|
||||||
|
document.removeEventListener('click', outsideClickListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('click', outsideClickListener)
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isVisible = elem => !!elem && !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length )
|
||||||
|
|
||||||
|
let fillModal = () => {
|
||||||
|
console.log(currentMedia)
|
||||||
|
mediaModalContent.innerHTML = ""
|
||||||
let attr = document.createAttribute('src')
|
let attr = document.createAttribute('src')
|
||||||
attr.value = url
|
attr.value = currentMedia.location
|
||||||
let el = null
|
let el = null
|
||||||
if (isVideo) {
|
if (currentMedia.isVideo) {
|
||||||
el = document.createElement('video')
|
el = document.createElement('video')
|
||||||
el.setAttribute('controls', '')
|
el.setAttribute('controls', '')
|
||||||
el.setAttribute('autoplay', '')
|
el.setAttribute('autoplay', '')
|
||||||
el.setAttribute('name', 'media')
|
el.setAttribute('name', 'media')
|
||||||
let source = document.createElement('source')
|
let source = document.createElement('source')
|
||||||
source.setAttribute('src', url)
|
source.setAttribute('src', currentMedia.location)
|
||||||
source.setAttribute('type', 'video/mp4')
|
source.setAttribute('type', 'video/mp4')
|
||||||
el.appendChild(source)
|
el.appendChild(source)
|
||||||
} else {
|
} else {
|
||||||
|
@ -93,42 +137,48 @@ let openModal = (url, isVideo) => {
|
||||||
el.attributes.setNamedItem(attr)
|
el.attributes.setNamedItem(attr)
|
||||||
}
|
}
|
||||||
mediaModalContent.appendChild(el)
|
mediaModalContent.appendChild(el)
|
||||||
//document.body.style.height = '100vh'
|
|
||||||
document.body.style.overflow = 'hidden'
|
|
||||||
document.body.style.touchAction = 'none'
|
|
||||||
|
|
||||||
setTimeout(() => {
|
if (mediaData.indexOf(currentMedia) === 0) {
|
||||||
|
navLeft.className += ' disabled'
|
||||||
|
} else {
|
||||||
|
navLeft.className = navLeft.className.replace('disabled', '')
|
||||||
|
}
|
||||||
|
|
||||||
const outsideClickListener = event => {
|
if (mediaData.indexOf(currentMedia) + 1 === mediaData.length) {
|
||||||
if (!mediaModalContent.contains(event.target) && isVisible(mediaModalContent)) {
|
navRight.className += ' disabled'
|
||||||
closeModal()
|
} else {
|
||||||
document.removeEventListener('click', outsideClickListener)
|
navRight.className = navRight.className.replace('disabled', '')
|
||||||
}
|
}
|
||||||
}
|
|
||||||
document.addEventListener('click', outsideClickListener)
|
|
||||||
|
|
||||||
}, 100)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const isVisible = elem => !!elem && !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length )
|
|
||||||
|
|
||||||
let closeModal = () => {
|
let closeModal = () => {
|
||||||
mediaModal.style.visibility = 'hidden'
|
mediaModal.style.visibility = 'hidden'
|
||||||
mediaModal.style.opacity = 0
|
mediaModal.style.opacity = 0
|
||||||
document.body.style.overflow = 'initial'
|
document.body.style.overflow = 'initial'
|
||||||
document.body.style.height = 'initial'
|
document.body.style.height = 'initial'
|
||||||
document.body.style.touchAction = 'initial'
|
document.body.style.touchAction = 'initial'
|
||||||
|
document.body.style.userSelect = 'initial'
|
||||||
let video = document.querySelector('#media-modal video')
|
let video = document.querySelector('#media-modal video')
|
||||||
if (video !== null) {
|
if (video !== null) {
|
||||||
video.pause()
|
video.pause()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
navLeft.onclick = () => {
|
||||||
|
if (mediaData.indexOf(currentMedia) === 0) { return; }
|
||||||
|
currentMedia = mediaData[mediaData.indexOf(currentMedia) - 1]
|
||||||
|
fillModal()
|
||||||
|
}
|
||||||
|
|
||||||
|
navRight.onclick = () => {
|
||||||
|
if (mediaData.indexOf(currentMedia) + 1 === mediaData.length) { return; }
|
||||||
|
currentMedia = mediaData[mediaData.indexOf(currentMedia) + 1]
|
||||||
|
fillModal()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode things
|
* Decode things
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let formatPhone = (phone) => {
|
let formatPhone = (phone) => {
|
||||||
if (phone.indexOf('+33') === 0) {
|
if (phone.indexOf('+33') === 0) {
|
||||||
phone = '0' + phone.substr(3)
|
phone = '0' + phone.substr(3)
|
||||||
|
|
|
@ -275,6 +275,49 @@
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.media-nav {
|
||||||
|
position: absolute;
|
||||||
|
width: .5em;
|
||||||
|
color: white;
|
||||||
|
opacity: 0.8;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1.25em;
|
||||||
|
transition: 0.2s all;
|
||||||
|
z-index: 9999;
|
||||||
|
width: 5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-nav.disabled {
|
||||||
|
opacity: 0.25 !important;
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-nav-btn svg {
|
||||||
|
height: 2em;
|
||||||
|
filter: drop-shadow(2px 4px 6px black);
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-nav-btn {
|
||||||
|
padding: 2em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-nav:hover {
|
||||||
|
opacity: 1;
|
||||||
|
transition: 0.2s all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-nav-left {
|
||||||
|
left: 2em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-nav-right {
|
||||||
|
right: 2em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************************************************
|
/* *****************************************************************************
|
||||||
|
|
||||||
* SECTION
|
* SECTION
|
||||||
|
@ -764,6 +807,17 @@ RESPONSIVE
|
||||||
height: 33em;
|
height: 33em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MODAL
|
||||||
|
**/
|
||||||
|
.media-nav {
|
||||||
|
bottom: 0em;
|
||||||
|
}
|
||||||
|
.media-nav-btn {
|
||||||
|
padding-top: 1em;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MOSAIC CASES
|
* MOSAIC CASES
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -48,7 +48,11 @@
|
||||||
{% if data.gallery|length > 0 %}
|
{% if data.gallery|length > 0 %}
|
||||||
<div class="media-mosaic mosaic-{{ data.gallery|length }}">
|
<div class="media-mosaic mosaic-{{ data.gallery|length }}">
|
||||||
{% for media in data.gallery %}
|
{% for media in data.gallery %}
|
||||||
<div class="media-container" onclick="openModal('{{ media.location }}', {{ media.isVideo }})">
|
<div
|
||||||
|
class="media-container"
|
||||||
|
data-video="{{ media.isVideo }}"
|
||||||
|
data-location="{{ media.location }}"
|
||||||
|
onclick="openModal({{ loop.index - 1 }})">
|
||||||
<div
|
<div
|
||||||
class="media {% if media.isVideo %}media-video-bg{% endif %}"
|
class="media {% if media.isVideo %}media-video-bg{% endif %}"
|
||||||
{% if not media.isVideo %}style="background-image: url({{ media.location }})"{% endif %}></div>
|
{% if not media.isVideo %}style="background-image: url({{ media.location }})"{% endif %}></div>
|
||||||
|
@ -65,7 +69,6 @@
|
||||||
<div class="media-modal-container" id="media-modal">
|
<div class="media-modal-container" id="media-modal">
|
||||||
<div class="media-modal">
|
<div class="media-modal">
|
||||||
<div class="media-modal-content" id="media-modal-content">
|
<div class="media-modal-content" id="media-modal-content">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="media-close" onclick="closeModal()">
|
<div class="media-close" onclick="closeModal()">
|
||||||
<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||||
|
@ -73,6 +76,21 @@
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
id="media-nav-left"
|
||||||
|
class="media-nav-left media-nav">
|
||||||
|
<div class="media-nav-btn">
|
||||||
|
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-left" class="svg-inline--fa fa-chevron-left fa-w-10" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path fill="currentColor" d="M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z"></path></svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="media-nav-right"
|
||||||
|
class="media-nav-right media-nav">
|
||||||
|
<div class="media-nav-btn">
|
||||||
|
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-right" class="svg-inline--fa fa-chevron-right fa-w-10" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path fill="currentColor" d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"></path></svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
@ -326,7 +344,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="contact-content">
|
<div class="contact-content">
|
||||||
<a href="{{ data.contacts.website|e }}">
|
<a href="{{ data.contacts.website|e }}">
|
||||||
{{ data.contacts.websiteLabel|e }}
|
Site Web
|
||||||
<svg class="external-link" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
<svg class="external-link" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
||||||
<path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path>
|
<path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -343,12 +361,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="contact-content">
|
<div class="contact-content">
|
||||||
<a href="{{ data.contacts.facebook|e }}">
|
<a href="{{ data.contacts.facebook|e }}">
|
||||||
<span class="short">
|
Page Facebook
|
||||||
{{ data.contacts.facebookLabel|e }}
|
|
||||||
</span>
|
|
||||||
<span class="long">
|
|
||||||
{{ data.contacts.facebook|e }}
|
|
||||||
</span>
|
|
||||||
<svg class="external-link" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
<svg class="external-link" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
||||||
<path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path>
|
<path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -365,12 +378,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="contact-content">
|
<div class="contact-content">
|
||||||
<a href="{{ data.contacts.instagram|e }}">
|
<a href="{{ data.contacts.instagram|e }}">
|
||||||
<span class="short">
|
Profil Instagram
|
||||||
{{ data.contacts.instagramLabel|e }}
|
|
||||||
</span>
|
|
||||||
<span class="long">
|
|
||||||
{{ data.contacts.instagram|e }}
|
|
||||||
</span>
|
|
||||||
<svg class="external-link" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
<svg class="external-link" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
||||||
<path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path>
|
<path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -387,12 +395,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="contact-content">
|
<div class="contact-content">
|
||||||
<a href="{{ data.contacts.twitter|e }}">
|
<a href="{{ data.contacts.twitter|e }}">
|
||||||
<span class="short">
|
Profil Twitter
|
||||||
{{ data.contacts.twitterLabel|e }}
|
|
||||||
</span>
|
|
||||||
<span class="long">
|
|
||||||
{{ data.contacts.twitter|e }}
|
|
||||||
</span>
|
|
||||||
<svg class="external-link" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
<svg class="external-link" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
||||||
<path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path>
|
<path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Loading…
Reference in a new issue