How to detect the screen resolution with JavaScript? - javascript

Is there a way that works for all browsers?

original answer
Yes.
window.screen.availHeight
window.screen.availWidth
update 2017-11-10
From Tsunamis in the comments:
To get the native resolution of i.e. a mobile device you have to multiply with the device pixel ratio: window.screen.width * window.devicePixelRatio and window.screen.height * window.devicePixelRatio. This will also work on desktops, which will have a ratio of 1.
And from Ben in another answer:
In vanilla JavaScript, this will give you the AVAILABLE width/height:
window.screen.availHeight
window.screen.availWidth
For the absolute width/height, use:
window.screen.height
window.screen.width

var width = screen.width;
var height = screen.height;

In vanilla JavaScript, this will give you the AVAILABLE width/height:
window.screen.availHeight
window.screen.availWidth
For the absolute width/height, use:
window.screen.height
window.screen.width
Both of the above can be written without the window prefix.
Like jQuery? This works in all browsers, but each browser gives different values.
$(window).width()
$(window).height()

You can also get the WINDOW width and height, avoiding browser toolbars and... (not just screen size).
To do this, use:
window.innerWidth and window.innerHeight properties. See it at w3schools.
In most cases it will be the best way, in example, to display a perfectly centred floating modal dialog. It allows you to calculate positions on window, no matter which resolution orientation or window size is using the browser.

Do you mean display resolution (eg 72 dots per inch) or pixel dimensions (browser window is currently 1000 x 800 pixels)?
Screen resolution enables you to know how thick a 10 pixel line will be in inches. Pixel dimensions tell you what percentage of the available screen height will be taken up by a 10 pixel wide horizontal line.
There's no way to know the display resolution just from Javascript since the computer itself usually doesn't know the actual dimensions of the screen, just the number of pixels. 72 dpi is the usual guess....
Note that there's a lot of confusion about display resolution, often people use the term instead of pixel resolution, but the two are quite different. See Wikipedia
Of course, you can also measure resolution in dots per cm. There is also the obscure subject of non-square dots. But I digress.

Using jQuery you can do:
$(window).width()
$(window).height()

Trying to get this on a mobile device requires a few more steps. screen.availWidth stays the same regardless of the orientation of the device.
Here is my solution for mobile:
function getOrientation(){
return Math.abs(window.orientation) - 90 == 0 ? "landscape" : "portrait";
};
function getMobileWidth(){
return getOrientation() == "landscape" ? screen.availHeight : screen.availWidth;
};
function getMobileHeight(){
return getOrientation() == "landscape" ? screen.availWidth : screen.availHeight;
};

See Get Monitor Screen Resolution with Javascript and the window.screen object

function getScreenWidth()
{
var de = document.body.parentNode;
var db = document.body;
if(window.opera)return db.clientWidth;
if (document.compatMode=='CSS1Compat') return de.clientWidth;
else return db.clientWidth;
}

just for future reference:
function getscreenresolution()
{
window.alert("Your screen resolution is: " + screen.height + 'x' + screen.width);
}

If you want to detect screen resolution, you might want to checkout the plugin res. It allows you to do the following:
var res = require('res')
res.dppx() // 1
res.dpi() // 96
res.dpcm() // 37.79527559055118
Here are some great resolution takeaways from Ryan Van Etten, the plugin's author:
2 unit sets exist and differ at a fixed scale: device units and CSS units.
Resolution is calculated as the number of dots that can fit along a particular CSS length.
Unit conversion: 1⁢in = 2.54⁢cm = 96⁢px = 72⁢pt
CSS has relative and absolute lengths. In normal zoom: 1⁢em = 16⁢px
dppx is equivalent to device-pixel-ratio.
devicePixelRatio definition differs by platform.
Media queries can target min-resolution. Use with care for speed.
Here's the source code for res, as of today:
!function(root, name, make) {
if (typeof module != 'undefined' && module.exports) module.exports = make()
else root[name] = make()
}(this, 'res', function() {
var one = {dpi: 96, dpcm: 96 / 2.54}
function ie() {
return Math.sqrt(screen.deviceXDPI * screen.deviceYDPI) / one.dpi
}
function dppx() {
// devicePixelRatio: Webkit (Chrome/Android/Safari), Opera (Presto 2.8+), FF 18+
return typeof window == 'undefined' ? 0 : +window.devicePixelRatio || ie() || 0
}
function dpcm() {
return dppx() * one.dpcm
}
function dpi() {
return dppx() * one.dpi
}
return {'dppx': dppx, 'dpi': dpi, 'dpcm': dpcm}
});

