Scaling an iFrame depending on window size and content size - javascript

I have a dynamically generated iFrame on my page that loads a website using a variable object.
All that is well understood. My challenge now is that in some cases, say if I am viewing on mobile, the frame width exceeds my mobile device width.
// STATIC VALUE
let screenSize = {
"height": window.innerHeight,
"width" window.innerWidth:
}
// DYNAMICALLY GENERATED VARIABLE
let frameValue = {
"url": "https://example.com",
"height": 913,
"width": 1600
}
//Using this variable, the iframe property is set as follows using javascript
$('#dynamicFrame').attr('src', frameValue.url);
$('#dynamicFrame').width(frameValue.width);
$('#dynamicFrame').height(frameValue.height);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- HTML DYNAMIC iFRAME -->
<iframe src="" id="dynamicFrame" frameBorder="0" width="100%" height="100%" scrolling="auto"> </iframe>
Need:
I would like an algorithm (or perhaps some code) to perhaps scale or zoom the iframe whilst keeping its aspect ratio.
Meaning I want the content to of frameValue.url (example.com) to load in the iframe as it would while considering frameValue.width & frameValue.height.
Notes:
I don't mind having the iframe look smaller or have dark bands around the edge just like when you watch videos on a mobile device or use zoom or Microsoft teams on a mobile device whilst the person sharing the screen is on a desktop device.
Please feel free to comment if you need further explanation. Thank you.

Is there any reason you aren't using a CSS solution? It'd be a much cleaner solution than setting the height/width attributes.
#dynamicFrame {
/* Swap for your desired aspect ratio */
aspect-ratio 16/9;
width: 100%;
height: auto;
}

Depending on the screen size and orientation, one of the following formulas may be useful.
NB:The orientation can be determined using the dimensions provided. i.e landcape = width > height
let scale = 0;
// If the window is potrait and the frame is landscape orientation
scale = screenSize.height * (1 / frameValue.height);
// If the window is landscape and the frame is potrait, one of the following applies.
scale = dimensions.height/dimensions.width).toFixed(2);
// OR
scale = dimensions.width/dimensions.height).toFixed(2);
// Set the iFrame Dynamic Scale Value
iframe.style.transform = `scale(${scale})`;

Related

Can I determine the actual width/height of an element on a web page?

To illustrate my question, here is a not-real example:
<img src='myimage-low.png' style='width: 150px;'>
<img src='myimage-high.png' style='width: 150px;'>
myimage-low.png is 150px x 100px
myimage-high.png is 1500px x 1000px
When I am zoomed all the way out on the web page, both images look the same. When I zoom in, the high definition image looks much better.
If I use javascript to get the image width with $(elem).width();, it says (as I would expect) 150px for both, regardless of the zoom.
Is there a way in javascript to get the actual screen size of the element as presented to the user? In my above example, they might both say "100px" when I'm fully zoomed out, and "1000px" when I'm fully zoomed in.
Note - I need to be able to need this for both <img> elements as well as any element that might have a css background-image.
For context, this is to determine which resolution of an image to load. There's no point in loading the 1500px if the user is on a low resolution and it will just be resized in the browser to 300px - they might as well have the 500px version which is faster to download.
Say hello to window.devicePixelRatio:
var el = document.querySelector('img');
function getElemSize(el) {
var rect = el.getBoundingClientRect();
return {
width: Math.round(rect.width * window.devicePixelRatio),
height: Math.round(rect.height * window.devicePixelRatio)
};
}
function updateSize() {
var size = getElemSize(el);
document.querySelector('p').innerHTML = JSON.stringify(size);
}
el.addEventListener('load', updateSize);
addEventListener('resize', updateSize);
<img src="https://howitworks.wpengine.com/wp-content/uploads/2015/09/214887-puppies-cute-puppy.jpg" style="width: 150px">
<p></p>
You can use the visualViewport API to multiply the width by the scale if you're looking for pinch zoom:
const { scale } = window.visualViewport;
const width = $(elem).width() * scale;
I tried adding a snippet for an example, but according to the spec the window.visualViewport.scale inside of an iframe is always 1. As long as your content is not in an iframe, this method will work for giving you the scale of the pinch zoom (tested in my browser console)

