<template>
<div class="layout" sname="ok2">
<slot />
<div class="vitural-view">
<resize-observer @notify="handleResize" />
</div>
</div>
</template>
<script>
// 缩放自适应
import { ResizeObserver } from 'vue-resize'
const min = Math.min;
const max = Math.max;
const round = Math.round;
export default {
data() {
return {
currentScaleW: null,
currentScaleH: null,
currentWidth: null,
currentHeight: null,
}
},
props: {
width: {
type: Number,
require: true,
},
height: {
type: Number,
require: true,
},
scaleType: {
type: String,
validator(value) {
return ['width', 'height', 'min', 'max', 'contain'].indexOf(value) !== -1;
},
}
},
components: {
'resize-observer': ResizeObserver
},
methods: {
handleResize() {
const size = this.getWindowSize();
const scaleW = size.width / this.width;
const scaleH = size.height / this.height;
let _scaleW = null;
let _scaleH = null;
switch (this.scaleType) {
case 'width':
_scaleW = scaleW;
_scaleH = scaleW;
break;
case 'height':
_scaleW = scaleH;
_scaleH = scaleH;
break;
case 'max':
_scaleW = max(scaleW, scaleH);
_scaleH = max(scaleW, scaleH);
break;
case 'contain':
_scaleW = scaleW;
_scaleH = scaleH;
break;
case 'min':
default:
_scaleW = min(scaleW, scaleH);
_scaleH = min(scaleW, scaleH);
break;
}
this.handleTranslate(_scaleW, _scaleH);
if (_scaleW === this.currentScaleW && _scaleH === this.currentScaleH) return;
this.scale(_scaleW, _scaleH);
this.currentScaleW = _scaleW;
this.currentScaleH = _scaleH;
},
handleTranslate(scaleW = 1, scaleH = 1) {
const width = this.width * scaleW;
const height = this.height * scaleH;
const size = this.getWindowSize();
const left = round(size.width - width) / 2;
const top = round(size.height - height) / 2;
this.$el.style.paddingLeft = left / scaleW + 'px';
this.$el.style.paddingTop = top / scaleH + 'px';
// this.$el.parentElement.style.paddingTop = top + 'px';
// this.$el.parentNode.style.paddingTop = top + 'px';
},
/**
* @method getWindowSize
* @description 获取当前窗口大小
*/
getWindowSize() {
const clientRect = document.documentElement.getBoundingClientRect();
return {
width: clientRect.width,
height: clientRect.height,
}
},
getStyle(obj, property) {
return window.getComputedStyle ? window.getComputedStyle(obj, null)[property] : obj.currentStyle[property];
},
scale(scaleW = 1, scaleH = 1) {
this.$el.style.transform = `scale(${scaleW}, ${scaleH})`;
this.$emit('scale', min(scaleW, scaleH))
},
},
mounted() {
const $el = this.$el;
$el.style.width = this.width + 'px';
$el.style.height = this.height + 'px';
this.handleResize(); // 初始设置
}
}
</script>
<style scoped>
.layout {
transform-origin: 0 0;
}
.layout .vitural-view {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
z-index: -1;
}
</style>
驾驶舱适配
最新推荐文章于 2024-09-18 20:34:32 发布