if you mean browser resolution then
window.innerWidth gives you the browser resolution
you can test with http://howbigismybrowser.com/
try changing your screen resolution by zoom in / out browser and check resolution size with http://howbigismybrowser.com/
Window.innerWidth should be same as screen resolution width

Easy steps to find screen resolution is:
Copy
`My screen resolution is: ${window.screen.width} * ${window.screen.height}`
paste in browser console
hit enter

Related

Javascript: How to get length of a line in canvas by inch (or milimeter) [duplicate]

Is there a reliable equation to work out pixel size to MM? Or is that not possible cross device?
We are working with a bespoke system that delivers content to many devices with different screen sizes, it can detect the screen width in MM, but we would like to accurately convert this to pixel size to deliver correctly sized images dynamically using a simple jquery script!?
Any ideas?
Cheers
Paul
What i did :
<div id="my_mm" style="height:100mm;display:none"></div>
Then:
var pxTomm = function(px){
return Math.floor(px/($('#my_mm').height()/100)); //JQuery returns sizes in PX
};
tl;dr: If you don't know the DPI of the device, you won't be able to deduce how big the pixel is in the real-world.
Pixels on their own are not real-world units of measurement.
They can become a real-world measurement if you take into account the DPI value of the device that displays them.
The formula is:
mm = ( pixels * 25.4 ) / DPI
So 8 pixels viewed on a 96-DPI screen setting:
( 8 * 25.4 ) / 96 = 2.116mm
All this assuming the device is not scaled/zoomed.
old post but I stumbled upon this today and had to make it work.
the trick is to create an element with dimensions styled in inches and request its width, this will give you the px per inch.
function inch2px(inches) {
$("body").append("<div id='inch2px' style='width:1in;height:1in;display:hidden;'></div>");
var pixels = $("#inch2px").width();
$("#inch2px").remove();
return inches * pixels;
}
function px2inch(px) {
$("body").append("<div id='inch2px' style='width:1in;height:1in;display:hidden;'></div>");
var pixels = $("#inch2px").width();
$("#inch2px").remove();
return px / pixels;
}
now if you need millimetres, just do px2inch(10)*25.4.
You would need to know the DPI of the device and if the display is scaled or not. That would mean that you would have to have a database of the physical screen dimensions and screen resolutions of each device.
No need for jQuery.
function xToPx(x) {
var div = document.createElement('div');
div.style.display = 'block';
div.style.height = x;
document.body.appendChild(div);
var px = parseFloat(window.getComputedStyle(div, null).height);
div.parentNode.removeChild(div);
return px;
}
pixels = xToPx('10cm'); // convert 10cm to pixels
pixels = xToPx('10mm'); // convert 10mm to pixels
Please notice that values in pixels are depending on what resolution the browser of the device tells you. Some browsers (on some phones) lie about this and tell you something different than the actual screen resolution in an attempt to be compatible with older sites. Main important thing is to never port conversion values from one device to another but always use real-time calculations. Even on a desktop the user can change the screen resolution.
To learn more about the units, check out this (short) article on W3:
https://www.w3.org/Style/Examples/007/units.en.html
i use this simple function
function pix2mm(val,dpi){
return (val/0.0393701)/dpi;
}
test outputs it 300,600,900 DPI
var r = pix2mm(100,300); // converting 100 pixels it 300 DPI
console.log(r); // output : 8.4 mm
var r1 = pix2mm(100,600); // converting 100 pixels it 600 DPI
console.log(r1); // output : 4.2 mm
var r2 = pix2mm(100,900); // converting 100 pixels it 900 DPI
console.log(r2); // output : 2.8 mm
DEMO : https://jsfiddle.net/xpvt214o/29044/
You cannot reliably calculate this since there is no way to detect physical screen size.
Based on the #Dawa answer above, this is my solution:
var mmToPx = function(mm) {
var div = document.createElement('div');
div.style.display = 'block';
div.style.height = '100mm';
document.body.appendChild(div);
var convert = div.offsetHeight * mm / 100;
div.parentNode.removeChild(div);
return convert;
};
Just note that the 100mm height, will give you a better precision factor.
The calculation will be instant and the div will not be visible. No need for jQuery
Late but may be useful.
1 px = 0.26458333333719 mm
Milli Meter Pixel
1 mm = 3.779527559 px
So if you have lets say 10px. It will be equal to 10 * 0.26458.. = 2.64mm
ref : https://everythingfonts.com/font/tools/units/px-to-mm
Enjoy :)