Understanding orientation, aspect ratio and CSS pixels on mobile devices

For my current project, I need to optimize a page layout in landscape mode for mobile devices. Can you help me to understand the different ways that the browser window size is measured?
I am working with an Android smartphone with hardware pixel dimensions of 720 x 1280 pixels.
Portrait Mode
In portrait mode, when I use JavaScript to get the document.documentElement.clientWidth and ~Height, I get the result 980 x 1394.
When I use the following CSS...
html {
height: 100vh;
width: 100vw;
}
body {
height: 100%;
width: 100%;
margin: 0;
}
... Chrome Development Tools reports that the size of the body is 980 x 1546.
Landscape Mode
In landscape mode, things seem even more complex. In my test, I explicitly CSS set the dimensions of the whole <html> tag to 100vw x 100vh, and the body width and height to 100%.
However, JavaScript reports the clientWidth and clientHeight as 980 x 460, while Chrome Development tools shows the dimensions of the html and body elements as 980px x 556px, although neither of these elements fills the screen width or height.
A <main> element whose width is set to 200vh and whose height is set to 100vh fills the entire width of the screen in landscape mode, but leaves a gap in the vertical direction, despite the fact that Chrome reports it to have dimensions of 1112px x 556px.
It would also be very helpful to know what exactly the different dimension properties are measuring, so that I can understand how they should be used.
EDIT:
To reply to #Kaddath: No, I had not configured a viewport meta tag. When I add the tag <meta name = "viewport" content = "width = device-width, initial-scale = 1.0">, the dimensions change. In particular the `` clienttWidth in portrait mode becomes the screen width in hardware pixels, divided by the devicePixelRatio, which makes perfect sense. The clientHeight appears to be the height of the screen in CSS pixels, minus the height of the app bar and the built-in button bar.
In portrait mode, the values for clientWidth and clientHeight are not so easy to explain.
To better understand how browser work on different situation try to call you function with
setTimeout(showSize,300);
onresize doesn't fire correctly on all browsers.
Also try window.outerWidth and window.outerHeight.
It is very much to explain but you will learn.
You can also read https://developers.google.com/web/fundamentals/native-hardware/fullscreen/

React Page Getting Weird Scaling in Responsive Mode [duplicate]

When in google chrome's device mode, what does window.innerWidth return? Is it the viewport of the device (plus any scroll bars)?
I'm getting different values for the device's width x height (the dimensions on top of the page - the device's viewport?) and window.innerWidth x window.innerHeight (browser's viewport?). Is this supposed to happen?
Here's a picture of what I'm getting, and the code I used.
<!doctype html>
<html>
<head></head>
<body>
<script>
var image;
window.onload = function() {
image = document.getElementById("img");
checkWindowSize();
window.addEventListener('resize', function(event){
checkWindowSize();
});
}
function checkWindowSize() {
var width = window.innerWidth,
height = window.innerHeight;
console.log("window.innerHeight: ", window.innerHeight, " window.innerWidth: ", window.innerWidth);
}
</script>
<img id="img" class="vid-img-filter" src="http://i.imgur.com/jkhFJMn.jpg" alt="">
</body>
</html>
window.innerWidth and innerHeight return the dimensions of the visual viewport. In desktop browsers, this is generally the browser's window dimensions. On mobile the situation is a bit more complicated because of pinch zoom.
When you load a page without a <meta name="viewport"> tag, a default layout width is used (e.g. Chrome uses 980px). When the browser loads the page it does so maximally zoomed out. It looks like your device size above has a width of 425px so the browser zooms out when the page is loaded to see the whole 980px. If you have content that's wider than this (e.g. your image) it'll zoom out even further. Seeing as how your window.innerWidth is 1248, that implies a scale factor of about 30%.
tl;dr: innerWidth/innerHeight reflect viewport with the pinch-zoom factor applied and the page is loaded fully zoomed out.
EDIT: This has since changed in Chrome. window.innerWidth now returns the layout viewport width. To get the visual viewport width, use window.visualViewport.width. See this article for more details.
I'm not sure if this is a recent update (since the last responses), but I was able to find the viewport height/width by using:
window.screen.width
and
window.screen.height
This was particularly useful when I was trying to test whether the screen was phone-sized or not.
We're currently having success with something like:
const widths = [window.innerWidth];
if (window.screen?.width) {
widths.push(window.screen?.width);
}
const width = Math.min(...widths);
The conditional check is there because I'm not sure how widespread the screen width API is. You may need to adjust this not to use certain newer JS features depending on what devices you are targeting/your build process.
This could potentially go a bit weird if you have a window that is wider than the screen, but for us that isn't a problem.
This gives us a width that matches the one at the top of the Responsive screen tool, even when contents overflow horizontally. This is important for us because we needed the UI to change in order to prevent that overflow, but the overflow was interfering with the width number we used to trigger the adjustment.
I'm not sure if this is important, but we are also using:
<meta name="viewport" content="width=device-width, initial-scale=1" />

