Canvans优缺点

基本使用

canvas 标签内部的内容是当前浏览器不兼容才会显示的
getContext(‘2d’)是用来获取上下文的api
<!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>
canvas {
background-color: rebeccapurple;
}
</style>S
</head>
<body>
<canvas id="canvs" width="200px" height="200px">
您的浏览器不兼容canvans
</canvas>
<script>
var c = document.querySelector('#canvs')
let ctx = c.getContext('2d')
console.log(ctx)
</script>
</body>
</html>
canvans的坐标系统

绘制矩形

使用
<!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>
canvas {
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="canvs" width="200px" height="200px">
您的浏览器不兼容canvans
</canvas>
<script>
var c = document.querySelector('#canvs')
let ctx = c.getContext('2d')
//绘制矩形
ctx.fillRect(0,0,100,100)
//绘制边框
ctx.strokeRect(100,100,10,10)
//清除矩形
ctx.clearRect(0,0,50,50)
</script>
</body>
</html>
效果

svg与canvans的区别
svg缩放不会失真模糊,因为是矢量图,做适配的话用svg

Echarts
根据官网进行一个demo
<!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>
</style>
</head>
<body>
<div id="main" style="width: 600px;height:400px;"></div>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.1/dist/echarts.min.js"></script>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var option = {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>
如果说我们想在vue/react组件中使用,那么我们需要注意要等待组件实例渲染完成再操作dom。
Echarts的渲染原理

可以在echarts.init()中进行渲染器的切换
options配置

坐标系配置

折线图

大屏适配方案
背景
近期公司投放在展厅大屏中演示的大数据页面,出现了文字、图表、表格等多类组件显示错乱的情况。
目的
解决页面错乱问题,实现多种分辨率的大屏适配
大屏适配方案1 – rem + font-size
动态设置HTML根字体大小 和 body 字体大小,也就是说要在缩放时动态改变HTML根字体大小 和 body 字体大小
我们可以写一个flexible.js来完成,监听onresize 事件
flexible.js
(function flexible(window, document) {
var docEl = document.documentElement;
var dpr = window.devicePixelRatio || 1;
console.log(dpr)
function setBodyFontSize() {
if (document.body) {
// 1.body 字体大小默认为 16px
document.body.style.fontSize = 16 * dpr + "px";
} else {
document.addEventListener("DOMContentLoaded", setBodyFontSize);
}
}
setBodyFontSize();
// 这里默认平均分成 10 等分(适用移动端)
function setRemUnit() {
// 2.这里改成了24,将网页分成 24 等份,这样每个 1rem 对应的为 80px
// 3.为什么要分成 24份 ? 目的是让缩放的细腻度更小,比如 0.1rem -> 8px
var rem = docEl.clientWidth / 24;
docEl.style.fontSize = rem + "px";
}
setRemUnit();
window.addEventListener("resize", setRemUnit);
window.addEventListener("pageshow", function (e) {
if (e.persisted) {
setRemUnit();
}
});
if (dpr >= 2) {
var fakeBody = document.createElement("body");
var testElement = document.createElement("div");
testElement.style.border = ".5px solid transparent";
fakeBody.appendChild(testElement);
docEl.appendChild(fakeBody);
if (testElement.offsetHeight === 1) {
docEl.classList.add("hairlines");
}
docEl.removeChild(fakeBody);
}
})(window, document);
假如你的大屏是1920px宽度
将设计稿的宽(1920)平均分成 24 等份, 每一份为 80px。
HTML字体大小就设置为 80 px,即1rem = 80px, 24rem = 1920px
body字体大小设置为 16px。
安装 cssrem 插件, root font size 设置为 80px。这个是px单位转rem的参考值
进入插件设置安装设计稿修改

接着就可以按照 1920px * 1080px 的设计稿愉快开发,此时的页面已经是响应式,并且宽高比不变。
我们将代码中的px手动改为rem即可,比如li的字体大小,div的宽高,这些改完后我们进行页面的缩放发现字体大小与宽高都会等比例缩放了
demo
<!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>
body {
margin: 0;
padding: 0;
}
ul {
margin: 0;
padding: 0;
}
body {
width: 24rem;
height: 13.5rem;
box-sizing: border-box;
background-color: rgba(255, 0, 0, 0.1);
border: 3px solid rebeccapurple;
}
ul {
display: flex;
flex-direction: row;
flex-wrap: wrap;
list-style: none;
width: 100%;
height: 100%;
}
li {
width: 33.333%;
height: 50%;
box-sizing: border-box;
border: 3px solid green;
font-size: 0.375rem;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<script src="../js/lib_flexible.js"></script>
</body>
</html>
大屏适配方案2 - vw
◼ 直接使用vw单位。
屏幕的宽默认为 100vw,那么100vw = 1920px, 1vw = 19.2px 。
安装 cssrem 插件, body的宽高(1920px * 1080px)直接把px单位转vw单位

接着就可以按照 1920px * 1080px 的设计稿愉快开发,此时的页面已经是响应式,并宽高比不变。
demo
<!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>
body,
ul {
margin: 0;
padding: 0;
}
body {
width: 100vw;
height: 56.25vw;
box-sizing: border-box;
border: 2px solid red;
background-color: rgba(255, 0, 0, 0.1);
}
ul {
display: flex;
flex-direction: row;
flex-wrap: wrap;
list-style: none;
width: 100%;
height: 100%;
}
li {
width: 33.333%;
height: 50%;
box-sizing: border-box;
border: 3px solid green;
font-size: 1.5625vw;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
</body>
</html>
大屏适配方案3(推荐) - scale
思路:
动态计算网页宽高比,决定是是否按照宽度的比率进行scale缩放。
demo
transform-origin: left top;代表设置缩放的原点为左上角
<!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>
body,
ul {
margin: 0;
padding: 0;
}
body {
position: relative;
box-sizing: border-box;
border: 2px solid red;
background-color: rgba(255, 0, 0, 0.1);
transform-origin: left top;
}
ul {
display: flex;
flex-direction: row;
flex-wrap: wrap;
list-style: none;
width: 100%;
height: 100%;
}
li {
width: 33.333%;
height: 50%;
box-sizing: border-box;
border: 3px solid green;
font-size: 30px;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<script>
window.onload = function () {
triggerScale();
window.addEventListener("resize", function () {
triggerScale();
});
};
function triggerScale() {
var targetX = 1920;
var targetY = 1080;
var targetRatio = 1920 / 1080;//宽高比率(16/9)
// 获取html的宽度和高度(不包含滚动条)
var currentX =
document.documentElement.clientWidth || document.body.clientWidth;
var currentY =
document.documentElement.clientHeight || document.body.clientHeight;
console.log(currentX, currentY)
// 1.缩放比例 3840 / 2160 => 2
var ratio = currentX / targetX;
var currentRatio = currentX / currentY;
var transformStr = "";
//超宽屏,如果还是参照宽度缩放,那么高度会有问题,因为宽高已经不等比了
if (currentRatio > targetRatio) {
ratio = currentY / targetY;//参照高度缩放
//除了缩放,还要进行居中
transformStr = `width:${targetX}px;height:${targetY}px; transform:scale(${ratio}) translateX(-${targetX / 2
}px); left:50%;`;
} else {
transformStr = `width:${targetX}px;height:${targetY}px; transform:scale(${ratio})`;
}
var bodyEl = document.querySelector("body");
// 2.需要修改缩放的原点
bodyEl.setAttribute("style", transformStr);
}
</script>
</body>
</html>
具体可以在app.vue的onMounted函数中通过节流执行这个函数
我们可以封装一个hook
useScalePage.js
import { onMounted, onUnmounted } from "vue";
import _ from "lodash";
export default function useScalePage() {
let resizeChange = _.throttle(function () {
triggerScale();
}, 100);
onMounted(function () {
triggerScale();
window.addEventListener("resize", resizeChange);
});
onUnmounted(function () {
console.log("useScale onUnmounted");
window.removeEventListener("resize", resizeChange);
});
function triggerScale(option = {}) {
let targetX = option.targetX || 1920;
let targetY = option.targetY || 1080;
let targetRatio = option.targetRatio || 16 / 9;
// 1.拿到当前屏幕的宽高
let currentX =
document.documentElement.clientWidth || document.body.clientWidth;
let currentY =
document.documentElement.clientHeight || document.body.clientHeight;
// 2.计算缩放的比例
let scaleRatio = currentX / targetX;
// 当前的屏幕宽高比
let currentRatio = currentX / currentY;
if (currentRatio > targetRatio) {
scaleRatio = currentY / targetY;
// 3.设置缩放( 类似图片放大 )
document.body.setAttribute(
"style",
`width:${targetX}px;height:${targetY}px;transform: scale(${scaleRatio}) translateX(-50%); left:50%`
);
} else {
// 3.设置缩放( 类似图片放大 )
document.body.setAttribute(
"style",
`width:${targetX}px;height:${targetY}px;transform: scale(${scaleRatio})`
);
}
}
}
app.vue

三种适配方案的对比

文章探讨了HTML5的Canvas标签及其坐标系统,展示了如何绘制矩形和清除区域。同时,提到了Canvas与SVG的区别,SVG作为矢量图在缩放时不失真。文章还通过Echarts的示例说明了在Web开发中的数据可视化应用,并讨论了在Vue或React组件中使用Echarts的注意事项。最后,文章深入介绍了多种大屏适配方案,包括使用rem、vw单位和scale函数,以解决不同分辨率下页面布局的问题。
2873

被折叠的 条评论
为什么被折叠?