Converting Pixels to Metres Advanced

I am having trouble converting pixels to metres on my game
how many pixels is a meter in Box2D?
Is an example of my problem, but does not solve it.
This is because this solution, while it works, will not go cross browser, that is, if the conversion rate is something constant like 50px to one meter, than on a device with 400x800 resolution, the objects will appear big, whereas on another device with 4000x8000 resolution (exagurated) the objects will be tiny.
I can understand some solutions to this, but the main reason why I am finding this so hard to implement is because one browser or phone might be 16:9 ratio, whereas another might be 14:7, and these differing ratio's are the kicker, since my entire game is held on the screen as it is not a scrolling game, it is just a simple physics game.
Because of this I understand that It is easier to have to world be a smaller size, and convert it back up when rendering, but these problems that I have mentioned have stumped me, and I was wandering if anyone had any feasible solutions.
Since your
entire game is held on the screen
I suggest you the following:
Decide how many "meters" you need your window width to be. Say you've decided:
any window width (W) is always N "meters"
Then k = W/N where k is a scaling multiplier meaning a part of window width within 1 "meter".
So if W = 400px and N = 100m you have k = 400px/100m = 4px/m.
And when other screen is W = 4000px you have k = 40px/m.
That way you can translate your "meters" to pixels by multiplying your dimensions in "meters" by k and your objects will be always scaled to the screen size.
In JavaScript it looks like:
var N = 100; // window width in "meters"
var k = window.innerWidth / N; // px in 1m
// let's count something simple
var U = 10; // speed in meters per second
var t = 10; // time in seconds
var S = U * t; // distance in meters
var S_px = S * k; // distance in pixels (scaled to the window width)

Getting display resolution through Javascript or jQuery

I was using javascript to obtain the my display resolution. The following code gave me the result of 1440 x 900 for my Macbook Pro
var screenWidth = screen.width;
var screenHeight = screen.height;
However, when I go check display setting of my Mac. It shows 2880 x 1800.
I'm wondering if I was on the wrong track on getting the resolution of a display?
You have a Retina display. You can use devicePixelRatio to determine what the physical display size is.
var physicalScreenWidth = screen.width * window.devicePixelRatio;
var physicalScreenHeight = screen.height * window.devicePixelRatio;
In your example, devicePixelRatio will be 2

canvasContext.fillRect throws NS_ERROR_FAILURE exception in Firefox

