3 stycznia 2020

HTML i dynamiczne dostosowanie rozmiaru video do szerokości i wysokości ekranu

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.

A na koniec:

Złota myśl pani Marty

W programowaniu (prawie) nie ma rzeczy niemożliwych.