当前位置: 首页 > news >正文

好用的可视化大屏适配方案

1、scale方案

在这里插入图片描述
优点:使用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%;}
}

如果你不想分别写html,js和css,那么你也可以使用v-scale-screen插件来帮你完成
使用插件参考:https://juejin.cn/post/7075253747567296548

2、使用dataV库,推荐使用

vue2版本:http://datav.jiaminghi.com/
vue3版本:https://datav-vue3.netlify.app/

<dv-full-screen-container>content
</dv-full-screen-container>

优点:方便,没有留白,铺满可视区

3、手写dataV的container容器

嫌麻还是用dataV吧
文件结构
在这里插入图片描述
index.vue

<template><div id="imooc-screen-container" :ref="ref"><template v-if="ready"><slot></slot></template></div>
</template><script>import autoResize from './autoResize.js'export default {name: 'DvFullScreenContainer',mixins: [autoResize],props: {options: {type: Object}},data() {return {ref: 'full-screen-container',allWidth: 0,allHeight: 0,scale: 0,datavRoot: '',ready: false}},methods: {afterAutoResizeMixinInit() {this.initConfig()this.setAppScale()this.ready = true},initConfig() {this.allWidth = this.width || this.originalWidththis.allHeight = this.height || this.originalHeightif (this.width && this.height) {this.dom.style.width = `${this.width}px`this.dom.style.height = `${this.height}px`} else {this.dom.style.width = `${this.originalWidth}px`this.dom.style.height = `${this.originalHeight}px`}},setAppScale() {const currentWidth = document.body.clientWidthconst currentHeight = document.body.clientHeightthis.dom.style.transform = `scale(${currentWidth / this.allWidth}, ${currentHeight / this.allHeight})`},onResize() {this.setAppScale()}}}
</script><style lang="less">#imooc-screen-container {position: fixed;top: 0;left: 0;overflow: hidden;transform-origin: left top;z-index: 999;}
</style>

autoResize.js

import { debounce, observerDomResize } from './util'export default {data () {return {dom: '',width: 0,height: 0,originalWidth: 0,originalHeight: 0,debounceInitWHFun: '',domObserver: ''}},methods: {async autoResizeMixinInit () {await this.initWH(false)this.getDebounceInitWHFun()this.bindDomResizeCallback()if (typeof this.afterAutoResizeMixinInit === 'function') this.afterAutoResizeMixinInit()},initWH (resize = true) {const { $nextTick, $refs, ref, onResize } = thisreturn new Promise(resolve => {$nextTick(e => {const dom = this.dom = $refs[ref]if (this.options) {const { width, height } = this.optionsif (width && height) {this.width = widththis.height = height}} else {this.width = dom.clientWidththis.height = dom.clientHeight}if (!this.originalWidth || !this.originalHeight) {const { width, height } = screenthis.originalWidth = widththis.originalHeight = height}if (typeof onResize === 'function' && resize) onResize()resolve()})})},getDebounceInitWHFun () {this.debounceInitWHFun = debounce(100, this.initWH)},bindDomResizeCallback () {this.domObserver = observerDomResize(this.dom, this.debounceInitWHFun)window.addEventListener('resize', this.debounceInitWHFun)},unbindDomResizeCallback () {this.domObserver.disconnect()this.domObserver.takeRecords()this.domObserver = nullwindow.removeEventListener('resize', this.debounceInitWHFun)}},mounted () {this.autoResizeMixinInit()},beforeDestroy () {const { unbindDomResizeCallback } = thisunbindDomResizeCallback()}
}

util/index.js

