实现原理
通过获取页面显示内容的比例,去跟项目自己设置的比例比较,然后算出缩放比例,通过给相应节点设置scal 来缩放实现等比适配
实现页面等比例显示,重点是两个知识点getBoundingClientRect()和transform: scale(x)。
getBoundingClientRect()
是用于获取某个元素相对于视窗的位置集合。集合中有top, right, bottom, left等属性。
#不需要传参数
rectObject = object.getBoundingClientRect();
# 可以拿到这些返回值
/*
rectObject.top:元素上边到视窗上边的距离;
rectObject.right:元素右边到视窗左边的距离;
rectObject.bottom:元素下边到视窗上边的距离;
rectObject.left:元素左边到视窗左边的距离;
rectObject.width:元素自身的宽度;
rectObject.height:元素自身的高度;
*/
transform: scale()
是用于元素的缩放,不懂得可自行百度
实现方法
1、创建一个页面节点
<template>
<!-- cont 总是按高度或宽度铺满屏幕(cover) -->
<div ref="cont" class="fit-screen-cont" >
<!-- content 通过 scale(实际尺寸/设计尺寸) 来缩放实现等比适配 -->
<div class="fit-content" :style="getFitContentStyle()" >
<slot ref="content" class="fit-content"></slot>
</div>
</div>
</template>
2、缩放方法,算出页面缩放比例
updateScaleRatio(){
var rect = this.$refs.cont && this.$refs.cont.getBoundingClientRect();
var ratio = rect.width / rect.height;
var innerRatio = this.width / this.height;
if(ratio < innerRatio){
//Scale width
var scaleRatio = rect.width/ this.width ;
this.currentRatio = scaleRatio;
}
else{
scaleRatio = rect.height / this.height ;
this.currentRatio = scaleRatio;
}
},
3、实现节点缩放的方法,将此方法绑定在创建的页面节点上
getFitContentStyle(){
return {
width:this.width + 'px',
height:this.height + 'px',
transform:`scale(${this.currentRatio})`
}
}
4、通过页面监听页面变化和页面进入默认调用该方法,达到动态调节
mounted(){
window.addEventListener('resize',()=>{
this.updateScaleRatio();
})
this.updateScaleRatio();
},
完整代码
<template>
<!-- cont 总是按高度或宽度铺满屏幕(cover) -->
<div ref="cont" class="fit-screen-cont" >
<!-- content 通过 scale(实际尺寸/设计尺寸) 来缩放实现等比适配 -->
<div class="fit-content" :style="getFitContentStyle()" >
<slot ref="content" class="fit-content"></slot>
</div>
</div>
</template>
<script>
export default {
data(){
return {
width:1920,
height:1080,
currentRatio:1
}
},
mounted(){
window.addEventListener('resize',()=>{
this.updateScaleRatio();
})
this.updateScaleRatio();
},
methods:{
updateScaleRatio(){
var rect = this.$refs.cont && this.$refs.cont.getBoundingClientRect();
var ratio = rect.width / rect.height;
var innerRatio = this.width / this.height;
if(ratio < innerRatio){
//Scale width
var scaleRatio = rect.width/ this.width ;
this.currentRatio = scaleRatio;
}
else{
scaleRatio = rect.height / this.height ;
this.currentRatio = scaleRatio;
}
},
getFitContentStyle(){
return {
width:this.width + 'px',
height:this.height + 'px',
transform:`scale(${this.currentRatio})`
}
}
}
}
</script>
<style lang="scss" scoped>
.fit-screen-cont{
display:flex;
justify-content: center;
align-items: center;
width:100%;
height:100%;
flex:1;
overflow:hidden;
.fit-content{
flex:1;
transform-origin: center;
overflow: hidden;
position: absolute;
}
}
</style>