<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Videotube</title>
<link rel="stylesheet" href="css/index.css">
<link rel="stylesheet" href="videotube/videotube.min.css">
<script src="videotube/videotube.min.js"></script>
</head>
<body>
<main>
<div class="container">
<h1 class="title">Видео</h1>
<ul class="video__content">
<li>
<a href="https://youtu.be/C6cxWsTayAI" class="card__link tube">
<img src="https://i.ytimg.com/vi/C6cxWsTayAI/maxresdefault.jpg" alt="flex-basis, flex-grow, flex-shrink">
</a>
</li>
<li>
<a href="https://www.youtube.com/watch?v=yVR1VsRGsRs" class="card__link tube">
<img src="https://i.ytimg.com/vi/yVR1VsRGsRs/maxresdefault.jpg" alt="git и github">
</a>
</li>
<li>
<a href="https://youtu.be/Uy2li11PXC8" class="card__link tube">
<img src="https://i.ytimg.com/vi/Uy2li11PXC8/maxresdefault.jpg" alt="Топ-10 плагинов">
</a>
</li>
<li>
<a href="https://www.youtube.com/watch?v=0gYhRh6S4C4" class="card__link tube">
<img src="https://i.ytimg.com/vi/0gYhRh6S4C4/maxresdefault.jpg" alt="Основы HTML">
</a>
</li>
<li>
<a href="https://www.youtube.com/watch?v=g0RzCKhuA-E" class="card__link tube">
<img src="https://i.ytimg.com/vi/g0RzCKhuA-E/maxresdefault.jpg" alt="CurrentColor SVG">
</a>
</li>
<li>
<a href="https://www.youtube.com/watch?v=vKYmg2AR2xo" class="card__link tube">
<img src="https://i.ytimg.com/vi/vKYmg2AR2xo/maxresdefault.jpg" alt="Основы CSS">
</a>
</li>
<li>
<a href="https://youtu.be/Elnsd8TWCrA" class="card__link tube">
<img src="https://i.ytimg.com/vi/Elnsd8TWCrA/maxresdefault.jpg" alt="Модальное окно на JS">
</a>
</li>
<li>
<a href="https://www.youtube.com/watch?v=hAEs9SAr-ok" class="card__link tube">
<img src="https://i.ytimg.com/vi/hAEs9SAr-ok/maxresdefault.jpg" alt="Блокировка скролла">
</a>
</li>
<li>
<a href="https://youtu.be/o8KMucDpSno" class="card__link tube">
<img src="https://i.ytimg.com/vi/o8KMucDpSno/maxresdefault.jpg" alt="Webpack 5">
</a>
</li>
<li>
<a href="https://youtu.be/BrUayeSPBLc" class="card__link tube">
<img src="https://i.ytimg.com/vi/BrUayeSPBLc/maxresdefault.jpg" alt="Основы JS 1 часть из 5">
</a>
</li>
<li>
<a href="https://www.youtube.com/watch?v=1UP2dIYZXME" class="card__link tube">
<img src="https://i.ytimg.com/vi/1UP2dIYZXME/maxresdefault.jpg" alt="Верстка сайта Your Meal">
</a>
</li>
<li>
<a href="https://youtu.be/jYR9npaV2bg" class="card__link tube">
<img src="https://i.ytimg.com/vi/jYR9npaV2bg/maxresdefault.jpg" alt="Разрыв GAP для flexbox">
</a>
</li>
<li>
<a href="https://www.youtube.com/watch?v=LaJ6fKtz-cM" class="tube">
видео
</a>
</li>
</ul>
</div>
</main>
</body>
</html>
.videotube-modal-overlay {
color: #fff;
display: none;
z-index: 995;
opacity: 0;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
position: fixed;
background: #000;
text-align: center;
}
#videotube-modal-container {
z-index: 998;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
}
#videotube-modal {
text-align: center;
box-shadow: 0 0 40px #333;
}
#videotube-modal-loading {
position: fixed;
z-index: 997;
font-size: 1.5em;
top: 49%;
width: 5%;
text-align: center;
left: 45%;
}
#videotube-modal-close {
position: fixed;
right: 15px;
top: 15px;
padding: 3px 13px;
z-index: 999;
font-size: 25px;
text-shadow: 0 0 10px #fff;
border-radius: 3px;
cursor: pointer;
-webkit-transition-duration: 0.1s;
-o-transition-duration: 0.1s;
-moz-transition-duration: 0.1s;
transition-duration: 0.1s;
}
#videotube-modal-close:hover {
background: #333;
}
(() => {
const throttle = (type, name, obj) => {
obj = obj || window;
let running = false;
const func = function() {
if (running) {
return;
}
running = true;
requestAnimationFrame(function() {
obj.dispatchEvent(new CustomEvent(name));
running = false;
});
};
obj.addEventListener(type, func);
};
throttle("resize", "optimizedResize");
})();
((obj) => {
obj = obj || window;
obj.animation = function(elem, prop, cb) {
const count = prop.count;
let counter = 0
if (prop.start) {
prop.start.forEach(item => {
elem.style[item[0]] = item[1]
})
}
const allAnimation = [];
prop.anim.forEach(([style, from, to]) => {
const max = Math.max(from, to);
const min = Math.min(from, to);
const step = (max - min) / count;
allAnimation.push({style, from, to, step, reverse: min === to})
});
const rafAnimation = () => {
allAnimation.forEach((item) => {
if (item.reverse) {
item.from -= item.step
} else {
item.from += item.step
}
elem.style[item.style] = item.from;
})
counter++;
if (counter < count) {
requestAnimationFrame(rafAnimation);
} else {
if (prop.end) {
prop.end.forEach(item => {
elem.style[item[0]] = item[1]
})
}
if (cb) cb();
}
}
requestAnimationFrame(rafAnimation);
};
})();
const init = () => {
const overlay = document.createElement('div');
overlay.className = 'videotube-modal-overlay'
document.body.insertAdjacentElement('beforeend', overlay);
const video = document.createElement('div');
video.id = 'videotube-modal-container'
const sizeBlockList = [
[3840, 2160],
[2560, 1440],
[1920, 1080],
[1280, 720],
[854, 420],
[640, 360],
[426, 240]
];
const sizeVideo = () => {
const sizeBlock = sizeBlockList.find(item => item[0] < window.visualViewport.width) ||
sizeBlockList[sizeBlockList.length - 1];
const iframe = document.getElementById('videotube-modal');
iframe.width = sizeBlock[0];
iframe.height = sizeBlock[1];
video.style.cssText = `
width: ${sizeBlock[0]};
height: ${sizeBlock[1]};
`;
}
const sizeContainer = () => {
const wh = window.visualViewport.height;
const ww = window.visualViewport.width;
const fw = video.style.width;
const fh = video.style.height;
video.style.left = (ww - fw) / 2;
video.style.top = (wh - fh) / 2;
overlay.style.height = document.documentElement.clientHeight;
}
const sizeVideoTubeModal = () => {
sizeContainer();
sizeVideo();
}
const closeVideoTubeModal = () => {
animation(overlay, {
end: [['display', 'none']],
anim: [['opacity', 1, 0]],
count: 20,
},
() => {
overlay.textContent = "";
}
);
window.removeEventListener("optimizedResize", sizeVideoTubeModal);
document.removeEventListener('keyup', closeContainerEsc);
}
const closeContainerEsc = e => {
if (e.keyCode === 27) {
closeVideoTubeModal();
}
}
const openVideoTubeModal = e => {
const target = e.target.closest('.tube');
if (!target) return;
const href = target.href;
const search = href.includes('youtube');
let idVideo = search ? href.match(/(\?|&)v=([^&]+)/)[2] : href.match(/(\.be\/)([^&]+)/)[2];
if (idVideo.length === 0) return;
e.preventDefault();
animation(overlay, {
start: [['display', 'block']],
anim: [['opacity', 0, 1]],
count: 20,
}
);
overlay.insertAdjacentHTML('beforeend', `
<div id="videotube-modal-loading">Загрузка...</div>
<div id="videotube-modal-close">✖</div>
<div id="videotube-modal-container">
<iframe src="https://youtube.com/embed/${idVideo}?autoplay=1"
frameborder="0"
id="videotube-modal"
allowfullscreen
allow="autoplay">
</iframe>
</div>
`)
sizeVideo();
sizeContainer();
window.addEventListener("optimizedResize", sizeVideoTubeModal);
document.addEventListener('keyup', closeContainerEsc);
}
;
overlay.addEventListener("click", closeVideoTubeModal);
document.addEventListener('click', openVideoTubeModal)
}
document.addEventListener('DOMContentLoaded', init)
<iframe src="https://youtube.com/embed/${idVideo}?autoplay=1"
frameborder="0"
id="videotube-modal"
allowfullscreen
allow="autoplay">
</iframe>
<iframe src="https://youtube.com/embed/${idVideo}?autoplay=1&mute=1"
frameborder="0"
id="videotube-modal"
allowfullscreen
allow="autoplay">
</iframe>