Is it possible to scale a whole fixed-with page depending on the user's resolution? - screen-resolution

Is it possible to make a page for 1600px900px with all measurements fixed as pixels and then adding code to scale everything down if the users width is too little?
I'm not asking for fluid CSS as I already made a fix-width page. I can't change all the measurements, but still need to find a way to scale the content down for smaller monitors.

This code did the trick.
document.body.style.zoom = screen.width / 1600 + '';
document.body.style.MozTransform = screen.width / 1600 + '';
document.body.style.MozTransformOrigin = '0 0';
document.body.style.OTransform = screen.width / 1600 + '';
document.body.style.OTransformOrigin = '0 0';
document.body.style.WebkitTransform = screen.width / 1600 + '';
document.body.style.WebkitTransformOrigin = '0 0';

Related

Calculating physical distance scrolled from scrollWheel NSEvent

Making my first Swift app for macOS. Learning as I go...
I'm trying to make an app that calculates the total physical distance scrolled from a scrollwheel NSEvent handler. I'm using this code to attach the event handler:
NSEvent.addGlobalMonitorForEvents(matching: NSEvent.EventTypeMask.scrollWheel, handler: self.scrollWheel);
I'm getting the absolute deltaY value in the event handler by using let deltaY = abs(event.scrollingDeltaY)
I'm guessing the deltaY is reported in points, but how do I translate it to a physical distance (in inch)?
I'm manually calculating the ppi for the user's device using this code:
let width = NSScreen.main?.frame.width ?? 0
let height = NSScreen.main?.frame.height ?? 0
let diagonal = sqrt(pow(width, 2) + pow(height, 2))
let pixelsPerInch = ((width / CGDisplayScreenSize(CGMainDisplayID()).width) * 25.4) * CGFloat(NSScreen.main?.backingScaleFactor ?? 0
I'm using this formula to calculate the physical distance scrolled (in inches).
let distance = deltaY * 1 / pixelsPerInch * 40
The formula is hardcoded and obviously wrong. The multiplication by 40 is an approximation, as I have no idea if I'm on the right track. I'm looking for the right formula.
Any ideas?
Thanks in advance!
I believe you're close
CGDisplayScreenSize().width gives you the physical width in mm.
CGDisplayBounds().width gives you the width number of pixels.
And 1 inch = 25.4 mm
So:
let pixelsPerInch = CGDisplayBounds().width / ( CGDisplayScreenSize().width / 25.4 ))
...and...
let distance = deltaY / pixelsPerInch

Waveshare e-ink display - content faded when boxes drawn below

I'm using a Waveshare e-ink display (5x7) attached to a Pi Zero W via a HAT. I'm building the content from top to bottom.
As you can see from this photo (apologies for the reflection of the conservatory roof), all is fine up until this point :
However, if I then proceed to draw one or more boxes below the content, the weather icons fade out from right to left, like so :
The order in which I draw is irrelevant - it happens whether I draw the boxes then the weather data, or vice versa.
Relevant code is as follows :
# Draw one rectangle for top data
draw.rectangle([(0,0),(479,120)],outline = 0)
# And another for the tasks
draw.rectangle([(0,220),(239,700)],outline = 0)
# And a third for something else
draw.rectangle([(241,220),(479,700)],outline = 0)
# Draw the forecast (on a loop)
# If we have 400 pixels to play with, forecast covers next 5 hours, so 80 pixels per entry
i = 0
xoffset = 40
yoffset = 130
forecast = get_forecast()
while i < 5:
# Get the data
icon = get_icon(forecast[i]['icon'])
time = forecast[i]['time']
temperature = str(forecast[i]['temperature']) + u'\N{DEGREE SIGN}' + "C"
# Draw the forecast time
timewidth = forecastfont.getsize(time)[0]
textx = calculate_offset(xoffset, timewidth, xoffset)
texty = yoffset
draw.text((textx, texty), time, font = forecastfont, fill=0)
# Draw the forecast icon
iconwidth = weather24.getsize(icon)[0]
iconx = calculate_offset(xoffset, iconwidth, xoffset)
icony = yoffset + forecastfont.getsize(time)[1] + 5
draw.text((iconx, icony), icon, font = weather24, fill = 0)
# Draw the forecast temperature
tempwidth = temperaturefont.getsize(temperature)[0]
tempx = calculate_offset(xoffset, tempwidth, xoffset)
tempy = yoffset + forecastfont.getsize(time)[1] + weather24.getsize(icon)[1] + 5
draw.text((tempx, tempy), temperature, font = temperaturefont, fill=0)
# Advance the loop and move the offset
i += 1
xoffset += 60
My research appears to suggest that sleeping the display after writing should help, but I'm already doing that :
epd.display(epd.getbuffer(image))
epd.sleep()
This seems to be caused by too much light when the screen does update. It happends also once the screen is static but in reverse (screen darken with direct light).
It's a bit disapointing but you may want to move the screen in a darken place and especially avoid any direct lighting.
I noted this with a waveshare 7.5 v2 screen with esp32 drivers.