export function randomExtend (minNum, maxNum) {if (arguments.length === 1) {return parseInt(Math.random() * minNum + 1, 10)} else {return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10)}
}export function debounce (delay, callback) {let lastTimereturn function () {clearTimeout(lastTime)const [that, args] = [this, arguments]lastTime = setTimeout(() => {callback.apply(that, args)}, delay)}
}export function observerDomResize (dom, callback) {const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserverconst observer = new MutationObserver(callback)observer.observe(dom, { attributes: true, attributeFilter: ['style'], attributeOldValue: true })return observer
}export function getPointDistance (pointOne, pointTwo) {const minusX = Math.abs(pointOne[0] - pointTwo[0])const minusY = Math.abs(pointOne[1] - pointTwo[1])return Math.sqrt(minusX * minusX + minusY * minusY)
}

// 看下面这个没有封装完善的
核心原理: 固定宽高比,采用缩放,一屏展示出所有的信息
在这里插入图片描述

在这里插入图片描述

<template><div class="datav_container" id="datav_container" :ref="refName"><template v-if="ready"><slot></slot></template></div>
</template><script>
import { ref, getCurrentInstance, onMounted, onUnmounted, nextTick } from 'vue'
import { debounce } from '../../utils/index.js'
export default {// eslint-disable-next-line vue/multi-word-component-namesname: 'Container',props: {options: {type: Object,default: () => {}}},setup(ctx) {const refName = 'container'const width = ref(0)const height = ref(0)const origialWidth = ref(0) // 视口区域const origialHeight = ref(0)const ready = ref(false)let context, dom, observerconst init = () => {return new Promise((resolve) => {nextTick(() => {// 获取domdom = context.$refs[refName]console.log(dom)console.log('dom', dom.clientWidth, dom.clientHeight)// 获取大屏真实尺寸if (ctx.options && ctx.options.width && ctx.options.height) {width.value = ctx.options.widthheight.value = ctx.options.height} else {width.value = dom.clientWidthheight.value = dom.clientHeight}// 获取画布尺寸if (!origialWidth.value || !origialHeight.value) {origialWidth.value = window.screen.widthorigialHeight.value = window.screen.height}console.log(width.value, height.value, window.screen, origialWidth.value, origialHeight.value)resolve()})})}const updateSize = () => {if (width.value && height.value) {dom.style.width = `${width.value}px`dom.style.height = `${height.value}px`} else {dom.style.width = `${origialWidth.value}px`dom.style.height = `${origialHeight.value}px`}}const updateScale = () => {// 计算压缩比// 获取真实视口尺寸const currentWidth = document.body.clientWidth // 视口实际显示区(浏览器页面实际显示的)const currentHeight = document.body.clientHeightconsole.log('浏览器页面实际显示', currentWidth, currentHeight)// 获取大屏最终宽高const realWidth = width.value || origialWidth.valueconst realHeight = height.value || origialHeight.valueconst widthScale = currentWidth / realWidthconst heightScale = currentHeight / realHeightdom.style.transform = `scale(${widthScale}, ${heightScale})`}const onResize = async (e) => {// console.log('resize', e)await init()await updateScale()}const initMutationObserver = () => {const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserverobserver = new MutationObserver(onResize)observer.observe(dom, {attributes: true,attributeFilter: ['style'],attributeOldValue: true})}const removeMutationObserver = () => {if (observer) {observer.disconnect()observer.takeRecords()observer = null}}onMounted(async () => {ready.value = falsecontext = getCurrentInstance().ctxawait init()updateSize()updateScale()window.addEventListener('resize', debounce(onResize, 100))initMutationObserver()ready.value = true})onUnmounted(() => {window.removeEventListener('resize', debounce(onResize, 100))removeMutationObserver()})return {refName,ready}}
}
</script><style lang="scss" scoped>
.datav_container {position: fixed;top: 0;left: 0;transform-origin: left top;overflow: hidden;z-index: 999;
}
</style>

在使用Container组件的时候,这样用

<Container :options="{ width: 3840, height: 2160 }"><div class="test">111</div>
</Container> 

传入你的大屏的分辨率options

// 获取大屏真实尺寸

