Pytanie
Czy istnieje bezpieczny sposób na uzyskanie rzeczywiście prawidłowych fizycznych wymiarów ekranu w przeglądarce Chrome na Androida? W razie potrzeby stare wersje Chrome i Androida można pominąć.
Wcześniejsze badania
Istnieje wiele ślepych pytań dotyczących przepełnienia stosu, dotyczących uzyskania rzeczywistych fizycznych wymiarów ekranu urządzenia z poziomu javascript (lub css). Wydaje się, że nie ma zbieżności między standaryzacją html api a rzeczywistymi implementacjami przeglądarek, nie wspominając o tym, że implementacja przeglądarki opiera się na interfejsach API systemu operacyjnego, które z kolei wymagają sprzętu dostarczającego odpowiednich informacji.
Nawiasem mówiąc, niektóre wcześniejsze odpowiedzi są tajemnicze (rok 2011 i tym podobne), zakładając pewną gęstość pikseli, która panowała w tamtym czasie, a zatem są bezużyteczne. Inne odnoszą się do webkit, podczas gdy Chrome Blink mógł zastąpić webkit w chrome (?).
Chciałbym zbadać istnienie prostego rozwiązania, ograniczając rzeczy tylko do Chrome na Androida.
Uwaga
Chodzi o rozwiązanie javascript (lub css) w przeglądarce, a nie rozwiązanie dla aplikacji natywnej.
źródło
window.screenDensity
która zawiera fizyczne piksele na cal urządzenia, które ty i ja, Matt, możemy ją stamtąd pobrać.window.screenHeight
iwindow.screenWidth
w milimetrach fizycznych byłby miły.Odpowiedzi:
Naprawdę nie możesz uzyskać rzeczywistych wymiarów fizycznych ani rzeczywistego DPI, a nawet gdybyś mógł, nie możesz z nimi nic zrobić.
To dość długa i złożona historia, więc wybacz mi.
Internet i wszystkie przeglądarki definiują 1 piksel jako jednostkę zwaną pikselem CSS. Piksel CSS nie jest prawdziwym pikselem, a raczej jednostką, która jest uważana za 1/96 cala na podstawie kąta widzenia urządzenia. Jest to określane jako piksel odniesienia .
W 0,26 mm przestrzeni możemy mieć bardzo wiele rzeczywistych pikseli urządzenia.
Przeglądarka robi to głównie z powodów przestarzałych - większość monitorów miała 96 dpi w momencie narodzin sieci - ale także dla spójności, w „dawnych czasach” przycisk 22px na 15-calowym ekranie o rozdzielczości 800x600 był dwukrotnie większy niż przycisk 22px na 15-calowy monitor o rozdzielczości 1600x1200. W tym przypadku DPI ekranu wynosi w rzeczywistości 2x (dwukrotnie większa rozdzielczość w poziomie, ale w tej samej przestrzeni fizycznej). Jest to zła sytuacja dla sieci i aplikacji, dlatego większość systemów operacyjnych opracowała wiele sposobów wyodrębniania wartości pikseli w jednostkach niezależnych od urządzenia (DIPS na Androidzie, PT na iOS i CSS Pixel w sieci ).
Przeglądarka iPhone Safari jako pierwsza (o ile mi wiadomo) wprowadziła koncepcję widoku. Zostało to stworzone, aby umożliwić renderowanie aplikacji w pełnym stylu na małym ekranie. Widoczny obszar miał szerokość 960 pikseli. To zasadniczo pomniejszyło stronę 3x (iPhone miał pierwotnie 320px), więc 1 piksel CSS to 1/3 fizycznego piksela. Kiedy zdefiniowałeś obszar roboczy, możesz jednak uzyskać dopasowanie tego urządzenia do 1 piksela CSS = 1 prawdziwy piksel przy 163 dpi.
Używając okna roboczego, w którym szerokość jest równa „szerokość urządzenia”, nie musisz ustawiać szerokości obszaru roboczego dla każdego urządzenia na optymalny rozmiar w pikselach CSS, przeglądarka zrobi to za Ciebie.
Wraz z wprowadzeniem urządzeń z podwójnym DPI, producenci telefonów komórkowych nie chcieli, aby strony mobilne wyglądały na 50% mniejsze, więc wprowadzili koncepcję o nazwie devicePixelRatio (pierwsza w mobilnym zestawie internetowym, jak sądzę), która pozwala im utrzymać 1 piksel CSS na poziomie około 1 / 96 części cala, ale pozwól sobie zrozumieć, że zasoby, takie jak obrazy, mogą wymagać dwukrotnego rozmiaru. Jeśli spojrzysz na serię iPhone'ów, wszystkie ich urządzenia powiedzą, że szerokość ekranu w pikselach CSS wynosi 320 pikseli, mimo że wiemy, że to nieprawda.
Dlatego jeśli utworzyłeś przycisk, który ma 22 piksele w przestrzeni CSS, reprezentacja na ekranie fizycznym ma stosunek pikseli urządzenia 22 *. Właściwie to mówię, to nie jest dokładnie to, ponieważ współczynnik pikseli urządzenia też nigdy nie jest dokładny, producenci telefonów ustawili go na ładną liczbę, taką jak 2,0, 3,0 zamiast 2,1329857289918 ....
Podsumowując, piksele CSS są niezależne od urządzenia i nie musimy martwić się o fizyczne rozmiary ekranów, gęstość wyświetlania itp.
Morał tej historii jest następujący: nie martw się o zrozumienie rozmiaru fizycznego piksela ekranu. Nie potrzebujesz tego. 50 pikseli powinno wyglądać mniej więcej tak samo na wszystkich urządzeniach mobilnych, może się nieco różnić, ale CSS Pixel to nasz niezależny od urządzenia sposób tworzenia spójnych dokumentów i interfejsów użytkownika
Zasoby:
źródło
Bazując na odpowiedzi Matta, zrobiłem test:
// on Macbook Pro Retina (2880x1800, 15.4"), is the calculated diagonal size // approximately 15.4? Let's see... var svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); var screenWidthMillimeters = svgEl.screenPixelToMillimeterX * 2880; var screenHeightMillimeters = svgEl.screenPixelToMillimeterY * 1800; var screenDiagonalMillimeters = Math.sqrt(Math.pow(screenWidthMillimeters, 2) + Math.pow(screenHeightMillimeters, 2)); // pythagorean theorem var screenDiagonalInches = (screenDiagonalMillimeters / 10 / 2.54); // (mm / 10mm/cm) / 2.54cm/in = in console.log("The calculated diagonal of the screen is "+screenDiagonalInches+" inches. \nIs that close to the actual 15.4\"?");
Oto wynik:
The calculated diagonal of the screen is 35.37742738560738 inches. Is that close to the actual value of 15.4?
Nie.
Wydaje się więc, że nie ma jeszcze sposobu na uzyskanie rzeczywistych wartości fizycznych w przeglądarce internetowej.
źródło
svgEl.screenPixelToMillimeterX
najwyraźniej nie został zdefiniowany.Możesz utworzyć dowolny element strony i ustawić jego szerokość przy użyciu rzeczywistych jednostek fizycznych. Na przykład
<div id="meter" style="width:10cm"></div>
A następnie uzyskaj jego szerokość w pikselach. Na przykład poniższy kod html (użyłem JQuery) pokazuje szerokość ekranu urządzenia w centymetrach
<script> var pixPer10CM = $('#meter').width(); var CMPerPix = 10 / pixPer10CM; var widthCM = screen.width * CMPerPix; alert(widthCM); </script>
źródło
Możesz uzyskać te informacje za pomocą WURFL:
Właściwości wyświetlania urządzenia
Atrybuty nazywane są:
Długa wersja:
Najlepszą i najbardziej niezawodną strategią, aby to osiągnąć, jest wysłanie
user agent string
z przeglądarki do bazy danych takiej jakWURFL
(lub innej) aktualnej bazy danych, która może dostarczyć potrzebnych informacji.Ciąg agenta użytkownika
To jest informacja, którą mogą dostarczyć wszystkie nowoczesne przeglądarki; ujawnia informacje o urządzeniu i jego systemie operacyjnym. Po prostu nie ma wystarczającego znaczenia dla twojej aplikacji bez pomocy słownika, takiego jak
WURFL
.WURFL
Jest to baza danych powszechnie używana do wykrywania właściwości urządzeń.
Dzięki niemu możesz dokładnie obsługiwać większość popularnych urządzeń na rynku. Chciałbym opublikować demo kodu, ale jest ono dostępne do pobrania na
WURFL
stronie. Takie demo można znaleźć w folderze przykłady / demo, który jest pobierany wraz z biblioteką.Pobierz WURFL
Tutaj znajduje się więcej informacji i wyjaśnienie dotyczące sprawdzania rozmiaru fizycznego i rozdzielczości: http://www.scientiamobile.com/forum/viewtopic.php?f=16&t=286
źródło
Jako uzupełnienie odpowiedzi „nie ma dobrego rozwiązania tego problemu”, po prostu sprawdź jednostki, których możesz użyć w CSS https://www.w3schools.com/cssref/css_units.asp
Unit Description cm centimeters mm millimeters in inches (1in = 96px = 2.54cm) px * pixels (1px = 1/96th of 1in) pt points (1pt = 1/72 of 1in) pc picas (1pc = 12 pt) * Pixels (px) are relative to the viewing device. For low-dpi devices, 1px is one device pixel (dot) of the display. For printers and high resolution screens 1px implies multiple device pixels.
Wydaje się, że dzięki temu opisowi istnieje rozwiązanie.
cm
,mm
iin
będzie używany do rysowania czegoś o tym samym rozmiarze niezależnie od rozmiaru ekranu i rozdzielczości. Mając to na uwadze, można oczekiwać, że co najmniej jednapx
,pt
lubpc
mogą być wykorzystane do opracowania na poziomie pikseli, niezależnie od precyzji chcesz użyć (w przeciwnym razie, jaki jest sens posiadania miliony pikseli, prawda?). Więc nie. Wszystkie jednostki są ułamkami jednostki metrycznej, co sprawia, że wszystkie te jednostki mają inną skalę. A najgorsze w tej historii jest to, że żadne z nich nie jest dokładne. Po prostu pobaw się przykładem w3schools (narysuj 20 cm linię i zmierz ją linijką).Więc w końcu: - nie ma sposobu, aby wyciągnąć coś z wymiarów fizycznych dokładnie (co powinno być w przypadku
cm
,mm
,in
, a ostateczniept
ipc
). - nie ma możliwości narysowania czegoś o tym samym rozmiarze niezależnie od rozmiaru ekranu i rozdzielczości (co powinno mieć miejsce przynajmniejpx
).Jest to zarówno problem implementacyjny (faktyczny rozmiar ekranu nie jest używany), jak i problem projektowy (dlaczego miałoby
px
być niezależne od rozmiaru ekranu, skoro jest już tak wiele jednostek).źródło
Rozwiązałem ten problem w jednym z moich projektów internetowych http://www.vinodiscover.com Odpowiedź jest taka, że nie możesz wiedzieć na pewno, jaki jest rozmiar fizyczny, ale możesz uzyskać przybliżenie. Używając JS i / lub CSS, możesz znaleźć szerokość i wysokość widocznego obszaru / ekranu oraz gęstość pikseli za pomocą zapytań o media. Na przykład: iPhone 5 (326 ppi) = 320 na 568 pikseli i gęstość pikseli 2,0, podczas gdy Samsung Galaxy S4 (441 ppi) = 360 pikseli x 640 pikseli i gęstość pikseli 3,0. W rzeczywistości gęstość pikseli 1,0 wynosi około 150 ppi.
Biorąc to pod uwagę, ustawiłem CSS tak, aby wyświetlał 1 kolumnę, gdy szerokość jest mniejsza niż 284px, niezależnie od gęstości pikseli; następnie dwie kolumny od 284 do 568 pikseli; następnie 3 kolumny powyżej 852 pikseli. Jest to o wiele prostsze niż się wydaje, ponieważ przeglądarki teraz automatycznie wykonują obliczenia gęstości pikseli.
http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html
źródło
W odpowiedzi na odpowiedź zehelviona dotyczącą wykorzystania WURFL do znalezienia rozdzielczości, warto również wspomnieć, że WURFL jest również dostępny jako fragment kodu JavaScript .
W bezpłatnej edycji oferowanej na wurfl.io nie znajdziesz jednak informacji o ekranie i rozdzielczości (tylko nazwa urządzenia, format i wersja mobilna / nie mobilna), ale dostępna jest również wersja komercyjna z większymi możliwościami .
źródło
Piksele CSS nie są tak naprawdę naszym „pikselem niezależnym od urządzenia”. Platforma internetowa składa się z różnych typów urządzeń. Podczas gdy piksel CSS wygląda dość spójnie na urządzeniach przenośnych, na typowym monitorze biurkowym o rozdzielczości 96 dpi będzie o 50% większy. Zobacz moje pytanie . W niektórych przypadkach to naprawdę nie jest złe, np. Czcionki powinny być większe na większym ekranie, ponieważ odległość od oka jest większa. Ale wymiary elementu interfejsu użytkownika powinny być dość spójne. Załóżmy, że Twoja aplikacja ma górny pasek, wolisz, aby miała tę samą grubość na komputerach stacjonarnych i telefonach komórkowych, domyślnie będzie o 50% mniejsza, co nie jest dobre, ponieważ elementy dotykowe powinny być większe. Jedynym rozwiązaniem, jakie znalazłem, jest zastosowanie różnych stylów w oparciu o DPI urządzenia.
Możesz uzyskać DPI ekranu w JavaScript za pomocą window.devicePixelRatio. Lub zapytanie CSS:
@media only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 13/10), only screen and (min-resolution: 120dpi) { /* specific styles for handhelds/ high dpi monitors*/ }
Nie wiem jednak, jak zastosowanie tego mogłoby działać na monitorze stacjonarnym o wysokiej rozdzielczości. Być może elementy byłyby za małe. Szkoda, że platforma internetowa nie oferuje nic lepszego. Myślę, że implementacja dip nie byłaby zbyt trudna.
źródło
Zauważyłem w twoich komentarzach, że tak naprawdę martwiłeś się rozmiarem przycisków i tak dalej, które są widoczne dla widza.
Miałem ten sam problem, dopóki nie odkryłem, że chodziło tylko o dodanie metatagu do nagłówka HTML, aby ustawić początkową skalę:
<meta name="viewport" content="width=device-width, initial-scale=1">
źródło
JqueryMobile szerokość elementu
$(window).width(); // returns width of browser viewport $(document).width(); // returns width of HTML document
JqueryMobile Wysokość elementu
$(window).height(); // returns height of browser viewport $(document).height(); // returns height of HTML document
Powodzenia Danny117
źródło
Korzystając z funkcji getPPI () ( Internet mobilny: jak uzyskać fizyczny rozmiar piksela? ), Aby uzyskać jednocalowy identyfikator, użyj następującego wzoru:
var ppi = getPPI(); var x = ppi * devicePixelRatio * screen.pixelDepth / 24; $('#Cubo').width (x); $('#Cubo').height(x); <div id="Cubo" style="background-color:red;"></div>
źródło
Chciałbym móc odpowiedzieć na to pytanie, ale geekowie budujący interfejsy API nie zapewniają czasami zbyt wielu podstawowych potrzeb i abstrakcyjnych rzeczy.
Przy okazji, mam 40 lat doświadczenia w projektowaniu interfejsu użytkownika i oprogramowania i starałem się mieć to właśnie od dawna, jak się wydaje, od czasów sterowników "VESA" :).
W przypadku ekranu dotykowego miałem coś, co nazwałem „fingerSize ()”, czyli liczbą pikseli, która miała wynosić 1 cm (bardzo blisko średnicy przeciętnego obszaru dotykowego palca), ale podstawową datą jest „dpcm”.
Inną rzeczą, której potrzebujesz w przypadku wyświetlacza, jest „kąt widzenia”. Typ urządzenia wyświetlającego do oglądania i funkcji dotykowej w dużym stopniu określa odległość oglądania.
(Not code but I wanted fixed width font) Hand held - Phone/Tablet 25cm Touch screen / Desktop Monitor 40cm ( seated or standing at a counter with partially extended arm ) "Personal" Touch kiosk 50cm -> 80cm ( a bit further away standing extended arms and standing back to view ) Presentation Screen. any distance ( angle of view derived from pixel width of device. An ideal conventional cinema seat (as opposed to imax or immersive) you want about 50 degrees between edges of the screen. from viewer POV ) So what you want universally available is: device usage type. finger size in pixels (dots per CM) pixel dimensions of display. Then internally, when laying out and drawing you want the size/shape of a pixel for the current transform.
To właśnie staramy się zapewnić w naszych interfejsach API, ale niestety w wielu przypadkach jest to trudne do uzyskania.
źródło
Możesz uzyskać przybliżone oszacowanie rozmiaru, ale nie jest to dokładne.
Przygotowałem przykład, który przetestowałem na kilku urządzeniach, aby zobaczyć, jakie były wyniki. Mój iPhone 6 zwraca wartości większe o około 33%. Mój 27-calowy monitor biurkowy na moim Macu zgłosił 30-calowy monitor.
var $el = document.createElement('div'); $el.style.width = '1cm'; $el.style.height = '1cm'; $el.style.backgroundColor = '#ff0000'; $el.style.position = 'fixed'; $el.style.bottom = 0; document.body.appendChild($el); var screenDiagonal = Math.sqrt(Math.pow((window.screen.width / $el.offsetWidth), 2) + Math.pow((window.screen.height / $el.offsetHeight), 2)); var screenDiagonalInches = (screenDiagonal / 2.54); var str = [ '1cm (W): ' + $el.offsetWidth + 'px', '1cm (H): ' + $el.offsetHeight + 'px', 'Screen width: ' + window.screen.width + 'px', 'Screen height: ' + window.screen.height + 'px', 'Browser width: ' + window.innerWidth + 'px', 'Browser height: ' + window.innerHeight + 'px', 'Screen available width: ' + window.screen.availWidth + 'px', 'Screen available height: ' + window.screen.availHeight + 'px', 'Screen width: ' + (window.screen.width / $el.offsetWidth).toFixed(2) + 'cm', 'Screen height: ' + (window.screen.height / $el.offsetHeight).toFixed(2) + 'cm', 'Screen diagonal: ' + screenDiagonal.toFixed(2) + 'cm', 'Screen diagonal: ' + screenDiagonalInches.toFixed(2) + 'in', 'Device Pixel Ratio: ' + (window.devicePixelRatio || 1) ].join('\n'); var $pre = document.createElement('pre'); $pre.innerHTML = str; document.body.appendChild($pre);
http://codepen.io/kus/full/xOAPYB/
źródło
window.devicePixelRatio
. Na ekranie Apple Thunderbolt wynosi 1, a na 15-calowym pasku dotykowym Macbooka Pro. Czy ta wartość jest zawsze liczbą całkowitą? Nie miałoby to sensu, ponieważ jest to współczynnik. Inne elementy: stackoverflow.com/questions/16385573/ ...