Always the same size of image on all screens - javascript

I need that square image always be the same size on any screen (including mobile, tablet...). So if I take the ruler and measure image on any screen it have to be 5mm for example. It must be in JavaScript.
I wonder if the size of that image depends only of screen's DPI or it depends of screen resolution also? If in JavaScript I detect screen's DPI (and resolution if needed) is there any formula (or some JavaScript function) to calculate image size to get always the same result?
In the end, can I define image size in some unit which will ensure image to be always the same?
I asked the question here because it is connected to JavaScript, if you think that it is more suitable for some other forum please let me know.
Thanks...

If I understand correctly you want an image always to have a fixed absolute physical size. There is no way to achieve that. You can define a width with absolute units like inch, centimeter or millimeter, but the rendered result differs from one screen to another.
Every browser has set internally 1 inch = 96px, and with that base all other units are calculated. So only if a screen has a physical pixel-size of exactly 25.4 / 96 = 0.26458 mm
an element having width set to 5mm is really 5mm.
But the absolute physical size of a pixel differs widely on different screens and is not detectable by javascript.
EDIT According to your comment: Yes it is possible with your own screen. You can display an element with a width set to 200mm and measure the real width on screen in mm with a ruler. The quotient 200 / your_measurement gives you a conversion factor.
If you now want to set a width to a fixed value you have to multiply that value with the factor.
Display following file and measure the width of the red quadrat:
<!doctype html>
<head>
<style>
div {width: 200mm; height: 200mm; margin: 50px; background-color: red;}
</style>
</head>
<body>
<div></div>
</body>
</html>
The conversion factor is valid for all absolute units you want to use.
With some interaction of a user you can calibrate a users screen as they did on the ZEISS page you linked to. The user has to compare the element on screen against a fixed width (e.g. width of a credit card = 54mm). Since here the user is fixed and the code does the measurement, calculation of the factor is contrariwise: conversion factor f = code_result / 54.
I have made a FIDDLE here with 0.5mm-steps to get more accuracy.

Related

How To Create A Dynamically Sized TextArea In Android Javascript

In my app a user inputs a certain distance in the form of feet and inches. After submission, I need to draw a square textarea in the center of the screen, where the user will then be able to manually adjust the size of the text to match the height of the box. This needs to be able to work across various screen sizes and densities. The app runs on TV's. How can I accomplish this in javascript?
Thanks!
I was able to accomplish this with a little bit of math. In order to create the box at the right height, I first had to find the screen PPI (Pixels Per Inch). I did this by requiring the user to input the value (in inches) of the screens diagonal. I then used the Pythagorean theorem like the following.
float PPI = (float)Math.sqrt((double)(ScreenX * ScreenX + ScreenY * SceenY))/Diagonal
From here it was as easy as setting the desired height in inches and multiplying it by PPI, hope this helps!

Using CSS transforms for proportional sizing and spcing

