Note: Transition is not good in IE
<!-- video section -->
<div class="video-section" data-toggle-video-modal>
<div data-iframe-id="ahCwqrYpIuM"></div>
<img src="https://picsum.photos/id/1021/2048/1206" alt="video-img" />
<svg class="video-section__icon" style="enable-background:new 0 0 512 512;" version="1.1" viewBox="0 0 512 512" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M405.2,232.9L126.8,67.2c-3.4-2-6.9-3.2-10.9-3.2c-10.9,0-19.8,9-19.8,20H96v344h0.1c0,11,8.9,20,19.8,20 c4.1,0,7.5-1.4,11.2-3.4l278.1-165.5c6.6-5.5,10.8-13.8,10.8-23.1C416,246.7,411.8,238.5,405.2,232.9z" /></svg>
</div>
<!-- video modal -->
<div class="video-modal" data-video-modal>
<div class="video-modal__backdrop" data-video-modal-close></div>
<div class="video-modal__close" data-video-modal-close>
<svg class="video-modal__close-icon" enable-background="new 0 0 357 357" version="1.1" viewBox="0 0 357 357" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<polygon points="357 35.7 321.3 0 178.5 142.8 35.7 0 0 35.7 142.8 178.5 0 321.3 35.7 357 178.5 214.2 321.3 357 357 321.3 214.2 178.5" />
</svg>
</div>
<div class="video-modal__content-wrap">
<div class="video-modal__video-wrap-backdrop"></div>
<div class="video-modal__video-wrap" data-video-modal-content>
<div class="video-modal__error-message" data-video-modal-error>
<span class="video-modal__error-message-text">No media found</span>
</div>
</div>
</div>
</div>
// local var
$modal-height: 80vh;
$modal-width: 80vw;
$modal-height--devices: 40vh;
$modal-width--devices: 90vw;
// video section
.video-section {
position: relative;
cursor: pointer;
overflow: hidden;
margin-bottom: 1.8rem;
// video section backdrop
&:after {
content: "";
background-color: $color-black;
@include position-all-sides;
opacity: .4;
transition: opacity $transition;
}
// img
img {
min-width: 100%;
display: block;
transform: scale(1.01);
transition: transform $transition;
}
// icon
&__icon {
@include position-center;
width: 6rem;
height: 6rem;
z-index: 1;
fill: $color-white;
transition: transform $transition;
}
}
// hide ifram id
[data-iframe-id] {
display: none;
}
// video section hover transition
.video-section:hover {
img {
transform: scale(1.08);
}
&:after {
opacity: 0;
}
.video-section__icon {
transform: scale(1.2) translate(-50%,-50%);
}
}
// video modal
.video-modal {
@include position-all-sides;
position: fixed;
overflow: hidden;
opacity: 0;
pointer-events: none;
transition: opacity $transition--slow;
transition-delay: .6s;
z-index: 5;
// backdrop
&__backdrop {
cursor: pointer;
position: relative;
height: 100%;
width: 100%;
background-color: rgba($color-black, .7);
z-index: 5;
}
// close icon
&__close {
position: absolute;
top: 0;
right: 0;
background-color: $color-white;
padding: 1.6rem 4rem;
cursor: pointer;
z-index: 5;
transform: translate3d(0,-100%,0);
visibility: hidden;
transition: $transition--slow;
transition-delay: .4s;
}
// close hover effect
&__close:hover {
.video-modal__close-icon {
transform: rotate(180deg);
}
}
&__close-icon {
fill: $color-black;
height: 1.4rem;
width: 1.4rem;
transition: transform $transition;
}
//content wrap
&__content-wrap, &__video-wrap {
position: absolute;
z-index: 6;
}
&__content-wrap {
height: $modal-height;
width: $modal-width;
top: (100 - $modal-height) / 2;
left: (100 - $modal-width) / 2;
overflow: hidden;
}
// video wrap
&__video-wrap {
height: 100%;
width: 100%;
}
&__video-wrap iframe {
position: relative;
z-index: 5;
height: $modal-height;
width: $modal-width;
background-color: $color-black;
}
// video wrap background
&__video-wrap-backdrop {
@include position-all-sides;
z-index: 7;
background-color: $color-black;
opacity: 1;
transition: opacity $transition;
transition-delay: .6s;
}
}
// video modal transition
.video-modal.is-active {
opacity: 1;
transition-delay: 0s;
pointer-events: initial;
.video-modal__close {
transform: translate3d(0,0,0);
transition-delay: .2s;
visibility: visible;
}
.video-modal__video-wrap-backdrop {
transition-delay: .5s;
opacity: 0;
}
}
// video error message
.video-modal {
&__error-message {
@include position-center;
visibility: hidden;
opacity: 0;
transition: $transition;
text-align: center;
}
&__error-message-text {
font-size: 5rem;
color: $color-white;
}
}
// video error active
.video-modal__error-message.is-active {
visibility: visible;
opacity: 1;
}
@include viewport-large {
.video-section {
&:after {
opacity: 1;
}
img {
transform: none;
}
}
}
@include viewport-medium {
// video error message
.video-modal {
&__error-message-text {
font-size: 2.6rem;
}
}
}
@include viewport-small {
// video section
.video-section {
margin-bottom: 1rem;
&__icon {
width: 8rem;
height: 8rem;
}
&__icon-item {
width: 1.5rem;
height: 1.4rem;
}
}
// video modal
.video-modal {
transition-delay: 1s;
&__content-wrap {
height: $modal-height--devices;
width: $modal-width--devices;
top: (100 - $modal-height--devices) /2;
left: (100 - $modal-width--devices) /2;
}
&__video-wrap iframe {
height: $modal-height--devices;
width: $modal-width--devices;
}
}
}
export class videoModalModule {
videoModalToggle: NodeList = document.querySelectorAll("[data-toggle-video-modal]");
videoModalToggleArray: Array< HTMLElement> = Array.prototype.slice.call(this.videoModalToggle);
videoModal: HTMLElement = document.querySelector("[data-video-modal]");
videoModalClose: NodeList = document.querySelectorAll("[data-video-modal-close]");
videoModalCloseArray: Array< HTMLElement> = Array.prototype.slice.call(this.videoModalClose);
videoModalError: HTMLElement = document.querySelector("[data-video-modal-error]");
videoModalContent: HTMLElement = document.querySelector("[data-video-modal-content]");
activeClass: string = "is-active";
constructor() {
this.appendUrl();
this.toggleModal();
}
// append url to modal
private appendUrl = () => {
this.videoModalToggleArray.forEach((elem) => {
elem.addEventListener("click", () => {
let targetIframe: string = elem.firstElementChild.getAttribute("data-iframe-id");
if (targetIframe !== '') {
this.videoModalContent.innerHTML = '< iframe class="iframe-item" src="https://www.youtube.com/embed/' + targetIframe + '?autoplay=1' + '" frameborder="0" allowfullscreen="" allow="accelerometer; autoplay">< /iframe>';
} else {
this.videoModalError.classList.add(this.activeClass);
}
})
});
}
private toggleModal = () => {
// open modal
this.videoModalToggleArray.forEach((elem) => {
elem.addEventListener("click", () => {
this.videoModal.classList.add(this.activeClass);
})
});
// close modal
let closeModal = () => {
this.videoModal.classList.remove(this.activeClass);
// clear iframe, so it dosent run in background
setTimeout(() => {
document.querySelector(".iframe-item").removeAttribute("src");
}, 1200);
}
this.videoModalCloseArray.forEach(elem => elem.addEventListener("click", closeModal));
}
}