Website Needs to auto resize every element on the page like images and fonts

I've got a page that has a variety of text and images placed on the page. When the users resizes their window (or users that simply have different resolutions), the design needs to have everything scale proportionally. So I created this jQuery function that triggers on resize (or when page loads) and I look at every element I've put on that page so far and resize it based on the aspect ratio.
Like this:
theWindow.resize(function() {
resizeBg();
}).trigger("resize");
As I add more and more to the page it is extremely tedious. Every padding, margin, font-size, width, height, etc. needs to be resized based on that ratio.
Is there a jQuery plug-in or some other suggestion that would help with this?
Thank you.
Think of it like this, when a user resizes the window, JQuery runs a function.
$(window).resize(function()
{
var Width = $(document).width();
var Height = $(document).height();
$('body').css({"height" : Height, "width" : Width});
}
Or The easy way in CSS,
body
{
width:100%;
height:100%;
}

Raphael canvas filling a container div

Instead of specifying the width and height of a Raphael canvas, I need it to be 100% the size of its container. So I could just do a Raphael("container", containerElement.width, containerElement.height) and set the onresize function to reset those values. But then the content gets very jumpy and hectic as I resize the window or container because the scrollbars (which I want if it gets too small) flash in and out of existence.
Is this the proper way to bind Raphael's canvas to the full size of a container? I'd also like to provide the option to make the Raphael canvas "full screen" taking up the entire browser window.
If you are using a div then you could use CSS to set that to 100% of the width and height. You then use the Raphael("container", "100%", "100%")
As for making it full screen, most browsers have a command to do this. So if you really are doing 100% then when you press the command button e.g. (F11 in firefox) it will become FULL screen.
Raphael("container", "100%", "100%"); will fill the canvas to width/height of the DIV container. This works fine in Chrome and Safari. To get Firefox on board you'll need to give body and html 100% width/height in the css, otherwise the vector will be clipped.
A little bit late on this one but I'll post here for other people searching.
var h = $('container').height(); //get the container height into variable h
var w = $('container').width(); //get the container width into variable w
//set your Raphael canvas to the variables
var contpaper = Raphael("container", w, h);
var doit;
//function to reload the page and/or do other adjustments
function resizedw(){
document.location.reload()
}
//call function 200 ms after resize is complete.
$(window).resize(function(){clearTimeout(doit);
doit = setTimeout(function() {
resizedw();
}, 200)});
This solution is cross browser and mobile safe so you can use this to incorporate responsive design. By adding caveats for viewport width or height to your javascript in the form of if statements, you can define all of your shapes based on the same variables.

Categories

Resources