数据大屏适配方案 (scale)
目录
[TOC]
-
大屏之关键-前期的自适应适配 -
根据 ui 稿绘制图表,调细节
而解决了适配问题后,后面就只是一个慢工出细活,耗时间的事情了。
适配方案分析
看了网上的各种方案,目前大家采用的大概有 2 种👇
| 方案 | 实现方式 | 优点 | 缺点 |
|---|---|---|---|
| vm vh | 1.按照设计稿的尺寸,将 px 按比例计算转为 vw 和 vh | 1.可以动态计算图表的宽高,字体等,灵活性较高 2.当屏幕比例跟 ui 稿不一致时,不会出现两边留白情况 | 1.每个图表都需要单独做字体、间距、位移的适配,比较麻烦 |
| scale | 1.通过 scale 属性,根据屏幕大小,对图表进行整体的等比缩放 | 1.代码量少,适配简单 2.一次处理后不需要在各个图表中再去单独适配 | 1.因为是根据 ui 稿等比缩放,当大屏跟 ui 稿的比例不一样时,会出现周边留白情况 2.当缩放比例过大时候,字体会有一点点模糊,就一点点 3.当缩放比例过大时候,事件热区会偏移。 |
vw vh
什么是vw和vh
- vw和vh他们是一个相对单位(类似em和rem)
vw是:viewport width 视口宽度单位
vh是: viewport height 视口高度单位
- 相对视口的尺寸计算
1vw=1/100视口宽度
1vh=1/100视口高度
eg:当前屏幕视口是375像素,1vw就是3.75像素
vw和百分比的区别是什么?
百分比是相对父元素来说的
vw和vh是相对于当前视口来说的
vw怎么使用
如何还原设计稿?
前提:我们设计稿按照iphone678来设计,有个盒子是50*50像素的,如何使用vw呢?
分析:
②那么1vw是多少像素呢
375/100=3.75px
③我们的目标是做少像素?
50 50
④ 那么,50是多少个vw?
50/3.75=13.33vw
实现思路
按照设计稿的尺寸,将 px 按比例计算转为 vw 和 vh ,转换公式如下
假设设计稿尺寸为 1920*1080(做之前一定问清楚 ui 设计稿的尺寸)
即:
网页宽度=1920px
网页高度=1080px我们都知道
网页宽度=100vw
网页宽度=100vh所以,在 1920px*1080px 的屏幕分辨率下
1920px = 100vw
1080px = 100vh
这样一来,以一个宽 100px 和 100px 的 div 来说,其所占的宽高,以 vw 和 vh 为单位,计算方式如下:
vwDiv = 100 / (1920 / 100vw)
vhDiv = 100 / (1080 / 100vh)所以,就在 1920*1080 的屏幕分辨率下,计算出了单个 div 的宽高
当屏幕放大或者缩小时,div 还是以 vw 和 vh 作为宽高的,就会自动适应不同分辨率的屏幕
案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width:100vw;
height:100vh;
background: orange;
}
.top{
width: 5.2vw;
height: 9.26vh;
background: red;
margin-left: 2.6vw;
}
.bottom{
width: 5.2vw;
height: 9.26vh;
background: skyblue;
margin-left: 2.6vw;
margin-top:9.26vh;
}
</style>
</head>
<body>
<div class="box">
<div class="top">数据大屏幕</div>
<div class="bottom">hahaha </div>
</div>
</body>
</html>
<script>
//vw|vh:新增单位 ->IE8
</script>
scale方案
我们整个大屏的尺寸设置和设计图一样,只是通过css的scale放大缩小属性,来控制实际展示的大小。
通过监听浏览器窗口的大小,来改变scale的比例,从而实现数据大屏适配。(百度、网易等大数据适配的解决方案均是这个)
scale()方法
缩放,指的是“缩小”和“放大”。在CSS3中,我们可以使用scale()方法来将元素根据中心原点进行缩放。
跟translate()方法一样,缩放scale()方法也有3种情况:
(1)scaleX(x):元素仅水平方向缩放(X轴缩放);
(2)scaleY(y):元素仅垂直方向缩放(Y轴缩放);
(3)scale(x,y):元素水平方向和垂直方向同时缩放(X轴和Y轴同时缩放);
1、scaleX(x)
语法:transform:scaleX(x)
说明:x表示元素沿着水平方向(X轴)缩放的倍数,如果大于1就代表放大;如果小于1就代表缩小。 大家想想倍数是怎样一个概念就很好理解了。
2、scaleY(y)
语法: transform:scaleY(y)
说明: y表示元素沿着垂直方向(Y轴)缩放的倍数,如果大于1就代表放大;如果小于1就代表缩小。
3、scale(x,y)
语法:transform:scale(x,y)
说明:x表示元素沿着水平方向(X轴)缩放的倍数,y表示元素沿着垂直方向(Y轴)缩放的倍数。
注意,Y是一个可选参数,如果没有设置Y值,则表示X、Y两个方向的缩放倍数是一样的(同时放大相同倍数)。
css3 transform
当谈到网页设计和用户界面的时候,CSS3 Transform是一个非常强大且灵活的工具。它提供了一种改变元素在2D和3D空间中位置、旋转、缩放和倾斜的方式,为开发者创造出更为吸引人的用户体验。
1. 基本转换属性
1.1 位移(Translate)
通过 translate 属性,我们可以改变元素在水平和垂直方向上的位置。例如:
.element {
transform: translate(50px, 30px);
}
上述代码将元素向右移动50像素,向下移动30像素。
1.2 旋转(Rotate)
使用 rotate 属性可以实现元素的旋转效果。例如:
.element {
transform: rotate(45deg);
}
这将使元素顺时针旋转45度。
1.3 缩放(Scale)
通过 scale 属性,我们可以实现元素的缩放效果。例如:
.element {
transform: scale(1.5);
}
这会将元素放大1.5倍。
1.4 倾斜(Skew)
skew 属性用于倾斜元素。例如:
.element {
transform: skew(30deg, 20deg);
}
这将使元素在水平方向倾斜30度,在垂直方向倾斜20度。
2. 3D转换
CSS3 Transform还支持在三维空间中进行转换,通过使用 rotateX 、 rotateY 、 rotateZ 等属性,可以创建更为复杂的动画效果。
.element {
transform: rotateX(45deg) rotateY(45deg);
}
这将使元素绕X轴和Y轴同时旋转45度。
3. 过渡效果
结合CSS3 Transform和过渡效果,我们可以创建平滑的动画效果。通过 transition 属性,我们可以指定过渡的持续时间、延迟时间以及过渡效果的类型。
.element {
transition: transform 0.3s ease-in-out;
}
.element:hover {
transform: scale(1.2);
}
上述代码表示在0.3秒内以缓慢进出的方式将元素放大1.2倍,实现了在鼠标悬停时的过渡效果。
4. 实际应用
CSS3 Transform在实际应用中有着广泛的用途,比如创建响应式的用户界面、实现页面切换动画、以及设计独特的交互元素。通过巧妙地运用这些转换属性,开发者能够提升用户体验,使页面更为生动有趣。
案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.container {
width: 100vw;
height: 100vh;
background: url(./bg.png) no-repeat;
background-size: cover;
}
.box {
position: fixed;
width: 1920px;
height: 1080px;
background: red;
transform-origin: left top;
left: 50%;
top: 50%;
}
.top {
width: 100px;
height: 100px;
background: hotpink;
margin-left: 50px;
}
.bottom {
width: 100px;
height: 100px;
background: skyblue;
margin-left: 50px;
margin-top: 100px;
}
</style>
</head>
<body>
<div class="container">
<!-- 数据展示的区域 -->
<div class="box">
<div class="top">我是祖国的</div>
<div class="bottom">老花骨朵</div>
</div>
</div>
</body>
</html>
<script>
//控制数据大屏放大与缩小
let box = document.querySelector('.box');
box.style.transform = `scale(${getScale()}) translate(-50%,-50%)`
//计算缩放的比例啦
function getScale(w = 1920, h = 1080) {
const ww = window.innerWidth / w;
const wh = window.innerHeight / h;
return ww < wh ? ww : wh;
//ww<wh情况: 1920/1920(ww) 1080/1080(wh)
//ww>wh情况:1920/1920(ww) 1080/1080(wh)
}
window.onresize = () => {
box.style.transform = `scale(${getScale()}) translate(-50%,-50%)`
}
</script>
vue3中使用
<template>
<div class="comtainer">
<!-- 数据大屏内容区域 -->
<div class="screen" ref="screen">
<!-- 顶部 -->
<div class="top"></div>
<!-- 底部 -->
<div class="bottom">
<div class="left">左</div>
<div class="center">中</div>
<div class="right">右</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
// 获取数据大屏展示内容盒子的dom元素
let screen = ref();
onMounted(() => {
screen.value.style.transform = `scale(${getScale()}) translate(-50%,-50%)`;
});
// 定义大屏缩放比例
function getScale(w = 1920, h = 1080) {
// 例子 原型搞为1920(4) 屏幕2269 (8) 放大缩小的比例 宽度
const ww = window.innerWidth / w;
// 例子 原型搞为1080(3) 屏幕2160 (6) 放大缩小的比例 高度
const wh = window.innerHeight / h;
// 函数返回宽度缩放比例ww和高度缩放比例wh中较小的那个值,这是因为它希望保持宽高比例不变,
// 选择较小的比例来进行缩放,以确保整个内容可以在屏幕内完整显示。
return ww < wh ? ww : wh;
// ww宽度小于wh 高度:(视口宽度变小,视口高度变大)
}
// 监听窗口变化
window.onresize = () => {
// scale(${getScale()}):这部分代码设置了缩放变换。
// ${getScale()}是一个函数调用,它返回一个用于缩放的值。这个值将会替换${getScale()},从而生成类似scale(1.5)的字符串,其中1.5是实际的缩放比例。缩放可以让元素变大或变小。
//translate(-50%,-50%):这部分代码设置了平移变换。它将元素水平和垂直方向分别平移到其自身宽度和高度的50%处。这通常用于将元素在其容器中水平和垂直居中对齐。
// 先缩放完在把元素拽回去(因为scale缩放是以盒子中心点缩放的 css中改变了盒子位置及其中心点)
screen.value.style.transform = `scale(${getScale()}) translate(-50%,-50%)`;
};
</script>
<style scoped lang="scss">
.comtainer {
width: 100vw;
height: 100vh;
// no-repeat 表示不要重复平铺背景图像,即只显示一次,不会在水平和垂直方向重复。
background: url(./images/bg.png) no-repeat;
// cover 的意思是将背景图像等比例缩放,以覆盖整个元素的背景区域,确保背景图像完全覆盖并填充整个元素,无论元素的大小如何。
background-size: cover;
.screen {
// 设置定位让基点位于屏设备中心点
position: fixed;
left: 50%;
top: 50%;
width: 1920px;
height: 1080px;
background-color: red;
// 设置缩放基点为左上角 不能以盒子中心点
transform-origin: left top;
}
}
</style>