Dziś mniej dywagacji, a trochę konkretów. Czyli jak dynamicznie dostosować w HTML rozmiar video do szerokości i wysokości ekranu.
W listopadzie pracowałam nad stroną rener.in i moim głównym zadaniem było poprawne wyświetlenie filmu – video miało zajmować cały ekran i dynamicznie dostosowywać się do zmiany szerokości ekranu (tzw. resize event). Nigdy wcześniej nie pracowałam z video w HTML-u, ale gdy zgłosili się do mnie sympatyczni panowie z Rener i przedstawili swoje oczekiwania, nie mogłam odmówić i nie skorzystać z wyzwania. Wzięłam się więc ochoczo do pracy.
W ruch poszedł Stack Overflow – jedno z moich ulubionych miejsc w sieci. Jak zgrabnie dostosować to video? (I jak je w ogóle wyświetlić???) Pomysłów było sporo, ale żaden mi nie odpowiadał. Jestem zwolenniczką prostych rozwiązań, a do tego perfekcjonistką, więc żaden zawiły lub prawie działający kod nie miał u mnie szans. Pozostała kartka papieru i długopis i powstało moje autorskie rozwiązanie. Działa tylko, jeśli znane są proporcje filmu – u mnie było to 16:9.
Najsampierw umieszczamy znacznik <video>
w kodzie strony:
<video id="video" playsinline muted onplaying="this.controls=false" autoplay loop> <source id="mp4" src="" type="video/mp4"> <source id="webm" src="" type="video/webm"> </video>
src
dla <source>
ustawiamy dynamicznie w JavaScript w zależności od szerokości ekranu.
I do dzieła!
window.addEventListener('resize', resize, false); function resize() { if (window.innerWidth != previous_width) { previous_width = window.innerWidth; var video = document.getElementById('video'); if (video) { var delta = 20; var window_width = window.innerWidth; var window_height = window.innerHeight; var width = window_width + delta; var height = width * 9 / 16; if (height < window_height) { height = window_height + delta; width = height * 16 / 9; } video.width = width; video.height = height; } } }
gdzie previous_width
jest ustawione na 0 przy załadowaniu strony (onLoad()
), a delta
to nasz bufor bezpieczeństwa, w razie gdyby dzielenie nie było całkowite.
Co tu się dzieje? Najpierw zakładamy, że szerokość ekranu jest większa niż jego wysokość i na jej podstawie obliczamy wysokość video (* 9 / 16
). Potem sprawdzamy, czy wyliczona wysokość jest mniejsza niż wysokość ekranu. Jeśli tak, przyjmujemy wysokość ekranu za wysokość video i na jej podstawie obliczamy szerokość.
Myślę, że jest to dość eleganckie i proste rozwiązanie, a do tego przetestowane w BrowserStack.
Kompletny przykład
Poniżej kompletny przykład, który można skopiować. Wystarczy podmienić ścieżki do plików i ewentualnie zmodyfikować wysokość elementu fullscreen-video
.
<div class="fullscreen-video"> <video id="video" playsinline muted onplaying="this.controls=false" autoplay loop> <source id="mp4" src="" type="video/mp4"> <source id="webm" src="" type="video/webm"> </video> </div> <style> .fullscreen-video {height: calc(100vh - 60px); width: 100%; overflow: hidden; position: relative;} .fullscreen-video video {object-fit: cover; position: absolute; top: 0; left: 0;} </style> <script> window.addEventListener('resize', resize, false); window.addEventListener('load', onLoad, false); function onLoad() { previous_width = 0; var video = document.getElementById('video'); var mp4video = document.getElementById('mp4'); var webmvideo = document.getElementById('webm'); if (video) { resize(); if (window.innerWidth < 576) { mp4video.src = "/wp-content/uploads/videos/film_small.mp4"; webmvideo.src = "/wp-content/uploads/videos/film_small.webm"; video.load(); } else if (window.innerWidth < 1200) { mp4video.src = "/wp-content/uploads/videos/film_medium.mp4"; webmvideo.src = "/wp-content/uploads/videos/film_medium.webm"; video.load(); } else { mp4video.src = "/wp-content/uploads/videos/film_medium.mp4"; webmvideo.src = "/wp-content/uploads/videos/film_big.webm"; video.load(); } } } function resize() { if (window.innerWidth != previous_width) { previous_width = window.innerWidth; var video = document.getElementById('video'); if (video) { var delta = 50; var window_width = window.innerWidth; var window_height = window.innerHeight; var width = window_width + delta; var height = width * 9 / 16; if (height < window_height) { height = window_height + delta; width = height * 16 / 9; } video.width = width; video.height = height; } } } var previous_width; </script>
Cześć, można to zastosować do strony opartej o WordPress? Próbuje zastosować to do Divi builder do modułu kod al e coś to nie działa.
Cześć Rafał, jasne, powinno zadziałać. Dodałam do wpisu kompletny przykład i możesz go wypróbować. Jeśli chcesz, żeby video zajmowało cały ekran, to kontener, w którym znajduje się video, też powinien być szerokości i wysokości ekranu.
Dziękuje bardzo za przykład. Teraz kod działa. Jednak on ma zastosowanie do innego przypadku niż myślałem. Czy da się zrobić tak aby były zachowane proporcie wideo? Mam wideo o rozdzielczości 1920×1080. Wideo nie musi być na całą szerokość strony ale żeby było na wysokość strony, a szerokość była obliczana zachowując proporcie wideo. Jeśli szerokość będzie mniejsza niż wysokość (smartfon) to wtedy wideo powinno być na pełną szerokość, a wysokość powinna być obliczana na podstawie szerokości zachowują proporcie wideo.
Ten przykład zachowuje proporcje dla filmu o proporcjach 16:9, więc powinien dla Ciebie działać. Musisz jednak zmodyfikować funkcję resize(), żeby działała dla Twojego konkretnego przypadku. Np. dla smartfonów video.width = window.innerWidth, a video.height = 9 * window.innerWidth / 16. Pokombinuj 🙂
Ok, dziękuje.
Pani Marto,
bardzo dziękuję, że udostępnia Pani skrypt. Dwa dni szukałam sensownego rozwiązania na wideo w tle strony 🙂
Pozdrawiam serdecznie – Małgorzata
Cieszę się, że mogłam pomóc 🙂 Pozdrawiam!