前言

开发过大屏的铁汁们应该知道,前期最头疼的就是大屏适配,由于大屏项目需要在市面上不是很常见的显示器上进行展示,所以要根据不同的尺寸进行适配,今天我将为大家分享的我使用的大屏适配方案,话不多说,直接上效果图。

效果图

上面所展示的只是其中一种模式,其中一共有四种模式,分别为1-居中留白(按比例伸缩);、2-居中留白(若不超出屏则不拉伸);、3-窄边铺满(长边滚动)、4-铺满全屏。


准备工作

首先,我们需要把使用到的依赖进行安装:

npm i element-resize-detector

npm i animejs

npm i jquery

然后,在vuex中定义以下变量和方法:

 state: {
    mode: 1, //1-居中留白(按比例伸缩); 2-居中留白(若不超出屏则不拉伸); 3-窄边铺满(长边滚动); 4-铺满全屏
    exw: 40,
    left: 0,
    top: 0,
    orderWork: {},
    warn: {},
    fontSize: 30,
  },
mutations: {
    increment(state, fs) {
      state.fontSize = fs;
    },
    exMode(state, mode) {
      state.mode = mode;
    },
    addExW(state, exw) {
      state.exw = exw;
    },
    addLeft(state, left) {
      state.left = left;
    },
    addTop(state, top) {
      state.top = top;
    },
  },

最后,需要在main.js中定义我们需要用到的全局方法:

// 以下为vue3的写法
import ElementResizeDetectorMaker from "element-resize-detector";
import anime from "animejs";
import jquery from "jquery";

const app = createApp(App);

app.config.globalProperties.$erd = ElementResizeDetectorMaker();
app.config.globalProperties.$anime = anime;
app.config.globalProperties.$jquery = jquery;

app.use(store).use(router).use(ElementPlus).mount("#app");


// 以下为vue2的写法
import Vue from 'vue'
import ElementResizeDetectorMaker from "element-resize-detector";
import anime from "animejs";
import jquery from "jquery";

Vue.prototype.$erd = ElementResizeDetectorMaker();
Vue.prototype.$anime = anime;
Vue.prototype.$jquery = $jquery;

实现

在App.vue中书写以下代码:

<template>
  <div id="app" :style="{ padding: pad }" class="hidden">
    <div ref="appBox" class="app-box" :style="{ width: tw, height: th }">
      <router-view />
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      pad: "0",
      w: 4160,
      h: 1248,
      fs: 30, //基本字体大小
      tw: "100%",
      th: "100%",
      speed: 2,
      ani: null,
    };
  },
  created() {},
  computed: {
    mode() {
      return this.$store.state.mode;
    },
  },
  watch: {
    mode() {
      this.$jquery(this.$refs.appBox).css("transform", "none");
      this.calc();
    },
  },
  mounted() {
    this.calc();
    this.$nextTick(() => {
      document.addEventListener("keydown", (e) => this.turnMode(e), true);
      this.$erd.listenTo(document.querySelector("html"), () => {
        this.$jquery(this.$refs.appBox).css("transform", "none");
        this.calc();
      });

      this.$store.commit("addExW", this.$jquery(this.$refs.ex).outerWidth());
    });
  },
  methods: {
    calc: function () {
      let fs = this.fs;
      let html = document.querySelector("html");
      let sc = this.w / this.h;
      let ww = parseFloat(
        document.defaultView.getComputedStyle(html, null).width
      );
      let wh = parseFloat(
        document.defaultView.getComputedStyle(html, null).height
      );
      if (this.mode <= 2) {
        let isEnough = this.h <= wh && this.w <= ww && this.mode == 2;
        if (isEnough) {
          this.pad = wh / 2 - this.h / 2 + "px " + (ww / 2 - this.w / 2) + "px";
        } else {
          if (sc < ww / wh) {
            this.pad = "0 " + (ww / 2 - (wh * sc) / 2) + "px";
            fs = (wh * fs) / this.h;
          } else {
            this.pad = wh / 2 - ww / sc / 2 + "px 0";
            fs = (ww * fs) / this.w;
          }
        }
        this.tw = "100%";
        this.th = "100%";

        this.$store.commit(
          "addLeft",
          isEnough
            ? ww / 2 - this.w / 2
            : sc < ww / wh
            ? ww / 2 - (wh * sc) / 2
            : 0
        );
        this.$store.commit(
          "addTop",
          isEnough
            ? wh / 2 - this.h / 2
            : sc < ww / wh
            ? 0
            : wh / 2 - ww / sc / 2
        );
      } else if (this.mode == 3) {
        this.pad = "0";
        if (sc < ww / wh) {
          this.tw = ww + "px";
          this.th = ww / sc + "px";
          fs = (ww * fs) / this.w;
          this.$nextTick(() => {
            document.removeEventListener(
              "keydown",
              (e) => this.trans(e, 1),
              true
            );
            document.addEventListener("keydown", (e) => this.trans(e, 1), true);
            this.mouseWheel(
              this.$refs.appBox,
              () => this.trans({ keyCode: 38 }, 1, 240),
              () => this.trans({ keyCode: 40 }, 1, 240)
            );
          });
        } else {
          this.tw = wh * sc + "px";
          this.th = wh + "px";
          fs = (wh * fs) / this.h;
          this.$nextTick(() => {
            document.removeEventListener(
              "keydown",
              (e) => this.trans(e, 0),
              true
            );
            document.addEventListener("keydown", (e) => this.trans(e, 0), true);
            this.mouseWheel(
              this.$refs.appBox,
              () => this.trans({ keyCode: 37 }, 0, 240),
              () => this.trans({ keyCode: 39 }, 0, 240)
            );
          });
        }

        this.$store.commit("addLeft", 0);
        this.$store.commit("addTop", 0);
      } else if (this.mode == 4) {
        this.pad = "0";
        this.tw = "100%";
        this.th = "100%";
        fs = sc < ww / wh ? (wh * fs) / this.h : (ww * fs) / this.w;

        this.$store.commit("addLeft", 0);
        this.$store.commit("addTop", 0);
      }
      html.style["font-size"] = parseInt(fs) + "px";
      this.$store.commit("increment", fs);
    },
    trans: function (e, s, st) {
      let ts = s
        ? this.$jquery(this.$refs.appBox).outerHeight()
        : this.$jquery(this.$refs.appBox).outerWidth();
      let ws = s
        ? this.$jquery(this.$refs.appBox).parent().outerHeight()
        : this.$jquery(this.$refs.appBox).parent().outerWidth();
      let event = e || window.event;
      let code = event.keyCode || event.which;
      let of = parseFloat(
        this.$jquery(this.$refs.appBox).css("transform")
          ? this.$jquery(this.$refs.appBox).css("transform").split(",")[
              s ? 5 : 4
            ] || 0
          : 0
      );
      let step = st || 120;
      if (code == (s ? 38 : 37) && of < 0) {
        let m = of + step > 0 ? 0 : of + step;
        this.run(this.$refs.appBox, s, m - of);
      } else if (code == (s ? 40 : 39) && ts + of - ws > 0) {
        let m = ts + (of - step) - ws > 0 ? of - step : ws - ts;
        this.run(this.$refs.appBox, s, m - of);
      }
      return false;
    },
    run: function (el, s, dis) {
      this.$anime.remove(el);
      this.ani = null;
      let obj = {
        targets: el,
        duration: parseInt(Math.abs(dis) / this.speed),
        easing: "linear",
      };
      if (s) {
        obj.translateY = "+=" + dis;
      } else {
        obj.translateX = "+=" + dis;
      }
      this.ani = this.$anime(obj);
    },
    mouseWheel: function (ele, fn1, fn2) {
      function wheelDelta(ev) {
        // 使火狐浏览器 和标准浏览器的 滚轮数值返回一致
        return ev.wheelDelta ? ev.wheelDelta : ev.detail * -40;
      }
      function clack(ev) {
        if (wheelDelta(ev) < 0) {
          fn2.call(ele);
        } else {
          fn1.call(ele);
        }
      }
      if (navigator.userAgent.match(/Firefox/gi)) {
        ele.addEventListener("DOMMouseScroll", function (ev) {
          // 火狐浏览器
          ev = ev || window.event;
          ev.preventDefault();
          clack(ev);
        });
      } else {
        //其他浏览器 chrome ie
        if (ele.addEventListener) {
          ele.addEventListener(
            "mousewheel",
            function (ev) {
              ev = ev || window.event;
              ev.returnValue ? (ev.returnValue = false) : ev.preventDefault();
              clack(ev);
            },
            { passive: false }
          );
        } else {
          ele.attachEvent("onmousewheel", function (ev) {
            ev = ev || window.event;
            if (ev.returnValue) {
              ev.returnValue = false;
            }
            clack(ev);
          });
        }
      }
    },
    turnMode: function (e) {
      let event = e || window.event;
      let code = event.keyCode || event.which;

      let obj = {
        49: 1,
        50: 3,
      };
      let mode = obj[code] || this.mode;
      this.$store.commit("exMode", mode);
    },
    exBtn: function () {
      let mode = this.mode == 1 ? 3 : 1;
      this.$store.commit("exMode", mode);
    },
  },
};
</script>
<style scoped>
.app-box {
  box-sizing: border-box;
  overflow: hidden;
  background-size: 100% 100%;
  user-select: none;
  background-color: darkorange;
}
</style>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #fff;
  background-color: #fff;

  width: 100vw;
  height: 100vh;
  box-sizing: border-box;
  font-size: 1rem;
}
</style>

GitHub 加速计划 / vu / vue
82
16
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:4 个月前 )
9e887079 [skip ci] 2 个月前
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 6 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