• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z wyliczaniem wielkości obrazka na podstawie wielkości okna

Object Storage Arubacloud
+1 głos
162 wizyt
pytanie zadane 26 listopada 2015 w JavaScript przez tomashpl Obywatel (1,370 p.)
edycja 26 listopada 2015 przez tomashpl

Szanowni, 

to mój pierwszy post na forum, tak że na samym początku chciałbym Was pozdrowić i przywitać się.

Żeby nie zanudzać, przejdę do meritum: mam problem z kodem JavaScript, który generalnie działa, ale nie dokońca tak, jakbym chciał, a mianowicie...

Na jsfiddle wrzuciłem podgląd poniższego skryptu

function setImgSize(img, aspectRatio) {

    var windowHeight = $(window).height();
    var windowWidth  = $(window).width();


    if (windowWidth/windowHeight >= aspectRatio)
    {
        img.height(windowHeight);
        img.width(windowHeight * aspectRatio);
    }
    else
    {
        img.width(windowWidth);
        img.height(windowWidth / aspectRatio);
	}
				
}
			
$(window).on('load', function(){
	img = $('#img');
	imgAspectRatio = img.width() / img.height();

	setImgSize(img, imgAspectRatio);
});
						
$(window).on('resize', function(){
	setImgSize(img, imgAspectRatio);
});

$('body').on('click', function(){
	alert("Image width: "+ img.width() 
          + "\nImage height: " + img.height() 
          + "\nImage aspect ratio base: " + imgAspectRatio 
          + "\nImage aspect ratio current: " + img.width()/img.height() 
          + "\n\nWindow width: " + $(window).width() 
          + "\nWindow height: " + $(window).height() 
          + "\nWindow aspect ratio: " + $(window).width()/$(window).height());
});

W skrypcie tym ustawiam wielkość obrazka względem rozmiaru okna. Założenie jest takie, że obrazek zawsze ma mieć startowe proporcje (te zapisuję w zmiennej imgAspectRatio, a uzyskuję je dzieląc startową szerokość przez startową wysokość obrazka. 

Następnie wywołuję metodę ustawiającą rozmiary obrazka. W tym celu pobieram szerokość i wysokość viewportu i ustalam jego aspect ratio. Jeśli jest ono większe lub równe niż aspect ratio obrazka, wtedy obrazek otrzymuje wysokość viewportu, a szerokość jest wyliczana ze wzoru windowHeight * imgAspectRatio. W przeciwnym wypadku to szerokość obrazka jest ustawiana na szerokość viewportu, a wysokość obliczana wzorem windowWidth / imgAspectRatio.

I matematycznie się niby wszystko zgadza. Dla przykładu:

1920/1080 = 16/9 = 1,777777777777778
1024/768 = 4/3 = 1,333333333333333

​1920 / 1,777777777777778 = 1080
1080 * 1,777777777777778 = 1920

1024 / 1,333333333333333 = 768
768 * 1,333333333333333 = 1024

Niestety rodzą się dwa problemy z wykorzystaniem powyższego skryptu JS:

  1. W większości przypadków odświeżenie okna przeglądarki (lub uruchomienie opcji "RUN" na jsfiddle) sprawia, że obrazek nie dostaje odpowiedniej szerokości lub wysokości w zależności od aspect ratio viewportu, ale nieco mniejsze. Jeśli zrobić resize, to wszystko zaczyna wyglądać jak należy (poza wyjątkiem z punktu 2), ale ponowne odświeżenie znów generuje problem. 

    Nie ma też znaczenia, czy używam window.onload(), $(window).on('load', callback), $('#img').load() - po prostu przy ładowaniu strony rozmiar obrazka jest wyliczany w większości sytuacji niepoprawnie.
     
  2. W sytuacji, kiedy aspect ratio viewportu jest nieznacznie większe od aspect ratio obrazka i zaczniemy zmniejszać szerokość okna, to skalowanie obrazka odbywa się skokowo. Problem nie występuje przy czynności odwrotnej, czyli kiedy aspect ratio viewportu jest mniejsze niż obrazka i zaczynamy je powiększać.

Nie jest to coś, co przeszkadza mi jakoś drastycznie i dla moich potrzeb jest w zupełności akceptowalne, ale chciałbym wiedzieć, czy da się to jakoś poprawić, czy to jednak jakiś bug. Czy może ja coś źle robię i źle kombinuję.

Dzięki z góry za pochylenie się nad moim problemem.

Pozdrawiam!
Tomek

 

2 odpowiedzi

+1 głos
odpowiedź 27 listopada 2015 przez Szymon Lisowiec Mądrala (7,150 p.)
var windowHeight = $(window).innerHeight();
var windowWidth  = $(window).innerWidth();
//chyba
//spróbuj też zamiast pobierać rozmiar okna, to dokumentu.

 

komentarz 27 listopada 2015 przez tomashpl Obywatel (1,370 p.)

Hmmm... dziwna sprawa, ale pomogło co innego (na pierwszy problem). Co prawda nie ma czegoś takiego, jak $(window).innerWidth(), ale jest window.innerWidth oraz analogicznie dla wysokości.

Co ciekawe, zamiana na window.innerWidth i window.innerHeight pomogła na skalowanie obrazka tuż przy ładowaniu, ale jest to o tyle dziwne, że zarówno czysty JS jak i JQuery zwracają tymi metodami dokładnie te same dane. 

http://jsfiddle.net/au5h7ep3/1/

Jak sobie odkomentujesz alert, to zobaczysz, że dane są identyczne, bez względu na zastosowaną metodę pozyskania zmiennych windowWidth i windowHeight. Jednak przy użyciu JS działa, a JQuery nie.

 

komentarz 29 listopada 2015 przez Szymon Lisowiec Mądrala (7,150 p.)
1. http://api.jquery.com/innerwidth/
2. Ogólnie bez różnicy. Jak działa window.innerHeight, to po co męczyć się z przerobieniem tego na jquery.
+1 głos
odpowiedź 27 listopada 2015 przez NXT Obywatel (1,860 p.)

Może problem dotyczy operacji arytmetycznych w JS?

Poczytaj tutaj: http://kursjs.pl/kurs/math.html#mnozenie

komentarz 27 listopada 2015 przez tomashpl Obywatel (1,370 p.)
Bardzo dziękuję za podpowiedź. Myślę, że to może mieć wpływ na te skokowe zmiany przy pomniejszaniu viewportu. Wieczorem się tym zajmę i zobaczę, jaki będzie efekt :)

Podobne pytania

0 głosów
2 odpowiedzi 1,193 wizyt
pytanie zadane 21 października 2015 w HTML i CSS przez firefoxlin Początkujący (290 p.)
0 głosów
2 odpowiedzi 210 wizyt
pytanie zadane 30 września 2015 w Java przez Damianoo4444 Bywalec (2,700 p.)
0 głosów
1 odpowiedź 187 wizyt
pytanie zadane 23 marca 2019 w C i C++ przez Hailon Początkujący (310 p.)

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...