一、什么是可视化
•可视化是利用计算机图形学和图像处理技术,将数据转换成图形或图像在屏幕上显示出来,并进行交互处理的理论、方法和技术。
•个人理解:首先,不仅是一种技术,更是一门学科。它涉及到计算机图形学、图像处理技术、计算机视觉、计算机辅助设计等多个领域。它是运用这些学科中的各种技术,以2d/3d等视觉效果、以可交互的形式呈现在用户面前,让用户能以更直观的方式去体会、理解并去交互的一种技术。
二、可视化的类型
1、科学可视化
面向的领域主要是自然科学,如物理、化学、气象气候、航空航天、医学等领域。
2、信息可视化
处理的对象是与我们密切相关的抽象数据集合。它起源于统计图形学,表现形式主要在二维空间,要在有限的展现空间中以直观的方式传达大量的抽象信息。
3、可视分析学
它是一门以可视交互为基础的分析推理科学。综合了图形学、数据挖掘、人机交互等技术,以可视交互界面为通道,将人感知和认知能力以可视的方式融入数据处理过程,形成人脑智能和机器智能优势互补和相互提升,完成有效的分析推理和决策。
三、前端如何实现可视化
1、html + css
怎么实现?
1)、css过渡属性transition
2)、css转换属性 transform (2d或3d的转换,旋转、缩放、移动、倾斜)
3)、 css阴影 box-shadow (blur模糊处理,高斯模糊...)
4)、 css动画 animation (可实现帧动画)
5)、 css3D perspective (可实现3d场景效果)
......
css动画库
2、svg
定义
1)、是一种矢量图形语言
2)、使用 XML格式定义图形,可选可搜索
优势
1)、放大后分辨率不会改变,更适合制作地图
2)、让前端操作起来更熟悉,类似操作dom
3)、与普通的图片格式比起来压缩性更强
库
性能优化
1)、将属性“Pointer-event”设置为None,如果一个元素不需要产生任何事件的话,最好吧这个属性设置成none。其实每个元素都有很多事情,一次鼠标移动就可以让有用没有用的事件被激活,即便是没有事件处理函数,SVG解析器也是要处理这些事件消息的。所以为了减少解析器的工作负担,就直接屏蔽掉最好。
2)、重复标签定义在defs中。defs标签的作用就是为了复用,其实在软件开发过程中复用的思想是不可或缺的,在svg技术中也是如此。Defs和g标签是容器元素,但是在defs元素的子元素在解析的时候不会渲染,只有在use的时候才会渲染。
3)、减少透明度使用。对于opacity透明度来说,使用透明度确实能够增加美观度,但是却牺牲了很大的性能,如果有可能的话尽量使用fill-opacity或者stroke-opacity这两个开销小些的属性。
4)、重绘区域尽可能小,大量的绘制都会增加cpu使用率,导致性能额外消耗,如果只是更新一部分图形,则只需要重绘一部分即可。
5)、减少色彩渐变和滤镜
6)、从服务器端生成SVG发送到客户端
7)、尽量减少animate动画(例如飞线、粒子等效果)
3、canvas
特性
1)、H5新特性
2)、逐像素进行渲染
使用
ctx.getContext("2d")
优势
1)、性能优秀
2)、适合图像密集型的绘制
是一个dom元素,本身不具备绘制能力,需要使用js来绘制,通过canvas元素创建context对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法
性能:canvas的性能不会因为画布上图案多少而改变,
库
ZRender.js(Echarts底层渲染引擎)
性能优化
1)、总体思路
每一帧中,尽可能减少调用渲染相关的API次数
在每一帧中,尽可能调用那些渲染开销较低的API
在每一帧中,尽可能以导致开销最低的方式调用渲染相关API
2)、context的一些属性赋值开销
| 属性 | 开销ms | 开销(非法赋值) |
|---|---|---|
| font | 1000+ | 1000+ |
| shadowColor | 280+ | 400+ |
| fillStyle、strokeStyle | 100+ | 200+ |
| textAlign、textBaseline | 60+ | 100+ |
| lineWidth、lineJoin | 40+ | 100+ |
3)、分层canvas
使用多个canvas实例,将他们重叠放置,利用z-index属性控制层级,只重绘需要改变的canvas画布
4)、离屏渲染: drawImage()
将需要重复绘制的对象先缓存到一个canvas画布中,等需要用到的时候直接调用一次drawImage()API就行,不需要重复调用多个canvas API,极大的提高性能。
5)、需要大量计算数据的场景
不要在渲染的过程中计算大量数据,这样会阻塞渲染,使用webWorker,在另一个线程中进行计算
Canvas VS SVG
在开发可视化组件之前技术选型很重要,选择适合当前场景的绘制技术能大大增强页面渲染性能
Svg:
1)、不依赖分辨率
2)、支持事件处理
3)、最适合带有大型渲染区域的应用程序
4)、复杂度高会减慢渲染速度
Canvas
1)、依赖分辨率
2)、不支持事件处理
3)、弱的文本渲染能力
4)、能够以 .png 或 .jpg 格式保存结果图像
5)、适合小分辨率,大数据量绘制的场景
4、webgl
定义
是一项用来在网页上绘制和渲染复杂三维图形,并允许用户与其交互的技术
优势
1)、允许js在网页上显示和操作三维图形
2)、可以利用gpu加速渲染复杂的三维模型,大幅度提高用户体验
引擎库
WebGL程序结构
传统的动态网页包括html跟js两种语言,当引入webgl后,还需要加入着色器语言GLSL ES,也就是说,webgl网页包含了三种语言:html、js、GLSL ES。通常GLSL ES是以字符串的形式在js中编写,所以实际上也只需用到html文件跟js文件即可。
Shader(可编程渲染管线/着色器)
1)、是使用一种叫GLSL的类C语言写成的
2)、分为顶点着色器(vertexShader)和片源着色器(fragmentShader)
通过一系列set的api将数据输入
顶点着色器中计算一系列的矩阵变换(平移、旋转、投影、视图等)、光照等
片源着色器中进行光栅化、纹理采样、差值计算、像素处理、透明度测试、深度测试以及混合测试等,最后输出
光栅化就是把顶点数据转换为片元的过程。片元中的每一个元素对应于帧缓冲区中的一个像素。光栅化其实是一种将几何图元变为二维图像的过程。
\
GLSL ES——OpenGL ES着色器语言
概述
GLSL ES是在OpenGL的基础上简化删除了一部分功能后形成的。它的目标平台包括电子设备产品或嵌入式设备,如智能手机或游戏主机等。简化GLSL ES能够允许硬件厂商对这些设备的硬件进行简化,由此降低硬件功耗、减少性能开销。
着色器是webgl渲染三维图形的关键,GLSL ES是专门用来编写着色器的编程语言
Js可以用var指定所有变量,但是GLSL要求你具体指明变量的数据类型,类似TS,必须时刻注意变量的类型
取样器就是能访问纹理的变量,比如我们传入的图片、后期加入一些效果时需要将当前帧画面存入缓存,也是用取样器去读取纹理
强类型语言
类型
数值类型: float、int
布尔值类型: bool
矢量类型: vec2、vec3、vec4、ivec2、ivec3、ivec4、bvec2、bvec3、bvec4
矩阵类型: mat2、mat3、mat4
取样器类型: sampler2D、samplerCube
WebGL中可绘制的基本图形
gl.TRIANGLE_STRIP计算方式:为了使法线统一,三角形的计算有奇偶两种环绕规则
webgl中如何改变模型的位置?矩阵
矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,通过矩阵可以对webgl中的所有物体进行坐标转换
webgl中最重要的三种矩阵
-
模型矩阵-
平移矩阵
-
缩放矩阵
-
旋转矩阵
- 沿X轴旋转
- 沿Y轴旋转
- 沿Z轴旋转
- 沿X轴旋转
-
2)、视图矩阵
在模型矩阵中,我们关心的是空间中的点在经历变换后在世界坐标系下的位置。事实上,我们更加关心空间中的点相对于观察者的位置。最简单的方案是将观察者置于原点处,面向z轴(或x轴、y轴)正半轴,那么空间中的点在世界坐标系下的位置就是其相对于观察者的位置。
观察者的位置和方向会变化,看上去就好像整个世界的位置和方向发生变化了一样,所以解决的方案很简单,将世界里的所有模型看作一个大模型,在所有模型矩阵的左侧再乘以一个表示整个世界变换的模型矩阵,就可以了。这个表示整个世界变换的矩阵又称为“视图矩阵”,因为他们经常一起工作,所以将视图矩阵乘以模型矩阵得到的矩阵称为“模型视图矩阵”。
视图矩阵可以称为模型矩阵的逆矩阵。
3)、投影矩阵
模型视图矩阵的作用是确定某一帧中,空间里每个顶点的坐标,而投影矩阵则将这些顶点坐标映射到二维的屏幕上
主要有两种投影方式
四、定时循环操作接口
1、requestAnimationFrame是什么?
浏览器用于定时循环操作的一个接口
主要用途是按帧对网页进行重绘,让各种网页动画效果(DOM动画、Canvas动画、SVG动画、WebGL动画)能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。
2、为什么不用setTimeout或setInterval?
严重的性能问题
普通的js动画之前用的都是定时器,css3出来之后,大大提升了性能和流畅度,但是css3也有局限性,不是所有属性都能参与动画、动画效果太少、无法完全控制动画过程等等,但是setTimeout和setInterval有严重的性能问题,怎么解决?使用requestAnimationFrame
它会紧紧跟随浏览器的刷新频率来逐帧重绘,充分利用显示器的刷新机制,节省系统资源。
当切换对话窗口或者最小化时,setTimeout和setInterval还是在执行当中,而requestAnimationFrame则会暂停渲染,直到页面被激活才会再次执行帧渲染,节省了cpu\gpu的开销
3、如何用?
const timer = window.requestAnimationFrame(callback)
window.cancelAnimationFrame(timer)