// 获取dom
dom = context.$refs[refName]
// 获取大屏真实尺寸
if (ctx.options && ctx.options.width && ctx.options.height) {width.value = ctx.options.widthheight.value = ctx.options.height
} else {width.value = dom.clientWidthheight.value = dom.clientHeight
}

// 获取画布尺寸

if (!origialWidth.value || !origialHeight.value) {origialWidth.value = window.screen.widthorigialHeight.value = window.screen.height
}

// 定义更新size方法

 const updateSize = () => {if (width.value && height.value) {dom.style.width = `${width.value}px`dom.style.height = `${height.value}px`} else {dom.style.width = `${origialWidth.value}px`dom.style.height = `${origialHeight.value}px`}
}

// 设置压缩比

 const updateScale = () => {// 计算压缩比// 获取真实视口尺寸const currentWidth = document.body.clientWidth // 视口实际显示区(浏览器页面实际显示的)const currentHeight = document.body.clientHeightconsole.log('浏览器页面实际显示', currentWidth, currentHeight)// 获取大屏最终宽高const realWidth = width.value || origialWidth.valueconst realHeight = height.value || origialHeight.valueconst widthScale = currentWidth / realWidthconst heightScale = currentHeight / realHeightdom.style.transform = `scale(${widthScale}, ${heightScale})`
}

相关文章:

好用的可视化大屏适配方案

1、scale方案 优点&#xff1a;使用scale适配是最快且有效的&#xff08;等比缩放&#xff09; 缺点&#xff1a; 等比缩放时&#xff0c;项目的上下或者左右是肯定会有留白的 实现步骤 <div className"screen-wrapper"><div className"screen"…...

言有三新书出版,《深度学习之图像识别(全彩版)》上市发行,配套超详细的原理讲解与丰富的实战案例!...

各位同学&#xff0c;今天有三来发布新书了&#xff0c;名为《深度学习之图像识别&#xff1a;核心算法与实战案例&#xff08;全彩版&#xff09;》&#xff0c;本次书籍为我写作并出版的第6本书籍。 前言 2019年5月份我写作了《深度学习之图像识别&#xff1a;核心技术与案例…...

英特尔开始加码封装领域 | 百能云芯

在积极推进先进制程研发的同时&#xff0c;英特尔正在加大先进封装领域的投入。在这个背景下&#xff0c;该公司正在马来西亚槟城兴建一座全新的封装厂&#xff0c;以加强其在2.5D/3D封装布局领域的实力。据了解&#xff0c;英特尔计划到2025年前&#xff0c;将其最先进的3D Fo…...

基于大数据+django+mysql的学习资源推送系统的设计与实现(含报告+源码+指导)

本系统为了数据库结构的灵活性所以打算采用MySQL来设计数据库&#xff0c;而Python技术&#xff0c; B/S架构则保证了较高的平台适应性。文中主要是讲解了该系统的开发环境、要实现的基本功能和开发步骤&#xff0c;并主要讲述了系统设计方案的关键点、设计思想。 由于篇幅限制…...

CCF HPC China2023 | 盛大开幕,邀您关注澎峰科技

2023年8月24日&#xff0c;以“算力互联智领未来”为主题的第十九届全国高性能计算学术年会&#xff08;CCF HPC China 2023&#xff09;在青岛红岛国际会议展览中心拉开帷幕。特邀嘉宾涵盖行业大咖&#xff0c;主持阵容同样是“重量级”——来自国家并行计算机工程技术研究中心…...

【git进阶使用】 告别只会git clone 学会版本控制 ignore筛选 merge冲突等进阶操作

git使用大全 基本介绍git 快速上手一 环境安装&#xff08;默认已安装&#xff09;二 远程仓库克隆到本地1 进入rep文件夹目录2 复制远程仓库地址3 git clone克隆仓库内容到本地4 修改后版本控制4.1 修改文件4.2 git status查看版本库文件状态4.3 git add将文件加入版本库暂存区…...

