[#1] iframe. No już ku*&$#wa nie wiem...! %|
robię sobie od kilku tygodni player do filmów z Teto. Bo jutub mnie wkurza swoim zamulaniem przez pierdylion zbędnych dupereli. Tak, wiem - są do tego zewnętrzne apki itp., dużo prościej, szybciej i wygodniej, no ale ja mam ambicję.

player opiera się na odpicowanej galerii Coppermine, którą zainstalowałem sobie już dawno temu i teraz robię z niej użytek. Można do niej dodawać sobie m.in. jutubowe filmiki, które ładowane są standardowo w iframe'ie.
Tak sobie umyśliłem, że player ma mi ładnie skalować ajfrejma wraz ze zmianą rozmiaru okna, a do tego w okienku zawsze ma być widoczny cały filmik. To ostatnie realizowane jest w javascripcie przez każdorazowy .click na <a hrefie> umiejscowionym nad ajfrejmem. No i przedwczoraj, jak sądziłem i jak widać na zarejestrowanym wówczas filmiku, udało mi się doprowadzić całość już do postaci zadowalającej, gdzie jedyną większą niedogodnością było "niewyrabianie się" w niektórych sytuacjach, widoczne około 2:40 - tak jakby ajfrejm nie zdążył zmienić rozmiaru:




niestety cały zbudowany przez kilka dni mechanizm chociaż działał, miał postać kilkusetlinijkowego śmietnika opartego na rozgałęzieniach ifów i różnych zmiennych o nazwach zd*py, w którym połowę stanowiły skomentowane linijki. Nadszedł więc czas na posprzątanie tego bałaganu, a przy okazji nadanie całośći bardziej czytelnej postaci. Tak też później uczyniłem - robiąc przezornie backup odpowiednich plików.
I w tym miejscu coś *ebło, gdyż od tamtej chwili co bym nie robił, to efekt jest taki jak poniżej. Czyt.: działać - działa, ale muli przy tym jak cholera. Konkretnie mulić wydaje się ów wspomniany na początku .click, bo jeśli wyłączę go z kodu - samo skalowanie wychodzi w miarę płynnie, bez tych uciążliwych przeskoków (co zresztą widać na pierwszym filmiku).



i ni wuja nie mam pojęcia, co jest nie tak, bo po przywróceniu zapisanych w backupie .js i stylów.css (tak na wszelki wypadek) muli to tak samo! Raczej wykluczam tę ewentualność, że backup jednak nie zawiera odpowiedniej wersji... Pliki w nim datowane są na przedwczoraj:
displayimage.js - 15:16
style.css - 13:26
a przedwczorajszy filmik został nagrany o 16:00. Biorąc pod uwagę, że w międzyczasie trzeba było wyjąć z szafy i rozstawić statyw oraz ustawić wszystkie srajfonowe pierdółki - wątpię, by w międzyczasie zostały wprowadzone istotne zmiany, których nie zbackupowałem.

Pytanie zatem brzmi: co tu, do kurki wodnej, może być źle, że tak po dodaniu tego .clicka cholernie tnie i nie chce przestać???!! %| A może jednak skalowanie ajfrejma robię źle? Pamiętam, że dawno temu borykałem się z podobnym zagadnieniem i gdzieś po głowie mi się obija, że ajfrejmów nie należy skalować bezpośrednio, tylko przez... no właśnie - nie pamiętam przez co. Te css-y typu fit-content, min-height itp. średnio ogarniam, a coś mi świta, że nimi właśnie trzeba się posługiwać, zamiast ustawiać za każdym krokiem inną wysokość i szerokość, nadając odpowiednie wartości odpowiednim divom czy czemuś tam (zauważyłem np., że w sytuacji, gdy iframe ma zajmować pełną dostępną szerokość, width:100% działa szybciej niż zapisanie do niego określonej liczby pikseli - mimo że to 100% też jest każdorazowo zapisywane...).
uprzedzając: nie, nie mam zapchanej pamięci ani obciążonego ponad miarę CPU czy GPU.

obecnie funkcja skalująca wygląda tak:

function setYTdim() {
    let vidRatio = $('.iframe_res').html();
    let resize_element = 'youtube';
    let fs_visible = $('.filmstrip_roll_VERT').css('visibility');
    if ($('iframe').length == 0) { resize_element = 'picture'; }
    let new_w;
    let new_h;
    let avail_h;
    if (resize_element == 'youtube') {
	    avail_h = $(window).height() - 10;
	    new_h = $('.display_media').height() - 10;
	    new_w = new_h * vidRatio;
	    if (fs_visible == 'visible') {
		if (new_w > $('.maintable_mm').width() - 228) {
		    new_w = $('.maintable_mm').width() - 228;
		    new_h = new_w / vidRatio;
		    $('iframe').width('100%');
		}
		if (new_h > avail_h) {
		    new_h = avail_h;
		    new_w = new_h * vidRatio;
		    $('iframe').width(new_w);		    
		}
	    }
	    else {
		...
	    }
	    $('iframe').height(new_h);
	    $('#top_iframe')[0].click()	    
    }
}


(.maintable_mm to klasa tabelki, w której mieści się player, a .display_media - obszar do wykorzystania w tej tabelce przez player; fs_visible określa tylko, czy pasek z listą filmików z prawej strony jest wysunięty, czy schowany, natomiast po jego schowaniu mulenie nie ustępuje ani nie maleje, więc ten fragment wyciąłem, jako zbędny).

i wywoływana jest w:
$(window).on("resize",function() {
    setYTdim();
});



dopuszczam jeszcze możliwość, że po drodze schrzaniłem coś edytując te wszystkie html-e i css-y, dodając czy odejmując któremuś elementowi coś istotnego, skoro samo określenie width w pikselach zamiast procentach też potrafi zauważalnie przymulić.

P.S. zamiast tych każdorazowych letów pewnie odpowiedniej byłoby zastosować jedno const poza funkcją, no ale jak wspomniałem - wcześniej śmietnik był milion razy większy, a działało to płynniej.

============================================================

/edit
znalazłem sposób bardziej "dzisiejszy" na resize ifrejma. Tj. dodanie display: flex oraz justify-content: center itp. nadrzędnemu divowi. Pomału staram się przebudować całość idąc w tę mańkę - tyle że nadal nie eliminuje to zacinania przy zmianie rozmiaru okna, kiedy dodamy .click. :/ Podejrzewam, że nie powinno to dziwić wobec takiego clickania po tysiąc razy na milisekundę... I pewnie jest cywilizowany sposób, by wykonywać je w określonych interwałach czasowych. Tyle że nadal nie tłumaczy to, czemu przedwczoraj tych przycięć nie było.

Ostatnia aktualizacja: 26.02.2024 18:07:03 przez snajper
[#2] Re: iframe. No już ku*&$#wa nie wiem...! %|

@snajper, post #1

update: przerobiłem już całość na te flexy, z grubsza to działa, aczkolwiek po dodaniu .click tnie nadal.
Przy okazji mam jednak pytanie bonusowe: wcześniej już dorobiłem taki bajer, że po schowaniu filmstripa i kliknięciu w widoczny przez chwilę pusty obszar po nim odgrywany jest dźwięk, jak widać na poniższym filmiku. Z tym że w założeniu ma on być odtwarzany tylko jeśli kursor wceluje w Teto, która tam na górze lub z boku widnieje. I nie wiem, w jaki sposób można by to zrealizować. Pewnie byłoby prosto, gdyby Teto stanowiła osobny <img>, ale niestety nie stanowi, bo jest częścią tła. Da się jakoś odczytać pozycję kursora względem określonego elementu podczas kliknięcia?



Ostatnia aktualizacja: 26.02.2024 23:53:10 przez snajper
[#3] Re: iframe. No już ku*&$#wa nie wiem...! %|

@snajper, post #2

no i główny problem rozwiązany. Tak jak myślałem - klikanie w href to NIE jest najwłaściwszy sposób na przesuwanie strony o określony obszar. Do tego celu służą stosowne funkcje. Teraz działa płynniutko. OK



a tak wygląda stosowny fragment kodu:

function inViewport($el) {
    var elH = $el.outerHeight(),
        H   = $(window).height(),
        r   = $el[0].getBoundingClientRect(), t=r.top, b=r.bottom;
    return Math.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H));
}

function scrollToVid(distance) {
    var ifr_Top = $('iframe').offset().top;
    var page_Top = $(window).scrollTop();
    if (ifr_Top < page_Top) $(window).scrollTop(ifr_Top-distance);
    else $(window).scrollTop(ifr_Top+distance);
}


ta pierwsza wzięta ze stackoverflow, zwraca wysokość wyświetlanego obszaru elementu.

a tak wygląda obecna główna funkcja skalująca:

function setYTdim2() {
    let fs_visible = $('.filmstrip_roll_VERT').css('visibility');
    let disp = $('.display_media');
    let dispHeight = inViewport($('.display_media'));
    let vidRatio = $('.iframe_res').html();
    let dispWidth;
    if (fs_visible == 'visible') { dispWidth = $('.maintable_mm').width() - 228; }
    else { dispWidth = $('.maintable_mm').width() - 30; }

    let dispRatio = dispWidth / dispHeight;
    let new_w;
    let new_h;

    if (dispRatio > vidRatio) {
	new_h = dispHeight - 30;
	new_w = new_h * vidRatio;
    }
    else {
	new_w = dispWidth;
	new_h = new_w / vidRatio;
        if (new_h > inViewport($('.display_media'))) {
    	    new_h = inViewport($('.display_media'));
	    new_w = new_h * ifr_ratio;
	}
    }

    
    $('#display_div').width(new_w);
    $('#display_div').height(new_h);

    var scrollBy = $('iframe').height() - inViewport($('iframe'));
    if (scrollBy > 0) {
	scrollToVid(scrollBy);
    }
}


jak widać, uwzględnia też proporcje filmiku, które ustalane są na podstawie miniaturki. Aczkolwiek tego ficzera jeszcze nie testowałem. Pewnie da się ją jeszcze uprościć, no ale tym zajmę się później. Jak również widać, przy okazji przejścia na divy z flexami zmieniłem też sposób skalowania filmiku - zamiast operować na iframe, dałem mu width i height na 100%, a rozmiar zmieniany jest divowi, w który jest zapakowany.

Ostatnia aktualizacja: 27.02.2024 02:31:50 przez snajper
[#4] Re: iframe. No już ku*&$#wa nie wiem...! %|

@snajper, post #3

tak się pochwalę postępami.
Siedziałem nad tym od 5 rano, zgłębiając tajniki XMLHttpRequesta, po kilku dniach rozkminiania 500-linijkowego jQuery do XHR aplołdów z chunking supportem. %| A na koniec tworzenia blobów i file'ów (bo blob "to je amelinum" i takiego bezimiennego tworu Coppermine nie łyknie). Słowem wyjaśnienia: w wersji out-of-the-box galeria umożliwia, poza obrazkami, upload filmików. Po dodaniu pluginu umożliwia też publikowanie jutubów, tyle że w sposób mega badziewny, tj. żeby dodać sobie filmik do galerii, należy:
a) utworzyć plik tekstowy z wklejonym adresem filmiku
b) przesłać tak utworzony plik jako nowy "obrazek"
c) jeśli chcesz mieć do tego automatyczną miniaturkę, to musisz później pod tak wrzuconym filmikiem kliknąć "Dodaj miniaturkę" i przesłać obrazek...