I'm trying to draw a huge canvas rectangle on top of the page (some kind of lightbox background), the code is quite straightforward:
var el = document.createElement('canvas');
el.style.position = 'absolute';
el.style.top = 0;
el.style.left = 0;
el.style.zIndex = 1000;
el.width = window.innerWidth + window.scrollMaxX;
el.height = window.innerHeight + window.scrollMaxY;
...
document.body.appendChild(el);
// and later
var ctx = el.getContext("2d");
ctx.fillStyle = "rgba(0, 0, 0, 0.4)";
ctx.fillRect(0, 0, el.width, el.height);
And sometimes (not always) the last line throws:
Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMCanvasRenderingContext2D.fillRect]
I've been guessing if that happens because of image size or because of the content type beneath the canvas (e.g. embeded video playing), but apparently not.
So I'm looking for any ideas on how to isolate and/or solve this issue.
Looking at the nsIDOMCanvasRenderingContext2D.fillRect() implementation (and going through the functions it calls) - there aren't all too many conditions that will return NS_ERROR_FAILURE. It can only happen if either EnsureSurface() or mThebes->CopyPath() fail. And the following two lines in EnsureSurface() are most likely the source of your issue:
// Check that the dimensions are sane
if (gfxASurface::CheckSurfaceSize(gfxIntSize(mWidth, mHeight), 0xffff)) {
What's being checked here:
Neither the width nor the height of the canvas can exceed 65535 pixels.
The height cannot exceed 32767 pixels on Mac OS X (platform limitation).
The size of canvas data (width * height * 4) cannot exceed 2 GB.
If any of these conditions is violated EnsureSurface() will return false and consequently produce the exception you've seen. Note that the above are implementation details that can change at any time, you shouldn't rely on them. But they might give you an idea which particular limit your code violates.
You could apply a try-catch logic. Firefox seems to be the only browser which behaves this a bit odd way.
el.width = window.innerWidth + window.scrollMaxX;
el.height = window.innerHeight + window.scrollMaxY;
// try first to draw something to check that the size is ok
try
{
var ctx = el.getContext("2d");
ctx.fillRect(0, 0, 1, 1);
}
// if it fails, decrease the canvas size
catch(err)
{
el.width = el.width - 1000;
el.height = el.height - 1000;
}
I haven't found any variable that tells what is the maximum canvas size. It varies from browser to browser and device to device.
The only cross browser method to detect the maximum canvas size seems to be a loop that decreases the canvas size eg. by 100px until it doesn't produce the error. I tested a loop, and it is rather fast way to detect the maximum canvas size. Because other browsers doesn't throw an error when trying to draw on an over sized canvas, it is better to try to draw eg. red rect and read a pixel and check if it is red.
To maximize detection performance:
- While looping, the canvas should be out of the DOM to maximize speed
- Set the starting size to a well known maximum which seems to be 32,767px (SO: Maximum size of a <canvas> element)
- You can make a more intelligent loop which forks the maximum size: something like using first bigger decrease step (eg.1000px) and when an accepted size is reached, tries to increase the size by 500px. If this is accepted size, then increase by 250px and so on. This way the maximum should be found in least amount of trials.

maintaining aspect ratio

I am working on an image cropping tool at the moment, the image crop tool comes from jCrop, what I am trying to is make the image the user takes the crop from smaller than the original uploaded. Basically if uploads a landscape image I need to make the image 304px wide without alterting the aspect ratio of the shot.
For instance if the user uploads a portrait shot, I need make the image 237px without altering the aspect ratio of the shot.
Is this possible? I have access to original images sizes in my code, but I cannot work out make sure I am not altering the aspect ratio?
Yes, it's possible if the source image is already wide enough. If it's not wide enough there isn't enough data to crop and if you wanted to maintain aspect ratio, you'd need to scale the image up before the crop.
Something like this should get you started:
CropWidth=237;
AspectRatio= SourceWidth/SourceHeight;
CropHeight = CropWidth*AspectRatio;
To properly maintain aspect ratio you should use GCD:
function gcd(a, b) {
return (b == 0) ? a : gcd(b, a % b);
}
You should then do something like this:
function calcRatio(objectWidth, objectHeight) {
var ratio = gcd(objectWidth, objectHeight),
xRatio = objectWidth / ratio,
yRatio = objectHeight / ratio;
return { "x": xRatio, "y": yRatio };
}
This will get you the ratio of some object. You can use this information to figure out how large the resulting image should be.
function findSize (targetHeight, xRatio, yRatio) {
var widthCalc = Math.round((xRatio * targetHeight) / yRatio);
return { "width" : widthCalc, "height" : targetHeight };
}
var test = calcRatio(1280,720),
dimensions = findSize(400, test.x, test.y);
//400 is what we want the new height of the image to be
Those are your dimensions. If you don't have any extra "space" around your images that you need to account for then your work is done. Otherwise you need to handle a couple cases.

Categories