【【萌新的STM32学习-16中断的基本介绍1】】

萌新的STM32学习-16中断的基本介绍1 中断 什么是中断 中断是打断CPU执行正常的程序&#xff0c;转而处理紧急程序&#xff0c;然后返回原暂停的程序继续执行&#xff0c;就叫中断 中断的作用 实时控制 &#xff1a; 就像对温度进行控制 故障控制 &#xff1a; 第一时间对突发情…...

ctfshow-红包题第二弹

0x00 前言 CTF 加解密合集CTF Web合集 0x01 题目 0x02 Write Up 同样&#xff0c;先看一下有没有注释的内容&#xff0c;可以看到有一个cmd的入参 执行之后可以看到文件代码&#xff0c;可以看到也是eval&#xff0c;但是中间对大部分的字符串都进行了过滤&#xff0c;留下了…...

C# winform中无标题栏窗口如何实现鼠标拖动?

文章目录 在C#中,可以通过重写窗体的鼠标事件来实现无标题栏窗体的拖动。 具体步骤如下: 禁用窗体的默认标题栏:在窗体属性中设置FormBorderStyle为None。 重写鼠标事件:在窗体类中重写MouseDown、MouseMove和MouseUp事件。 定义变量存储鼠标点击时的坐标。 在MouseDown事…...

【操作系统】各平台定时器粒度

文章目录 WindowsLinux Windows 在 Windows 操作系统中&#xff0c;定时器的精度取决于系统时钟的精度。通常情况下&#xff0c;Windows 系统时钟的精度为 15.6 毫秒&#xff08;即每秒钟约 64 次时钟中断&#xff09;&#xff0c;因此定时器的最小精度也是 15.6 毫秒。但是&a…...

抽象又有点垃圾的JavaScript

常数的排序 let x 10;let y 20;let z;if (x < y) {z x;x y;y z;}console.log(x, y);//x 20 ,y 10 通过一个媒介来继承x的初始值&#xff0c;然后将y的值赋值给x&#xff0c;再把媒介z的值赋值给y&#xff0c;达到排序 一个可重复使用的排序程序 第一种 function s…...

【Spring Boot】使用Spring Boot进行transformer的部署与开发

Transformer是一个用于数据转换和处理的平台&#xff0c;使用Spring Boot可以方便地进行Transformer的部署与开发。 以下是使用Spring Boot进行Transformer部署与开发的步骤&#xff1a; 创建Spring Boot项目 可以使用Spring Initializr创建一个简单的Spring Boot项目。在创…...

Qt应用开发(基础篇)——富文本浏览器 QTextBrowser

一、前言 QTextBrowser类继承于QTextEdit&#xff0c;是一个具有超文本导航的富文本浏览器。 框架类 QFramehttps://blog.csdn.net/u014491932/article/details/132188655 滚屏区域基类 QAbstractScrollAreahttps://blog.csdn.net/u014491932/article/details/132245486 文…...

JDBC:更新数据库

JDBC&#xff1a;更新数据库 更新记录删除记录 为了更新数据库&#xff0c;您需要使用语句。但是&#xff0c;您不是调用executeQuery()方法&#xff0c;而是调用executeUpdate()方法。 可以对数据库执行两种类型的更新&#xff1a; 更新记录值删除记录 executeUpdate()方…...

如何自定义iview树形下拉内的内容

