驾驶舱适配

该代码段展示了一个Vue.js组件,用于实现基于窗口大小的动态缩放适配。它使用ResizeObserver监听尺寸变化,根据预设的缩放类型(宽度、高度、最小、最大、包含)调整内容的宽高比例,确保内容在容器内适配显示。组件还处理了平移以保持内容居中。
摘要由CSDN通过智能技术生成
<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>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值