I want to use CSS transforms to do some layouts of images, and have the image layouts be consistent across different screen widths. (For the purposes of this post, I’m only going to discuss widths and x (left) values.) All the data that I need to do these layouts are in a database.
Of course, if I could do an HTML layout with dedicated styles for each layout, I’d be fine. I could do it like I have it here in this pen. There are three boxes, 2 smaller ones and a larger one that is 3 times the size of the smaller ones. The smaller boxes are each 10% of the window width, the larger one is 30%. The boxes are equally spaced, the left-most one is 10% from the left, the larger middle one is 30% from the left and the last one is 70% from the left. This leaves an equal amount of space ( 10% ) between the boxes.
img#smallA { /* CSS for the first box */
position: absolute;
top: 10%;
left: 10%;
width: 10%;
}
The spacing is uniform when using CSS only.
On the above pen that uses CSS only, you can resize the window width all you want and the sizing and spacing stays consistent; proportional to the screen width, just as we have coded it to do.
So it seems logical that one should be able to do the same thing with a transform. You can get the window width with JS, you can set the width of the boxes with the transform and you can set the x values with the transform. But here’s the pen where I’ve tried to do it. Click the larger box to run the sizeAndPos() function. Now if you resize the window width to 1000 pixels (watch the little gizmo in the center of the CodePen screen), this JS / transform method works perfectly and the layout looks like the other one. But if you stretch it, the spacing starts going off immediately. (Remember to click the larger box after resizing). I think the reason it works at 1000 pixels wide, is b/c at that window width, the boxes are at their natural width. But I don’t understand why it only works in that case.
The spacing is off now; the between gap box 2 and 3 is too big.
For anybody how looks at the code, you may wonder why I’m passing the original width of each image (origWidth) to the function. This is because the CSS scale transform function sizes the image based on it’s original dimensions (scaling an image to 1 gives you 100% of the original size). So to do a proportional size, you first have to figure out how many pixels wide the box should be (10% or 30% of the screen width, depending on the box). Then you have to divide that amount by the original size to get the proper ratio to do the scaling. The small boxes are 100 pixels wide and the large one is 300 pixels wide.
Surely this is possible with transforms. I have tried setting the transform properties individually, to control the order of the operations, but it didn’t help. Can anyone tell me why this doesn’t work?
After trying to make this way too complicated, I found the answer. Change the transform-origin property of the elements. The default on this property is 'center' both axis. But we need our transformations to originate from the top left corner.
img#smallA {
transform-origin: left top;
position: absolute;
}

How to adjust picture size to use as much screen as possible dynamically?

I am working on a Web UI which will be used for monitoring events, the events will popup on the UI as pictures, these picture will disappear after a certain amount of time. The UI will be opened in full screen on a wall-mounted monitor.
Now, given a number of pictures N, how can I re-size the pictures to use the screen optimally? The original picture size is 1280*720, the same ratio should be kept when scale up or down, and all the picture should be the same size.
The target screen Height and Width are variables. The number pictures N will be less than 100. Can someone suggest an effective, easy to implement algorithm?
Thanks to Sorin, here is the code I got, it works pretty well for the problem:
function resize(){
var ratio=1280/720;
var w=document.getElementById("container").clientWidth;
var h=document.getElementById("container").clientHeight;
var n=$("video").length;
var R=ratio/(w/h);
var width,height;
var column=1;
if(n>0){
while(column*Math.ceil(column*R)<n){
column++;
}
var row=Math.ceil(column*R);
height=Math.min(h/row,w/column/ratio)-12;//12 pixel margin
width=height*ratio;
$("video").height(height).width(width)
}
}
First figure out how to change the ratio. Pictures have a ratio of 1280/720 while the display has width/height. So you'll need 1 by 1280/720 / (width/height) pictures in your grid to correct the ratio (let's call this number R). Now you need a multiplier to get the number of picture you are showing to be the number of pictures you have. You need to find an M such that (M *floor(M *R) > N) since N is small a simple iteration will do.
So now you are going to show M pictures by M*R pictures in a grid.
All you need now is to scale all the pictures down. To make sure we leave as little whitespace as possible we take S as min (width / (1280 * M), height / (720 * floor(M *R))).
So scale all pictures by S and show them in a grid with M columns and floor(M*R) lines.
This all assumes that 1280 and 720 include any whitespace you may want to leave between the pictures. Otherwise you need to revise the calculations.

Set bottom position of element based on rendered height of another element

