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!
Related
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.
I'm trying to do and image highlight. So I take pdf image preview and based on the field (extracted from pdf) the user clicks, it will highlight the field in the image preview.
Im trying to accomplish this using css where a have rectangle at the bottom of the image and just set a margin based on the field position that will highlight that field in the pdf image preview.
The problem is that I can't quite get the conversion right for my margins.
So I know there 72pt in an inch and 96 pixels in an inch.
Don't really know where to take it form there. Should I also consider the user's resolution? Is there a library I can use?
So far what I have given:
field positions (in points),
pdf max height/width (in points),
image preview max height/width (in pixels)
How can I convert the field position to pixels so I can highlight that field in the image preview?
Convert points to pixels.
pdfPointsH / pdfPixelsH = x
pdfPointsW / pdfPixelsW = y
Use proportion to translate Point coordinates into Pixel coordinates e.g.:
PointX * x = PixelX
PointY * y = PixelY
Hope that helps.
I'm have a heat map application and store I store the x,y coordinates of a click and also the viewport width and height. Real data for 2 clicks:
x, y, width, height
433, 343, 1257, 959
331, 823, 1257, 959
The issue is when I resize the screen on the responsive site, the displayed clicks are now all off. I'm coming up empty on my searches but is there a formula or algorithm to recalculate the x and y coordinates for different resolutions. For example, the first click, if the width goes from 1257 to 990 and the height goes from 959 to 400, how to I recalculate the x and y so they line up in the same spot?
EDIT:
I added 2 fields to the database, width_percentage and height percentage
to store the x percentage of the width and the y percentage of the height. So if x was 433 and the width of the screen was 1257 then x was 35% from the left edge of the screen. I then used the same theory for the height and ran the calculations but it did not scale the click dot to the same spot as I though the percentages would do for scaling resolutions. I testing this by clicking on full resolution 1257 width then reopening at 900 width. See below for code to display click dots at lower resolution.
Ajax PHP
while ($row = mysql_fetch_array($results)) {
if( $_GET['w'] < $row['width'] ) {
$xcorr = $row['width_percentage'] * $_GET['w'];
$ycorr = $row['y'];
}
}
This uses the $_GET variable, passing the width and height of the screen resolution on page load. Then it gets the click dots from the database as $results. Since I only scale the resolution width from 1257 to 900 I did not put in calculation for height and its the same pixel as the initial click. The new width I multiplied by the percentage and set the dot that percentage margin from the left of the screen. Since the percentage is 35%
the new x coordinate becomes 900 *.35 = 315px from the left edge. It did not work and I'm still scratching my head on head to keep click in the same spot for responsive sites.
Have you tried this mathematical formula to change the range of a number?
And also instead of storing this:
x, y, width, height
433, 343, 1257, 959
331, 823, 1257, 959
You could store it normalized between 0 and 1 so it works for any width/height (calculated by dividing each x by its width and each y by its height):
x, y
0.344, 0.357
0.263, 0.858
Then you don't need to know the width/height you used when you stored them, and when you want to translate them to the size of the current screen you just multiply each one by the current width/height
You can acheive this by jquery:
$( window ).resize(function() {
//ur code
});
javascript
window.onresize = resize;
function resize()
{
alert("resize event detected!");
}
if you are working on mobile devices use this one also
$(window).on("orientationchange",function(event){
alert("Orientation is: " + event.orientation);
});
I think you are on the right track with the percentages. Are you including the offset of the map image. I wonder if your algo is working but the visual representation appears wrong because the offset is changing in the viewport.
$(window).resize(function() {
var offset = yourMap.offset();
myLeft = offset.left();
myTop = offset.top();
});
You need to add the offsets every time to get the proper placement.
This is what you should do. Sometimes the resize event fires when the document is being parsed. It is a good idea to put the code inside an onload event function. The orientation change function is taken from #Arun answer.
window.onload = function() {
$(window).on("orientationchange", function(event) {
alert("Orientation is: " + event.orientation);
});
window.onresize = function() {
alert('window resized; recalculate');
};
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
for this you need to do some calculation. Here is the function which will return new x and y potion based on the height and width
function getNewX(xVlaue, oldWidth, newWidth){
return xVlaue * newWidth / oldWidth;
}
newX = getNewX(10, 150, 100); // Use
You can use the common function for height and width calc.
DEMO
The whole question highly depends on the page you want to use this on.
Most pages have a centered block and/or some self-resizing (read "responsive") elements. If the page is not very responsive, e.g. having a fixed width, you have an easier job. If the page is centered, you might want to save the cursor's X-position relative to the center of the page. this way the window width doesn't matter. The same also applies to left- and right aligned pages of course - in this case you would save the X-pos relative to the left or right edge of the window respectively.
The following image shows a center-oriented click position. Note that the x- and y properties of the click don't change here if you resize the window.
Now to the more generic methods
If you save the window dimensions, the cursor position AND the scroll offsets on every click, you will most probably be able to reproduce it alongside the layout, but you'll need to reproduce it for every unique dimensions set. If you used the trick from above you might be able to overlay all layouts and find a common denominator. For example, if your page is centered in the window, has a max-width, and you saved the X-pos relative to the center of the window, you can overlay all clicks that happened in windows that were at least that width.
You could do some trickery however, and save the clicked elements alongside the informations you already do save. If you also save the click position relative to the element, you can evaluate this data to something like "the submit button is rather pressed on the bottom right side" or "people often click on the far end of that drop-down and sometimes mis-click by a few pixels".
Try both of the following:
1. Padding and margins might not scale. Use "* {padding:0;margin:0}" at the end of your stylesheet and check if that fixes it.
2. Ensure outer and inner (that means all) elements scale. Any single element failing to scale will make many other elements fall out of place. This generally happens with text inputs. Use "*{border:solid 2}" at the end of your stylesheet to visually observe the effect of scaling on each element.
I'm sure your problem will be resolved.
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.
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.