How to fit overlapping elements of fixed width within a certain space?

How can I evenly fit UI elements of a certain fixed width inside a fixed space on the screen? I want to calculate the position to the place the elements inside the space, without scaling or rotating the elements.
For eg: I want to fit the 4 cards which are 500 units in width inside the white space in the bottom which is 1000 units wide.
expected result: the four cards are placed such that they occupy 1000 units.
The expected result if there are eight cards.
card_offset = (total_width - card_width) / (number_of_cards - 1) * card_index;
Example:
1st card offset = (1000 - 500) / (4 - 1) * 0 = 0
2st card offset = (1000 - 500) / (4 - 1) * 1 = 167
3st card offset = (1000 - 500) / (4 - 1) * 2 = 334
4st card offset = (1000 - 500) / (4 - 1) * 3 = 500

iText7 Bug: Endless loop in ImageRenderer

i came across an endless-loop-issue due to floating point arithmetic in iText7 DotNet ImageRenderer.
I've added an image with 2464x3692 pixels to an PDF page area of 523x770 pixels, causing the Layout() function to loop endlessly because every iteration returned LayoutResult.NOTHING.
The main issue is that the image height is calculated inside the Layout-function using the following statement:
Line 90: height = (float)width / imageWidth * imageHeight;
Due to the floating point operation the height got a value of something like 770.0001.
This is greater than the area height, causing the loop to return LayoutResult.NOTHING, so the image gets autoscaled again.
Inside the AutoScale-function only the image width is checked, which IS inside the area boundaries and so nothing is scaled.
I've fixed this issue by changing the following code inside ImageRenderer.cs:
90 - height = (float)width / imageWidth * imageHeight;
90 + float? propHeight = RetrieveHeight();
91 + height = propHeight == null ? (float)width / imageWidth * imageHeight : propHeight.Value;
214 - SetProperty(Property.HEIGHT, UnitValue.CreatePointValue(area.GetBBox().GetHeight()));
215 + SetProperty(Property.HEIGHT, area.GetBBox().GetHeight());
ImageRenderer now uses the height that is set inside AutoScale without recalculating it if not necessary.
Hopefully this will be fixed in one of the next releases. :)
Regards
Yosh

Map distance to zoom in Google Static Maps

I am using Google Static Maps to display maps in my AppleTV app. What I need is to somehow map a distance of e.g. 1km to the zoom parameter of the Static Maps API.
In other words I have an imageView in which I wish to load the map image and if I know that the height of my imageView is 400px, and I wish for this map to show a real Earth surface of 1000m North to South, how would I tell the API to return me the map with this exact zoom?
I found a very similar question here, however no suitable answer is provided.
As stated at Google Maps Documentation:
Because the basic Mercator Google Maps tile is 256 x 256 pixels.
Also note that every zoom level, the map has 2 n tiles.
Meaning that at zoomLevel 2,the pixels in any direction of a map are = 256 * 2² = 1024px.
Taking into account that the earth has a perimeter of ~40,000 kilometers, in zoom 0, every pixel ~= 40,000 km/256 = 156.25 km
At zoom 9, pixels are 131072: 1px = 40,000 km / 131072 = 0.305 km ... and so on.
If we want 400px = 1km, we have to choose the closest approximation possible, so: 1px = 1km/400 = 0.0025km
I tried zoom = 15 and obtained 1px = 0.00478 and zoom = 16 that gave me 1px = 0.00238km
Meaning that you should use zoom = 16, and you will have 0.955km every 400px in the Equator line and only for x coordinates.
As you go north or south in latitude, perimeter is everytime smaller, thus changing the distance. And of course it also changes the correlation in the y axis as the projection of a sphere is tricky.
If you want to calculate with a function the exact distance, you should use the one provided by Google at their documentation:
// Describe the Gall-Peters projection used by these tiles.
gallPetersMapType.projection = {
fromLatLngToPoint: function(latLng) {
var latRadians = latLng.lat() * Math.PI / 180;
return new google.maps.Point(
GALL_PETERS_RANGE_X * (0.5 + latLng.lng() / 360),
GALL_PETERS_RANGE_Y * (0.5 - 0.5 * Math.sin(latRadians)));
},
fromPointToLatLng: function(point, noWrap) {
var x = point.x / GALL_PETERS_RANGE_X;
var y = Math.max(0, Math.min(1, point.y / GALL_PETERS_RANGE_Y));
return new google.maps.LatLng(
Math.asin(1 - 2 * y) * 180 / Math.PI,
-180 + 360 * x,
noWrap);
}
};