Skip to content
☆´∀`☆
On this page

不明确最终像素比的情况下的自适应大屏解决方案

  • 我也不知道为什么会不明确.....随手一下,方便下次抄

  • 需求:大屏需铺满屏幕,不能出现滚动条,白边,布局错乱等问题。

  • 设计稿为 1920*1080

方案 1:利用 transform 的 scale 直接缩放。

整一个缩放组件

js
<template>
  <div class="screen-adapter" id="screenAdapter" :style="style">
    <slot />
  </div>
</template>

<script setup>
  import { onMounted, reactive } from "vue";
  // 入参为设计稿宽高
  const props = defineProps({
    width: {
      type: String,
      default: "1920",
    },
    height: {
      type: String,
      default: "1080",
    },
  });
  const style = reactive({
    width: props.width + "px",
    height: props.height + "px",
    transform: "scale(1) ",
  });
  const Debounce = (fn, t) => {
    const delay = t || 500;
    let timer;
    return function () {
      const args = arguments;
      if (timer) {
        clearTimeout(timer);
      }
      const context = this;
      timer = setTimeout(() => {
        timer = null;
        fn.apply(context, args);
      }, delay);
    };
  };

  // 获取放大缩小比例
  const getScale = () => {
    const w = window.innerWidth / props.width;
    const h = window.innerHeight / props.height;
    return [w, h];
  };
  // 设置比例
  const setScale = () => {
    style.transform = "scale(" + getScale()[0] + "," + getScale()[1] + ") ";
  };
  onMounted(() => {
    setScale();
    window.onresize = Debounce(setScale, 1000);
  });
</script>

<style lang="less" scoped>
  .screen-adapter {
    transform-origin: 0 0;
    transition: 0.3s;
  }
</style>

用于最外层做整体缩放。

  • 优点
    • 不影响性能
    • 开发方便,不用考虑 echarts 及其他插件的文字内容和定位适应,高宽都可直接按设计稿的尺寸套
  • 缺点
    • 会模糊会模糊会模糊会模糊会模糊,当其他组件使用了定位或 transform 的时候,内部文字可能会出现模糊(仿佛眼睛度数又上升了...
    • 不能适配像素特别高的屏。由于是按照 1920*1080 进行缩放的,所以在特高像素下就会 gg(可能会变成马赛克(dog。(但是也能解决,在知道像素后在用插件改代码...(但现在开发快完成了,最终显示器像素还是不明确...靠
    • 如果实际屏幕像素比和设计稿相差大的话,元素会被压缩,不太好看~比如圆形被压成椭圆

方案 2:rem

  • 考虑到应该不会存在窗口大小频繁切换的情况,就先忽略了 resize。(希望以后也别让我加这需求(但考虑到万一有这需求,从改动方便来说,先用了全局。
  • 懒得加文件了,先 config 扔一起(这种命名一般是常量...但是...这里就当全局了吧(反正就我一个开发:(
js
const API_BASE_URL = "";
const FILE_URL = "";

let WIN_SCALE = 1;

function SET_SCALE() {
  const scaleWidth = document.documentElement.clientWidth / 1920;
  const scaleHeight = document.documentElement.clientHeight / 1080;
  WIN_SCALE = Math.min(scaleWidth, scaleHeight);
}
SET_SCALE();
function SCALE_INT(val) {
  const res = parseInt(val * WIN_SCALE);
  return res == 0 ? 1 : parseInt(val * WIN_SCALE);
}
js
// 基准大小
const baseSize = 16;
// 设置 rem 函数
function setRem() {
  let fontSize = baseSize * WIN_SCALE > 12 ? baseSize * WIN_SCALE : 12;
  document.documentElement.style.fontSize = fontSize + "px";
}
//初始化
setRem();

// window.onresize = function () {
//   SET_SCALE();
//   setRem();
// };
  • 优点
    • 高清,比例正常
  • 缺点
    • 开发起来较为麻烦,一些块需要计算为百分比,以及需要考虑比例不同情况下哪些块固定尺寸,哪些块自由缩放。以及插件生成的元素需要计算大小
    • Rem 性能-1-1-1-1-1-1

其他配置

echarts 自定义主题

js
const labelFontSize = SCALE_INT(12);
const lineWidth = SCALE_INT(2);
const px5 = SCALE_INT(5),
  px8 = SCALE_INT(8);
export default {
  color: ["#fcce4a", "#9960f8", "#2cffb1", "#46c0ff", "#73c0de", "#3ba272", "#fc8452", "#9a60b4", "#ea7ccc"],
  backgroundColor: "rgba(0, 0, 0, 0)",
  textStyle: {},
  title: {
    textStyle: {
      color: "#464646",
    },
    subtextStyle: {
      color: "#6E7079",
    },
  },
  line: {
    itemStyle: {
      borderWidth: px5,
      shadowColor: "rgba(255,255,255 ,1)",
      shadowBlur: px5,
    },
    lineStyle: {
      width: lineWidth,
    },
    symbolSize: px8,
    symbol: "emptyCircle",
    smooth: true,
  },
   ......
};

总结

  • 在开发中,可以两种方案同时用~,根据最终确定的显示屏来决定采用哪种方案。
  • 可以将两种方案结合,自身元素用 rem,插件生成的用 transform 局部缩放