1.使用render函数给第一层父级定义 2. 使用树形结构中的render函数来定义子组件 renderContent(h, {root, node, data}) {return data.children.length0? h(span, {style: {display: inline-block,width: 400px,lineHeight: 32px}}, [h(span, [h(Icon, {type: ios-paper-outli…...

技术的巅峰演进:深入解析算力网络的多层次技术设计

在数字化时代的浪潮中&#xff0c;网络技术正以前所未有的速度演进&#xff0c;而算力网络作为其中的一颗明星&#xff0c;以其多层次的技术设计引领着未来的网络构架。本文将带您深入探索算力网络独特的技术之旅&#xff0c;从底层协议到分布式控制&#xff0c;为您呈现这一创…...

图像特征描述和人脸识别

CV_tutorial2 特征检测使用HOG实现行人检测Harris角点检测关键特征检测SIFT纹理特征 LBP算法 模板匹配人脸识别 特征检测 使用HOG实现行人检测 HOG方向梯度直方图 实现过程&#xff1a; 灰度化&#xff08;为了去掉颜色、光照对形状的影响&#xff09;;采用Gamma校正法对输…...

浅谈Lua协程和函数的尾调用

前言 虽然不经常用到协程&#xff0c;但是也不能谈虎色变。同时&#xff0c;在有些场景&#xff0c;协程会起到一种不可比拟的作用。所以&#xff0c;了解它&#xff0c;对于一些功能&#xff0c;也会有独特的思路和想法。 协程 概念 关于进程和线程的概念就不多说。 那么…...

【VS Code插件开发】状态栏(五)

&#x1f431; 个人主页&#xff1a;不叫猫先生&#xff0c;公众号&#xff1a;前端舵手 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域优质作者、阿里云专家博主&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4e2; 资料领取&#xff1a;前端…...

睿趣科技:抖音开网店要怎么找货源

在当今数字化的时代&#xff0c;电商平台的兴起为越来越多的人提供了开设网店的机会&#xff0c;而抖音作为一个充满活力的短视频平台&#xff0c;也为创业者提供了广阔的发展空间。然而&#xff0c;对于许多初次涉足电商领域的人来说&#xff0c;找到合适的货源却是一个重要的…...

表和Json的相互操作

目录 一、表转Json 1.使用 for json path 2.如何返回单个Json 3.如何给返回的Json增加一个根节点呢 4.如何给返回的Json增加上一个节点 二、对Json基本操作 1.判断给的字符串是否是Json格式 2.从 JSON 字符串中提取标量值 3. 从 JSON 字符串中提取对象或数组 4. 更…...

每日后端面试5题 第八天

1.UDP和TCP协议的区别 1.UDP无连接&#xff0c;速度快&#xff0c;安全性低&#xff0c;适合高速传输、实时广播通信等。 2.TCP面向连接&#xff0c;速度慢&#xff0c;安全性高&#xff0c;适合传输质量要求高、大文件等的传输&#xff0c;比如邮件发送等。 &#xff08;还…...

mysql数据库和数据表

常用的数据类型: int &#xff1a; 整型 用于定义整数类型的数据float &#xff1a; 单精度浮点4字节32位 准确表示到小数点后六位.double &#xff1a;双精度浮点8字节64位char &#xff1a;固定长度的字符类型 用于定义字符类型数据varchar &#xff1a;可变长度的字符类…...

MySQL执行更新的流程

一、加载缓存数据 引擎要执行更新语句的时候 &#xff0c;比如对“id10”这一行数据&#xff0c;他其实会先将“id10”这一行数据看看是否在缓冲池里&#xff0c;如果不在的话&#xff0c;那么会直接从磁盘里加载到缓冲池里来&#xff0c;而且接着还会对这行记录加独占锁。 二…...

要获取 PHP 中当前时间的前一天、本周、本月、本季度和本年,可以使用 PHP 的内置日期和时间函数。

要获取 PHP 中当前时间的前一天、本周、本月、本季度和本年&#xff0c;可以使用 PHP 的内置日期和时间函数。下面是一些示例代码来帮助你实现这些功能&#xff1a; php // 获取当前时间的前一天 $yesterday date(Y-m-d, strtotime(-1 day));// 获取本周的开始日期和结束日期…...

java八股文面试[java基础]——如何实现不可变的类

知识来源&#xff1a; 【23版面试突击】如何实现不可变的类&#xff1f;_哔哩哔哩_bilibili 【2023年面试】怎样声明一个类不会被继承&#xff0c;什么场景下会用_哔哩哔哩_bilibili...

juc基础(四)

目录 一、ThreadPool 线程池 1、参数说明 2、拒绝策略 3、线程池种类 &#xff08;1&#xff09;newCachedThreadPool(常用) &#xff08;2&#xff09;newFixedThreadPool(常用) &#xff08;3&#xff09;newSingleThreadExecutor(常用) &#xff08;4&#xff09;ne…...

C++智能指针weak_ptr的作用

当使用std::shared_ptr时&#xff0c;循环引用可能会导致资源泄漏的问题。下面是一个简单的示例&#xff0c;展示了循环引用导致资源泄漏的情况&#xff1a; #include <iostream> #include <memory>class A; class B;class A { public:std::shared_ptr<B> b…...

lintcode 344 · 歌曲时间【背包问题,动态规划】

题目链接&#xff0c;描述 https://www.lintcode.com/problem/344/ 给定长度为N的正整数数组song代表N首歌的时间 请你任选其中若干首播放&#xff0c;在满足开始播放最后一首歌的时间小于M的情况下求播放歌曲的最长时间 每首歌只能被播放一次 你可以任意指定播放顺序1 \leq …...

Qt应用开发(基础篇)——对话框窗口 QDialog

一、前言 QDialog类继承于QWidget&#xff0c;是Qt基于对话框窗口(消息窗口QMessageBox、颜色选择窗口QColorDialog、文件选择窗口QFileDialog等)的基类。 QDialog窗口是顶级的窗口&#xff0c;一般情况下&#xff0c;用来当做用户短期任务(确认、输入、选择)或者和用户交流(提…...

如何做企业网站内链/上海百度公司总部

在 Java 的线程安全是老生常谈的问题。经常是各种写法说法一大堆&#xff0c;感觉很多的来源都是在面试的时候&#xff0c;很多考官都喜欢问线程安全的问题。 起源 这个问题的起源就是 Java 是支持多线程的。如果对进程和线程是什么不太清楚的话&#xff0c;可以恶补下大学课…...

百度联盟/网站优化排名首页

MySQL中的索引探究 - 08/05本次分享讲述MySQL的索引原理&#xff0c;不同存储引擎对索引的支持情况。同时探究大家普遍关心的问题&#xff1a;MySQL在哪些操作中会用到索引&#xff1f;InnoDB引擎对索引做了哪些扩展&#xff1f;基于Generated Column的索引有什么用&#xff1f…...

政府网站建设存在问题/教育培训机构排名前十

需求背景&#xff1a; 从规范商家行为和让商家感觉到平台和他们互动出发点。 流程图&消息来源 消息来源&#xff1a;运营活动&#xff0c;违规通知&#xff0c;充值通知等 产品维度消息中心设计&#xff1a; 技术设计&#xff1a; crm新建任务流程图 服务调用&#xff1…...

江苏网站建设机构/搜索引擎优化的意思

这篇文章基于上一篇文章的例子 完整代码在这 Mybatis 多种条件查询和简单查询差别不是很大&#xff0c;更改xml映射文件就可以了。 一、模糊查询 模糊查询使用like&#xff0c;在配置文件中新建一个select标签&#xff0c;根据Sql语法规则构建好查询语句。 <select id"…...

wordpress 自定义函数/制作一个网站的全过程

cp -r /wenjian1/ /wenjian2/...

wordpress git升级/网站推广的途径和方法

如果您只想使用CSS3&#xff0c;甚至不需要使用任何jQuery / Javascript。只需在您的CSS中执行此操作&#xff1a;.confirm_selection {-webkit-transition: text-shadow 0.2s linear;-moz-transition: text-shadow 0.2s linear;-ms-transition: text-shadow 0.2s linear;-o-tr…...