tak że ten... Taki mechanizm średnio zachęca do wrzucania swojej jutubowej biblioteki. 😒
w związku z tym trzeba było hakować. I po wielu dniach walki zamierzony cel został osiągnięty, co widać na obrazku.

bonusowo od ostatniego posta z większych zmian doszły:
- custom video loader (zamiast kijowego jutubowego "czarnego ekranu")
- instant hover divy po najechaniu na miniaturkę (1:08)
- automatyczny scroll napisu (od biedy można to osiągnąć i samym css-em, tutaj jednak działa jQuery - z pomocą GSAP, dawniej znanego jako Tweenmax).

tak że czuję się hepi.
I z tej okazji może pójdę coś zjeść od rana.

a później czeka mnie sprzątanie komentarzowego śmietnika i testy... Już na tym filmiku zauważyłem buga: 1:18 na filmstripie widać, że są "wybrane" (w grubej ramce) dwa elementy... Ten filmstrip i instant hovery to też była długa walka... Do tego będę musiał pogmerać z właściwym zapisywaniem pobranego z API v3 tytułu, bo widać w nim parę zbędnych backslashów.





/ a tu dla porównania, tak wygląda galeriowa przeglądarka w stanie surowym (youtube player wygląda podobnie, różniąc się tylko iframe'em). Oczywiście wszystko, co widać poniżej, jest do bólu statyczne.



Ostatnia aktualizacja: 24.03.2024 21:01:58 przez snajper
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem