# 前端可视化
# 可视化的概念
想快速了解这个热门实用的技术,首先,你得知道可视化的概念是什么。
可视化是利用计算机图形学和图像处理技术,将数据转换成图形或图像在屏幕上显示出来,再进行交互处理的理论、方法和技术。
# 可视化的类型
它主要分为以下三个分支:科学可视化、信息可视化、可视分析学。
# 科学可视化
科学可视化是可视化领域最早、最成熟的一个跨学科研究与应用领域。
面向的领域主要是自然科学,如物理、化学、气象气候、航空航天、医学、生物学等各个学科,这些学科通常需要对数据和模型进行解释、操作与处理,旨在寻找其中的模式、特点、关系以及异常情况。
# 信息可视化
信息可视化处理的对象是抽象数据集合,起源于统计图形学,又与信息图形、视觉设计等现代技术相关。
其表现形式通常在二维空间,因此关键问题是在有限的展现空间中以直观的方式传达大量的抽象信息。
# 可视分析学
可视分析学被定义为一门以可视交互为基础的分析推理科学。
它综合了图形学、数据挖掘和人机交互等技术,以可视交互界面为通道,将人感知和认知能力以可视的方式融入数据处理过程,形成人脑智能和机器智能优势互补和相互提升,建立螺旋式信息交流与知识提炼途径,完成有效的分析推理和决策。
# 可视化的实现
回到生活和工作中,人们最常用的获取信息咨询的方式之一就是搜索引擎,下面简单的介绍下在浏览器中的Web前端页面有哪些方式可以实现可视化。
Html + Css
我们在浏览器中所看到的内容,大概80%以上都是用此方式来实现的。简单的说,html就是页面中一个个整齐的文字,图片,视频等元素,我们用搭积木的方式将各种元素拼凑起来,形成我们主要的信息内容。
而css则可以控制这些积木的大小、形状、颜色的样式。两者结合即可构成我们日常中看到的网页。
Svg
svg是一种图片格式,它作为矢量图,能在各个分辨率下都能呈现良好的图片效果,并能构建出各式各样的形状,使我们的页面更加美观。
Canvas
你可以把它想象成一张白纸,它允许你在白纸上自由的绘画,并将画完后的图形呈现在页面上。
它还可以用来实现动画和游戏,毕竟这两者的原理就是在固定时间内,迅速按顺序展示多张图片,利用人类的视觉暂留特性来实现的。
WebGL
它是一种3D绘图协议,我们在网页中看到的许多3d特效都离不开它。它利用到了电脑中显卡的性能来进行加速渲染,在性能上比前3者都高出了不少。
这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等
看了以上概念性的内容是否更加摸不着头脑?下面再看看代码实现上有什么区别。
我们将用上面4种技术来绘制一个下面这样简单的三角形。
html + css代码实现:
<div class="triangle"></div>
.triangle {
width: 0;
height: 0;
border-bottom: 100px solid #00FFFF;
border-left: 50px solid transparent;
border-right: 50px solid traansparent;
}
2
3
4
5
6
7
8
Svg代码实现:
<svg width="100%" height=300px version="1.1" xmlns="https://www.w3.org/200/svg">
<path d="M 150 0 L 300 240 L0 240 Z" fill="cyan">
</svg>
2
3
Canvas代码实现:
<canvas id="testCanvas"></canvas>
init() {
const canvasObj = document.getElementById("testCanvas");
const ctx = canvasObj.getContext("2d");
ctx.beginPath();
ctx.moveTo(150,0);
ctx.lineTo(300,240);
ctx.closePath();
ctx.fillStyle = "cyan";
ctx.fill();
}
2
3
4
5
6
7
8
9
10
11
WebGL代码实现:
<canvas id="testCanvas" width="300" height="240"></canvas>
init() {
const canvasObj = document.getElementById("testCanvas");
const ctx = canvasObj.getContext("webgl");
//编写着色器
const vertex =
attribute vec2 position;
void mail() {
gl_PointSize = 1.0;
gl_Position = vec4(position, 1.0, 1.0);
} ;
const fragment =
precision mediump float;
void mail() {
gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);
};
//创建着色器对象
const vertexShader = ctx.createShader(ctx.VERTEX_SHADER);
ctx.shaderSource(vertexShader, vertex);
ctx.compileShader(vertexShader);
const fragmentShader = ctx.createShader(ctx.FRAGMENT_SHADER);
ctx.shaderSource(fragmentShader, fragment);
ctx.compileShader(fragmentShader);
//创建webGLProgram对象
const program = ctx.createProgram();
ctx.attachShader(program,vertexShader);
ctx.attachShader(program,fragmentShader);
ctx.linkProgram(program);
ctx.useProgram(program);
//定义三角形定点
const points = new Float32Array([ -1, -1, 0, 1, 1, -1,]);
//将定义好的数据写入webGL缓冲区
const bufferId = ctx.createBuffer();
ctx.bindBuffer(ctx.ARRAY_BUFFER, bufferId);
ctx.bindBuffer(ctx.ARRAY_BUFFER, points, ctx.STATIC_DRAW);
//将缓冲区数据读取到GPU中
const vPosition = ctx.getAttribLocation(program, 'position');
ctx.vertexAttribPointer(vPosition, 2, ctx.FLOAT, false, 0, 0);
ctx.enableVertexAttribArray(vPosition);
//执行着色器程序完成绘制
ctx.clear(ctx.COLOR_BUFFER_BIT);
ctx.drawArrays(ctx.TRIANGLES, 0, points.length / 2);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 可视化的区别
HTML+CSS
优点: 方便,不需要第三方依赖,甚至不需要 JavaScript 代码。如果我们要绘制少量常见的图表,可以直接采用 HTML 和 CSS。
缺点: CSS 属性不能直观体现数据,绘制起来也相对麻烦,图形复杂会导致 HTML 元素多,而消耗性能。
SVG
优点: SVG是对 HTML/CSS 的增强,弥补了 HTML 绘制不规则图形的能力。它通过属性设置图形,可以直观地体现数据,使用起来非常方便。
缺点: 图形复杂时需要的 SVG 元素太多,也非常消耗性能。
Canvas2D
优点: 浏览器提供的简便快捷的指令式图形系统,它通过一些简单的指令就能快速绘制出复杂的图形。由于它直接操作绘图上下文,因此没有 HTML/CSS 和 SVG 绘图因为元素多导致消耗性能的问题,性能要比前两者快得多。
缺点: 如果要绘制的图形太多,或者处理大量的像素计算时,Canvas2D 依然会遇到性能瓶颈。
WebGL
优点: WebGL是浏览器提供的功能强大的绘图系统,功能强大,能够充分利用GPU 并行计算的能力,来快速、精准地操作图像的像素,在同一时间完成数十万或数百万次计算。它还内置了对 3D 物体的投影、深度检测等处理,这让它更适合绘制 3D 场景。
缺点: 使用比较复杂。
综合来看,四种可视化方法各有各的优势和擅长的场景,使用起来还需要根据具体的场景来进行选择。
# canvas绘画
# 1、简介
h5新增的标签,它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。
- 用途:绘制图表(Echars)、游戏、活动页面,动画小特效
- 相关框架
- 数据可视化:D3、antV、Echars
- 游戏:Eva.js
# 2、坐标体系
自上而下,自左从右,原点(0,0)在左上角,正常坐标系的第四象限
# 3、相关API
<canvas id="canvas" width="500" height="500"></canvas>
<script>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
</script>
2
3
4
5
# 1、矩形API
context.fillRect(xPot, yPot, width, height),实心矩形,默认黑色
context.strokeRect(xPot, yPot, width, height),空矩形,默认黑色
# 2、线条API
context.beginPath();
context.moveTo(xPot, xPot); //设置起点
context.lineTo(xPot, xPot); //设置经过点
context.closePath(); //自动闭合回到起点
context.stroke(); //输出轮廓
context.fill(); //填充内容
# 3、圆弧API
context.arc(x, y, radius, startAngle, endAngle, anti-clockwise)
- x:圆的中心的x坐标
- y:圆的中心的y坐标
- radius:圆的半径
- startAngle:圆弧的开始角度,使用弧度表示
- endAngle:圆弧的结束角度
- antiClockwise:可选,顺时针还是逆时针,默认false,顺时针
var degree = 1; // 表示 1°
var radians = degree * (Math.PI / 180); // 0.0175弧度
//画实心圆
context.beginPath();
context.arc(250, 250, 200, 0, 2*Math.PI, false)
context.fill();
2
3
4
5
6
# 4、文本API
context.fillText(text, x, y) //实心字体
context.strokeText(text, x, y) //空心字体
context.font = "italic 60px serif" //字体(font-style)、字体大小、font-family
context.fillStyle = color
context.strokeStyle = "red #ff000 rgb(255, 0, 0) rgba(255, 0, 0, 0)"
context.lineWidth = 5 //设置线的宽度
# 5、插除
context.clearRect(x, y, width, height)
# 6、加载图像
context.drawImage(image, x, y, width, height)
var image = new Image()
image.src = "http://xxxx.svg"
image.onload = function(){//保证图片加载完成
context.drawImage(image, 50, 50, 120, 20);
}
2
3
4
5
# 7、动画
循环播放下一针画面,60Hz,使用requestAnimFrame
<html>
<head>
<title>canvas</title>
</head>
<body>
<canvas id="canvas" width="500" height="200" style="border: 1px solid #333333"></canvas>
<script>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
//兼容定义requestAnimFrame
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 30);
};
var circle = {
x: 500,
y: 100,
radius: 50,
direction: 'right',
move: function () {
if (this.direction === 'right') {
if (this.x <= 430) {
this.x += 5;
} else {
this.direction = 'left';
}
} else {
if (this.x >= 60) {
this.x -= 5;
} else {
this.direction = 'right';
}
}
},
draw: function () {
context.beginPath();
context.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
context.fillStyle = '#00c09b';
context.fill();
}
}
function animate() {
circle.move();
context.clearRect(0, 0, canvas.width, canvas.height);
circle.draw();
requestAnimationFrame(animate);
}
circle.draw();
animate();
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 8、键盘
监测键盘上下按键,移动。
碰撞检测:矩形检测左、右、顶、底侧,圆形检测距离小于半径和
if(!(rect2.x + rect2.width < rect1.x) &&
!(rect1.x + rect1.width < rect2.x) &&
!(rect2.y + rect2.height < rect1.y) &&
!(rect1.y + rect1.height < rect2.y)){
//矩形碰撞了
}
2
3
4
5
6