前言
通常设计稿页面要放到不同尺寸屏幕上展示,这时就需要屏幕自适应了
原理
使用css transform属性,
transform: scale(${scaleX}, ${scaleY})
页面根据屏幕尺寸进行一定比例的放大或者缩小。
React hooks版
useWindowScale文件
import { useEffect, useState } from 'react';
const useWindowScale = (
designWidth: number = 1920, // 设计稿尺寸
designHeight: number = 1080,
) => {
const [scaleX, setScaleX] = useState(1);
const [scaleY, setScaleY] = useState(1);
const handleResize = () => {
const _scaleX = window.innerWidth / designWidth;
const _scaleY = window.innerHeight / designHeight;
setScaleX(_scaleX);
setScaleY(_scaleY);
};
useEffect((): (() => void) | void => {
handleResize();
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return {
scaleX,
scaleY,
};
};
export default useWindowScale;
引用useWindowScale hooks封装 ScaleLayout React组件
大屏页面只需引用ScaleLayout组件,用ScaleLayout组件包裹根组件就行
import React from 'react';
import useWindowScale from "@app/hooks/useWindowScale";
export interface ScaleLayoutProps {
className?: any;
style?: React.CSSProperties;
children?: React.ReactNode;
}
const ScaleLayout = (props: ScaleLayoutProps) => {
const { children } = props;
const { scaleX, scaleY } = useWindowScale();
return (
<div
style={{
width: '1920px',
height: '1080px',
transformOrigin: 'left top',
transform: `scale(${scaleX}, ${scaleY})`,
transition: 'transform .3s ease-in-out',
}}
>
{children}
</div>
);
};
export default ScaleLayout;
react举例使用
vue3 hooks版
useWindowScale文件
import { onMounted, onUnmounted, reactive, toRefs } from 'vue';
import { DESIGN_WIDTH, DESIGN_HEIGHT } from '@/utils/constant';
const useWindowScale = (
designWidth: number = DESIGN_WIDTH, //设计稿尺寸
designHeight: number = DESIGN_HEIGHT,
) => {
const scale = reactive({
scaleX: 1,
scaleY: 1,
});
const handleResize = () => {
scale.scaleX = window.innerWidth / designWidth;
scale.scaleY = window.innerHeight / designHeight;
}
handleResize();
onMounted(() => {
window.addEventListener("resize", handleResize);
});
onUnmounted(() => {
window.removeEventListener("resize", handleResize);
});
return toRefs(scale);
};
export default useWindowScale;
DESIGN_WIDTH设计稿宽度1920与DESIGN_HEIGHT设计稿高度1080是常量
引用useWindowScale hooks封装 ScaleLayout vue组件
大屏页面只需引用ScaleLayout组件,用ScaleLayout组件包裹根组件就行 ScaleLayout文件
<script setup lang="ts">
import { computed } from 'vue';
//弹性 伸缩布局
import useWindowScale from "@/hooks/useWindowScale";
import { DESIGN_WIDTH, DESIGN_HEIGHT } from '@/utils/constant';
const { scaleX, scaleY } = useWindowScale();
const designWidth = computed(() => DESIGN_WIDTH + 'px');
const designHeight = computed(() => DESIGN_HEIGHT + 'px');
</script>
<template>
<div class="scale-wrapper">
<slot/>
</div>
</template>
<style lang="less" scoped>
.scale-wrapper {
width: v-bind(designWidth);
height: v-bind(designHeight);
transform-origin: left top;
transform: scale(v-bind(scaleX), v-bind(scaleY));
transition: transform .3s ease-in-out;
}
</style>
vue举例使用
结语
写react多年,代码思想多少都是互通的,欢迎评论区交流