目录
方案一:transform
思路:设置外层根元素的宽高,同时采用transform对该元素及其子元素进行缩放transform:scale(scaleRate),使该元素宽度适配当前窗口
缩放的倍数scaleRate有以下两种情况:
当屏幕宽高比<=16:9时
按照1920:1080计算,固定父元素width=1920px,height=1080px, 根据宽度缩小比例进行缩小。
步骤:屏幕的可视宽度rootWidth,屏幕缩放倍数 scaleRate=rootWidth/1920,此时Dom应显示的高度为1080 * scaleRate。父元素设置transform:scale(scaleRate)(此时屏幕底部会有一些空白)
当屏幕宽高比>16:9时
当屏幕宽高比>16:9时,1080*scaleRate > 实际高度,当前屏幕放不下,此时scaleRate按照高度计算,scaleRate=rootHeight/1080, width=rootWidth/scaleRate(因为transform:scale时会缩放,相当于Dom最后显示的宽度=rootWidth/scaleRate*scaleRate=rootWidth,此时屏幕水平方向的间距会比较大)
<template>
<div class="home">
<div class="num">
<div>123</div>
<div>456</div>
</div>
</div>
</template>
<script>
export default {
name: "HomeView",
components: {},
data() {
return {};
},
mounted() {
this.resizeWindow();
window.addEventListener("resize", this.resizeWindow);
},
beforeDestroy() {
window.removeEventListener("resize", this.resizeWindow);
},
methods: {
resizeWindow() {
console.log("resize---");
let rootWidth = document.documentElement.clientWidth;
let rootHeight = document.documentElement.clientHeight;
let scaleRate = (rootWidth / 1920).toFixed(3) * 1;
// console.log(rootWidth, rootHeight, scaleRate);
// console.log(1920 * scaleRate, 1080 * scaleRate);
let targetDom = document.getElementsByClassName("home")[0];
// 当按照scale进行高度缩放时,缩放高度大于实际窗口高度,此时按照实际高度进行缩放
if (1080 * scaleRate > rootHeight) {
scaleRate = (rootHeight / 1080).toFixed(3) * 1;
// console.log(1920 * scaleRate, 1080 * scaleRate, scaleRate);
targetDom.style.width = `${rootWidth / scaleRate}px`;
}
else{
targetDom.style.width = '1920px'
}
targetDom.style.transform = `scale(${scaleRate})`;
},
},
};
</script>
<style scoped>
.home {
width: 1920px;
height: 1080px;
padding: 20px;
border: solid 5px #999;
font-size: 24px;
transform-origin: left top;
}
.num {
display: flex;
justify-content: space-between;
}
</style>
屏幕宽高比小于16:9
屏幕宽高比=16:9
屏幕宽高比大于16:9
放入地图
home.vue
1.设置resize全局监听,引入Amap组件
amap.vue
id=mapContainer节点作为地图的容器
踩坑:设置#mapContainer{width:100%;height: 100%},这样设置地图继承了父节点宽高,但是出现了一个问题,使用海量点渲染,点击事件不生效(LabelsLayer、LabelMarker),这是因为父元素的transform:scale改变了标注的位置
解决方法:父节点scale(x)倍,mapContainer也scale(1/x)倍,并把该节点设置为position:absolute,父元素设置 overflow: hidden;
//home.vue
<template>
<div class="home">
<Amap></Amap>
</div>
</template>
<script>
import Amap from "./amap";
import { resizeWindow } from "@/utils/resize.js";
import { onMounted, onBeforeUnmount } from "vue";
export default {
name: "HomeView",
components: { Amap },
data() {
return {};
},
setup() {
onMounted(() => {
resizeWindow();
window.addEventListener("resize", resizeWindow);
});
onBeforeUnmount(() => {
window.removeEventListener("resize", resizeWindow);
});
},
};
</script>
<style scoped>
.home {
width: 1920px;
height: 1080px;
font-size: 24px;
transform-origin: left top;
position: relative;
overflow: hidden;
}
</style>
//amap.vue
<template>
<div id="mapContainer"></div>
</template>
<script>
</script>
<style lang="less" scoped>
#mapContainer {
position: absolute;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
}
</style>
//resize.js
export function resizeWindow() {
//home节点的缩放,参考上面的缩放代码
......
//mapContainer节点
// 父级元素缩小的同时,放大地图,是地图根元素的transform:scale(1),这样地图上的marker标注才不会偏移
let mapContainer = document.getElementById('mapContainer')
let scaleRateReverse = (1 / scaleRate).toFixed(5) * 1
mapContainer.style.transform = `scale(${scaleRateReverse})`;
}