计算缩放值以转换 iframe 以覆盖其在视口中的内容
Calculating the scale value to transform an iframe to cover it's content in the viewport
我正在尝试使用带有 vimeo 视频的 iframe 使对象适合:封面(或背景大小:封面,如果它是图像)。由于vimeo根据iframe调整视频大小width/height/aspect-ratio我认为使用transform: scale
属性可以实现。
我知道我有这个逻辑来缩放带有 vimeo 视频的 iframe,在大多数情况下都能完成工作(覆盖屏幕)但它并不完美:
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
然后我有:
<iframe :style="`transform:scale(${scaleVideo})`"..>
但它不会完全填满视口,特别是当视口比小于 1 时(宽度比高度大得多的风景)
如何正确计算每种分辨率的(最小比例变换值)?我想我有单独的 portrait/landscape 但找不到钥匙
有什么想法吗?
-编辑-
这是我当前代码的 codepen 如果它有助于理解(在 vanilla js 中,因为我在我的环境中使用 vuejs)
-更新-
更新后的 codepen 几乎达到了我的意思,但出于某种原因,我不得不在计算的比率中添加一个小百分比,我猜这是因为滚动条之类的?代码预览:
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);
}
如果您从 CSS 中删除居中代码,您的演示就可以运行。 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()
}
说明:您的 iframe 设置为 100% width/height,这意味着它在技术上已经居中于视口。当使用 transform: scale
函数而不指定 transform-origin
时,默认值将为 50% 50%,这意味着它将从该元素的中心而不是左上角开始缩放。
我正在尝试使用带有 vimeo 视频的 iframe 使对象适合:封面(或背景大小:封面,如果它是图像)。由于vimeo根据iframe调整视频大小width/height/aspect-ratio我认为使用transform: scale
属性可以实现。
我知道我有这个逻辑来缩放带有 vimeo 视频的 iframe,在大多数情况下都能完成工作(覆盖屏幕)但它并不完美:
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
然后我有:
<iframe :style="`transform:scale(${scaleVideo})`"..>
但它不会完全填满视口,特别是当视口比小于 1 时(宽度比高度大得多的风景)
如何正确计算每种分辨率的(最小比例变换值)?我想我有单独的 portrait/landscape 但找不到钥匙
有什么想法吗?
-编辑-
这是我当前代码的 codepen 如果它有助于理解(在 vanilla js 中,因为我在我的环境中使用 vuejs)
-更新-
更新后的 codepen 几乎达到了我的意思,但出于某种原因,我不得不在计算的比率中添加一个小百分比,我猜这是因为滚动条之类的?代码预览:
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);
}
如果您从 CSS 中删除居中代码,您的演示就可以运行。 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()
}
说明:您的 iframe 设置为 100% width/height,这意味着它在技术上已经居中于视口。当使用 transform: scale
函数而不指定 transform-origin
时,默认值将为 50% 50%,这意味着它将从该元素的中心而不是左上角开始缩放。