I'm trying to make the object-fit: cover (or background-size: cover if it were an image) using an iframe with a vimeo video. As vimeo adjusts the video size according to the iframe width/height/aspect-ratio I thought that using the transform: scale
property could be achieved.
Right know I have this logic to scale an iframe with a vimeo video, in most of the cases does the job (covers the screen) but it's not perfect:
const w = window.innerWidth
const h = window.innerHeight
const ratioVideo = 640 / 360
const ratioScreen = w / h
const calculatedRatio = ratioVideo / ratioScreen
// minimum scale value
const minRatio = 1.45
scaleVideo = calculatedRatio > minRatio ? calculatedRatio : minRatio
And then I have:
<iframe :style="`transform:scale(${scaleVideo})`"..>
but it won't fill completely the viewport, expecially when the viewport ratio is < 1 (landscape with much more width than height)
How would be the right calculation (of the minimun scale transform value) for every resolution? I guess i have the separete the portrait/landscape but can't find the key
Any thoughts?
-EDIT-
Here is a codepen with my current code if it helps to understand (in vanilla js because i'm using vuejs in my environment)
-UPDATE-
This updated codepen almost achieves what i mean, but for reason i have to add a small percentage to the caculated ratio, I guess it's becuase the scroll bars or something? code preview:
let calculate = function () {
const w = window.innerWidth
const h = window.innerHeight
const ratioVideo = 640 / 360
const ratioScreen = w / h
if (ratioScreen > ratioVideo) {
calculatedRatio = ratioScreen / ratioVideo
} else {
calculatedRatio = ratioVideo / ratioScreen
}
/* a little % more */
calculatedRatio = calculatedRatio * 1.07
document.documentElement.style.setProperty('--s', calculatedRatio);
}
If you remove centering code from CSS, your demo works. See this pen
.video {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
:root {
--s: 1;
}
.video__player {
position: absolute;
width: 100%;
height: 100%;
transform: scale(var(--s));
}
let calculate = function () {
const w = window.innerWidth
const h = window.innerHeight
const ratioVideo = 640 / 360
const ratioScreen = w / h
const calculatedRatio = Math.max(ratioScreen, ratioVideo) / Math.min(ratioScreen, ratioVideo);
document.documentElement.style.setProperty('--s', calculatedRatio);
console.log(calculatedRatio)
}
calculate()
window.onresize = () => {
calculate()
}
Explanation: your iframe is set at 100% width/height, meaning it's technically already centered to the viewport. When using transform: scale
function without specifying transform-origin
, default value will be 50% 50% meaning it will scale from center of that element and not top left corner.