«

记前端大屏适配方案

codeez 发布于 阅读:1242 笔记


整理一下以往做过的大屏项目是如何处理大屏适配的。

有些项目需要投放到一面墙的大屏幕上。

适配方案:scale

缺点:

如果ui稿和屏幕比例不同会出现留白;

缩放比例过大时,字体会有些许模糊,事件热区会偏移;

适配方案:vw+vh

按照设计稿的尺寸,将px按比例计算转为vw和vh

相较scale,当ui稿和屏幕比例不一致时不会留白。

缺点:每个图表都需要单独做字体、间距、位移的适配,比较麻烦

首先在布局时,应该采用模块化设计,每个模块相对独立,方便后续调整。

一、vw+vh

假设设计稿尺寸为1920*1080

那么一个200px宽高的div对应的vw、vh是:

vwDiv = 200px/1920px*100vw

vhDiv = 200px/1080px*100vh

css方案:

// 使用 scss 的 math 函数,https://sass-lang.com/documentation/breaking-changes/slash-div
// 新建util.scss
@use "sass:math";

// 默认设计稿的宽度
$designWidth: 1920;
// 默认设计稿的高度
$designHeight: 1080;

// px 转为 vw 的函数
@function vw($px) {
  @return math.div($px, $designWidth) * 100vw;
}

// px 转为 vh 的函数
@function vh($px) {
  @return math.div($px, $designHeight) * 100vh;
}

在vue.config.js里配置一下utils.scss的路径,就可以全局使用了

const path = require("path");

function resolve(dir) {
  return path.join(__dirname, dir);
}

module.exports = {
  publicPath: "",
  configureWebpack: {
    name: "app name",
    resolve: {
      alias: {
        "@": resolve("src"),
      },
    },
  },
  css: {
    // 全局配置 utils.scs,详细配置参考 vue-cli 官网
    loaderOptions: {
      sass: {
        prependData: `@import "@/styles/utils.scss";`,
      },
    },
  },
};

在组件中使用

<template>
    <div class="box">           
    </div>
</template>

<script>
export default{
    name: "Box",
}
</script>

<style lang="scss" scoped="scoped">
/* 
 直接使用 vw 和 vh 函数,将像素值传进去,得到的就是具体的 vw vh 单位       
 */
.box{
    width: vw(300);
    height: vh(100);
    font-size: vh(16);
    background-color: black;
    margin-left: vw(10);
    margin-top: vh(10);
    border: vh(2) solid red;
}
</style>

js方案

// 定义设计稿的宽高
const designWidth = 1920;
const designHeight = 1080;

// px转vw
export const px2vw = (_px) => {
  return (_px * 100.0) / designWidth + 'vw';
};

export const px2vh = (_px) => {
  return (_px * 100.0) / designHeight + 'vh';
};

export const px2font = (_px) => {
  return (_px * 100.0) / designWidth + 'vw';
};

处理echarts中字体大小:

echarts 的字体大小只支持具体数值(像素),不能用百分比或者 vw 等尺寸

其原理是计算出当前屏幕宽度和默认设计宽度的比值,将原始的尺寸乘以该值

另外,其它 echarts 的配置项,比如间距、定位、边距也可以用该函数

工具函数:

// Echarts图表字体、间距自适应
export const fitChartSize = (size,defalteWidth = 1920) => {
  let clientWidth = window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;
  if (!clientWidth) return size;
  let scale = (clientWidth / defalteWidth);
  return Number((size*scale).toFixed(3));
}
将方法挂在到原型

import {fitChartSize} from '@src/utils/dataUtil.js'
Vue.prototype.fitChartFont = fitChartSize;
// 在组件中使用
itemStyle: {
              normal: {
                borderWidth: 0,
                shadowBlur: this.fitChartSize(20),
                shadowOffsetX: 0,
                shadowOffsetY: this.fitChartSize(5),
                shadowColor: "rgba(0, 0, 0, 0.3)",
              },
            }

二、scale

当屏幕宽高比 < 设计稿宽高比,我们需要缩放的比例是屏幕宽度 / 设计稿宽度

当屏幕宽高比 > 设计稿宽高比,我们需要缩放的比例是屏幕高度 / 设计稿高度

<div className="screen-wrapper">
    <div className="screen" id="screen">

    </div>
 </div>
<script>
export default {
mounted() {
  // 初始化自适应  ----在刚显示的时候就开始适配一次
  handleScreenAuto();
  // 绑定自适应函数   ---防止浏览器栏变化后不再适配
  window.onresize = () => handleScreenAuto();
},
deleted() {
  window.onresize = null;
},
methods: {
  // 数据大屏自适应函数
  handleScreenAuto() {
    const designDraftWidth = 1920; //设计稿的宽度
    const designDraftHeight = 960; //设计稿的高度
    // 根据屏幕的变化适配的比例
    const scale =
      document.documentElement.clientWidth /
        document.documentElement.clientHeight <
      designDraftWidth / designDraftHeight
        ? document.documentElement.clientWidth / designDraftWidth
        : document.documentElement.clientHeight / designDraftHeight;
    // 缩放比例
    document.querySelector(
      '#screen',
    ).style.transform = `scale(${scale}) translate(-50%, -50%)`;
  },
},
};
</script>
/*
  除了设计稿的宽高是根据您自己的设计稿决定以外,其他复制粘贴就完事
*/  
.screen-root {
    height: 100%;
    width: 100%;
    .screen {
        display: inline-block;
        width: 1920px;  //设计稿的宽度
        height: 960px;  //设计稿的高度
        transform-origin: 0 0;
        position: absolute;
        left: 50%;
        top: 50%;
    }
}

...未完待续

前端

请先 登录 再评论