Following is the url to my website
http://projectilepixels.com/beta/
I need the space shuttle to appear "naturally positioned" i.e slightly below the grass at all resolutions above 786 x 1024. However as the grass image as it's width set to 100%, the height is dynamic. Thus the bottom value for the shuttle would also be dynamic. I had initially tried using a simple css % value but that didn't help.
My current attempt uses JavaScript. Following is the code
<script>
$(document).ready(function() {
var grass = $( '#grass' );
var grassHeight = grass.outerHeight() - grass.outerHeight()/100 * 74;
$( '#shuttle_1' ).css("bottom",grassHeight);
});
</script>
The initial script just used
var grassHeight = grass.outerHeight();
however it ended up really messed up.
So, as a temp fix I added the mathematics's that calculates 74% (a solution I didn't really want to use as it uses magic numbers), it seemed to work "fine" on Mozilla at 786 x 1024, however I tested it on chrome at a slightly higher resolution (Can't remember it right now, will check the specific resolution and edit this part soon). I'm new to JavaScript and am under as to what would be the best practice to solve this problem across all browsers and resolutions
Would really appreciate if someone guided me around this problem. I'm open to using css,Javascript as well as jquery.
i would have deffently use $.position in here,
$("#Grass").position({
of: $(shuttle),
my: "top center",
at: "bottom center"
});
that will locate the the grass top line of the grass (its center), below the center of the bottom line on the shuttle
Why dont you develop a few constant values that can be applied to the actual rendered values of the grass image to adjust the placement. Something like:
Lets say the grass image is 500px x 237px but the height of the grass is only 158px – If we want the shuttle to sit right at the crown of the grass, it needs to be offset from the bottom of the screen by 158px – 158 divided by 237 works out (almost magically) to .66667
Since this is a fixed ratio, we can use .66667 to calculate the offset from the bottom of the screen for any size grass image, as long as we know the dimensions of the grass image by multiplying the height and .6667
$(function(){
var OFFSET = .66667; //this value is our shuttle adjustment constant
$( '#shuttle_1' ).css("bottom",($('#grass').height() * OFFSET)); //sets the bottom offset of the shuttle
$( '#shuttle_1' ).css("left",(($('#grass').width()/2)-($( '#shuttle_1' ).width()/2))); //centers the shuttle
});
Here is a JSfiddle demonstrating it.

Increase or decrease font size based on percentage change of height and width of an element

I want to adjust the font size of the text within an element as the element is resized. I managed to get it to resize the font fairly well with the width in this jsFiddle:
http://jsfiddle.net/jWKWS/3/
However, I can only resize it based on one dimension. I can either use the height percentage or I can use the width percentage. Is there away to take both dimensions into account with a single equation so that the size adjusts appropriately for both the height and the width?
How about basing it off area? Add:
percentageAreaDifference = (1-percentageWidthDifference)*(1-percentageHeightDifference)
and then
newFontSize = startingFontSize * percentageAreaDifference;
Although you might want to play with it; I suspect that will shrink/grow the font a little faster than needed. You might want to make that:
newFontSize = startingFontSize * Math.sqrt(percentageAreaDifference);
Since changing the font size actually shrinks it along both dimensions, and so a 50% decrease in font size decreases the area a character occupies by 75% (roughly).
I think you just need to change the newfontsize calculation to:
newFontSize = startingFontSize + (startingFontSize * (percentageWidthDifference + percentageHeightDifference ));
If width decreases a lot, and height increases a little, net decrease. And vice versa. Presumeably you want to keep the text contained in the box, however, and reflow is going to bite you there. Not sure how you would keep it contained with certainty
I put far more time into this than I care to admit but a friend and I finally figured out the best way to scale text with an element. You have to calculate the 2-dimensional diagonal using Pythagorean Theorem and get the percentage differences from the diagonal.
var diagonal = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
Just calculate it once for the original size and again for the new size, then get the percentage difference.
var percentage = (newDiagonal - oldDiagonal) / newDiagonal;
Then simply increase the font size by the same percentage.
var newFontSize = oldFontSize + (oldFontSize * percentage);
The other option is to skip all the crappy math and use this plugin we wrote:
jquery.dynamiText
I think you might want the sqrt of the area (as a multiple of the original area). Demo in this jsfiddle.
The key lines are (in the var statement):
newArea = newWidth*newHeight,
origArea = startingWidth*startingHeight,
areaDiff = (newArea/origArea),
newFontSize = (startingFontSize * Math.sqrt(areaDiff));
The sqrt is used because the area taken up by a character is roughly proportional to the font size squared. So the total area needed for N characters is ~[(f1/f0)^2]N. So the square root of the area 'factor' gives a measure of the new font size factor to use.
A worked example; if the new width is 1.2x the old width, and the new height is 1.5x the old height, the new area is 1.8x the old area. This formula then says the new font size should be 1.34x the old font size. And it seems to work.

Categories