vue大屏适配方案

news2024/10/10 12:17:37

前言

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

效果图

上面所展示的只是其中一种模式,其中一共有四种模式,分别为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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1862921.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity 弧形图片位置和背景裁剪

目录 关键说明 Unity 设置如下 代码如下 生成和部分数值生成 角度转向量 计算背景范围 关键说明 效果图如下 来自红警ol游戏内的截图 思路&#xff1a;确定中心点为圆的中心点 然后 计算每个的弧度和距离 Unity 设置如下 没什么可以说的主要是背景图设置 代码如下 …

天才程序员周弈帆 | Stable Diffusion 解读(四):Diffusers实现源码解读

本文来源公众号“天才程序员周弈帆”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;Stable Diffusion 解读&#xff08;四&#xff09;&#xff1a;Diffusers实现源码解读 接上一篇文章[天才程序员周弈帆 | Stable Diffusion 解读…

关于哈希表的一点理论基础

1.哈希表 数组就是哈希表&#xff0c;关键元素就是数组的下标。主要用于判断一个元素是否在集合中出现。 2.哈希函数 3.哈希碰撞 即有两个元素的下标相同 3.哈希碰撞的解决办法 &#xff08;1&#xff09;拉链法&#xff1a; 放到链表中&#xff0c;但要注意控制哈希表的大…

【SpringSecurity】认证与鉴权框架SpringSecurity——授权

目录 权限系统的必要性常见的权限管理框架SpringSecurity授权基本流程准备脚本限制访问资源所需权限菜单实体类和Mapper封装权限信息封装认证/鉴权失败处理认证失败封装鉴权失败封装配置SpringSecurity 过滤器跨域处理接口添加鉴权hasAuthority/hasAnyAuthorityhasRole/​ hasA…

L58---100.路径总和(广搜)---Java版

1.题目描述 2.思路 (1)首先检查p,q节点是不是为空&#xff1b;如果同时为空&#xff0c;则他们是相同的树 (2)p&#xff0c;q节点如果一个为空&#xff0c;一个不为空&#xff0c;则他们不是相同的树 (3)p,q的值不一样&#xff0c;则他们不是相同的树 (4)递归遍历左子树和右子…

用英文介绍纽约:NEW YORK, USA‘s MEGACITY

NEW YORK, USA’s MEGACITY | America’s Largest City Link: https://www.youtube.com/watch?vdzjQ-akB3BI&listPLmSQiOQJmbZ7TU39cyx7gizM9i8nOuZXy&index24 The story of New York City, America’s megalopolis. Summary Paragraph 1: The Historical Developm…

路由表操作

路由表&#xff08;Routing Table&#xff09;是网络设备&#xff08;如计算机、路由器、交换机等&#xff09;用来确定数据包传输路径的数据库。每当网络设备收到一个数据包时&#xff0c;它会查找路由表&#xff0c;决定将数据包转发到哪个网络接口或网关。下面介绍路由表的基…

vue3 antv/g6 动态设置mode,让节点不可以拖动

1、查看一下官网的设置说明 G6 设置mode 默认模式&#xff1a; const graph new G6.Graph({container: div,width: 500,height: 500,modes: {default: [drag-node,drag-canvas],custom: [drag-canvas]} })默认情况下&#xff0c;我们定义的是default&#xff0c;然后创建节…

Emacs之显示blame插件:blamer、git-messenger(一百四十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

【C++STL】Vector扩容机制

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

AI文档助手:提升文档处理效率

随着人工智能技术的飞速发展&#xff0c;AI文档助手已经成为我们提升工作效率的重要工具。小编就来和大家分享几款AI文档助手&#xff0c;它们能够通过智能化的功能帮助我们快速、准确地完成各种文档任务。 1.百度文库AI助手 百度文库AI助手是百度基于文心一言重构的一站式智能…

【jupyter notebook】解决打不开以及安装扩展插件的问题

文章目录 问题描述问题 1解决问题 2解决 问题描述 问题 1 在自定义的虚拟环境下&#xff0c;安装 jupyter notebook 6.4.12 版本时&#xff0c;报以下错误&#xff1a; 解决 查了一些 解决方法&#xff0c;执行以下命令即可解决&#xff1a; conda install traitlets5.9.0 …

WAV怎么转mp3?将wav转成MP3的几种方法介绍

WAV怎么转mp3&#xff1f;很多情况下&#xff0c;我们可能需要将高质量的 WAV 文件转换为更小、更兼容的 MP3 文件。例如&#xff0c;你可能想要为你的音乐收藏腾出更多存储空间&#xff0c;或者需要将音频文件上传到联网平台&#xff0c;而这些平台通常对文件大小有严格限制。…

React@16.x(40)路由v5.x(5)常见应用场景(2)- 实现类似 vue 的路由模式

目录 1&#xff0c;vue-router2&#xff0c;React 模拟实现 1&#xff0c;vue-router vue 的路由配置文件&#xff0c; // src/router/index.ts const routes [{path: "/news",children: [{ path: "", component: NewsView },{ path: "detail"…

【UE5.3】笔记1

内容浏览器&#xff1a;存放项目中所有的资源&#xff1a;关卡、蓝图类...... 关卡--Map 至少有一个关卡&#xff0c;可以有多个关卡 -漫游 视野漫游&#xff1a;鼠标右键WASD QE 鼠标滑轮控制摄像机速度 运行&#xff0c;ESC退出运行,快捷键F8不停止运行单独弹出功能 -创…

Android 11 ,默认授予预置应用/APK 需要的权限,解决permission denied for window type 2003 问题。

写这篇文章的原因是解决了一个APP闪退的问题&#xff0c;闪退的原因是插拔U盘时&#xff0c;注册的广播接收者接收到广播需要弹出一个Dialog询问是否需要打开U盘&#xff0c;这个Dialog设置的是系统级别悬浮窗&#xff0c;没有这个权限&#xff0c;报错导致闪退&#xff0c;下面…

【C语言】解决C语言报错:Dangling Pointer

文章目录 简介什么是Dangling PointerDangling Pointer的常见原因如何检测和调试Dangling Pointer解决Dangling Pointer的最佳实践详细实例解析示例1&#xff1a;释放内存后未将指针置为NULL示例2&#xff1a;返回指向局部变量的指针示例3&#xff1a;指针悬空后继续使用示例4&…

Python-PDF文件密码破解小工具

背景 经常从网络上下载的PDF笔记被加了密&#xff0c;在自己学习的过程中想要添加书签却因为没有密码无法添加&#xff0c;所以通过Python实现一个解密小工具&#xff0c;亲测大多数密码都可以破解。 代码 import os import tkinter as tk from tkinter import filedialog #…

三元前驱体废水回收镍钴工艺:环保与经济效益的双重胜利

在全球新能源产业迅猛发展的背景下&#xff0c;锂离子电池作为绿色能源的核心组件&#xff0c;其需求量激增&#xff0c;带动了上游材料市场&#xff0c;尤其是三元前驱体材料的蓬勃发展。然而&#xff0c;伴随着行业的快速扩张&#xff0c;三元前驱体生产过程中产生的含镍钴废…

Qt的学习之路

目录 一、信号槽机制 1.1 基本概念 1.2 特点 1.3 使用方法 1.4 信号槽连接类型 1.5 注意 二、元对象系统 2.1 基本概念 2.2 实现方式 2.3 主要特性 2.4 使用场景 三、国际化 3.1 标记可翻译的文本&#xff08;tr函数&#xff09; 3.2 生成翻译源文件&#xff08;…