前端可视化 - 灰灰

940 阅读10分钟

一、什么是可视化

•可视化是利用计算机图形学和图像处理技术,将数据转换成图形或图像在屏幕上显示出来,并进行交互处理的理论、方法和技术。
•个人理解:首先,不仅是一种技术,更是一门学科。它涉及到计算机图形学、图像处理技术、计算机视觉、计算机辅助设计等多个领域。它是运用这些学科中的各种技术,以2d/3d等视觉效果、以可交互的形式呈现在用户面前,让用户能以更直观的方式去体会、理解并去交互的一种技术。

二、可视化的类型

1、科学可视化

面向的领域主要是自然科学,如物理、化学、气象气候、航空航天、医学等领域。       image.png

2、信息可视化

处理的对象是与我们密切相关的抽象数据集合。它起源于统计图形学,表现形式主要在二维空间,要在有限的展现空间中以直观的方式传达大量的抽象信息。

image.png

3、可视分析学

      它是一门以可视交互为基础的分析推理科学。综合了图形学、数据挖掘、人机交互等技术,以可视交互界面为通道,将人感知和认知能力以可视的方式融入数据处理过程,形成人脑智能和机器智能优势互补和相互提升,完成有效的分析推理和决策。

image.png

三、前端如何实现可视化

1、html + css

      怎么实现?

          1)、css过渡属性transition

          2)、css转换属性 transform (2d或3d的转换,旋转、缩放、移动、倾斜)

          3)、 css阴影 box-shadow (blur模糊处理,高斯模糊...)

          4)、 css动画 animation (可实现帧动画)

          5)、 css3D perspective (可实现3d场景效果)

          ......

image.png

        css动画库

2、svg

      定义

             1)、是一种矢量图形语言

             2)、使用 XML格式定义图形,可选可搜索

      优势

             1)、放大后分辨率不会改变,更适合制作地图

             2)、让前端操作起来更熟悉,类似操作dom

             3)、与普通的图片格式比起来压缩性更强

       库

           d3.js

       性能优化

             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动画(例如飞线、粒子等效果)              image.png

3、canvas

      特性

            1)、H5新特性

            2)、逐像素进行渲染

      使用

            ctx.getContext("2d")

image.png

      优势

            1)、性能优秀

            2)、适合图像密集型的绘制

            是一个dom元素,本身不具备绘制能力,需要使用js来绘制,通过canvas元素创建context对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法

            性能:canvas的性能不会因为画布上图案多少而改变,

       库

             ZRender.js(Echarts底层渲染引擎)

性能优化

             1)、总体思路

      每一帧中,尽可能减少调用渲染相关的API次数
      在每一帧中,尽可能调用那些渲染开销较低的API
      在每一帧中,尽可能以导致开销最低的方式调用渲染相关API

             2)、context的一些属性赋值开销

属性开销ms开销(非法赋值)
font1000+1000+
shadowColor280+400+
fillStyle、strokeStyle100+200+
textAlign、textBaseline60+100+
lineWidth、lineJoin40+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)、适合小分辨率,大数据量绘制的场景

image.png

4、webgl

      定义

              是一项用来在网页上绘制和渲染复杂三维图形,并允许用户与其交互的技术

      优势

            1)、允许js在网页上显示和操作三维图形

            2)、可以利用gpu加速渲染复杂的三维模型,大幅度提高用户体验

      引擎库

             Three.js

             Babylon.js

             PlayCanvas.js

             Thing.js

WebGL程序结构

             传统的动态网页包括html跟js两种语言,当引入webgl后,还需要加入着色器语言GLSL ES,也就是说,webgl网页包含了三种语言:html、js、GLSL ES。通常GLSL ES是以字符串的形式在js中编写,所以实际上也只需用到html文件跟js文件即可。

image.png

Shader(可编程渲染管线/着色器)

            1)、是使用一种叫GLSL的类C语言写成的
2)、分为顶点着色器(vertexShader)和片源着色器(fragmentShader)     

image.png              通过一系列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计算方式:为了使法线统一,三角形的计算有奇偶两种环绕规则

image.png

webgl中如何改变模型的位置?矩阵

                    矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,通过矩阵可以对webgl中的所有物体进行坐标转换

image.png

webgl中最重要的三种矩阵

  • 模型矩阵 
    
    • 平移矩阵image.png

    • 缩放矩阵 image.png

    • 旋转矩阵

      • 沿X轴旋转 image.png
      • 沿Y轴旋转 image.png
      • 沿Z轴旋转 image.png                  

2)、视图矩阵

在模型矩阵中,我们关心的是空间中的点在经历变换后在世界坐标系下的位置。事实上,我们更加关心空间中的点相对于观察者的位置。最简单的方案是将观察者置于原点处,面向z轴(或x轴、y轴)正半轴,那么空间中的点在世界坐标系下的位置就是其相对于观察者的位置。

观察者的位置和方向会变化,看上去就好像整个世界的位置和方向发生变化了一样,所以解决的方案很简单,将世界里的所有模型看作一个大模型,在所有模型矩阵的左侧再乘以一个表示整个世界变换的模型矩阵,就可以了。这个表示整个世界变换的矩阵又称为“视图矩阵”,因为他们经常一起工作,所以将视图矩阵乘以模型矩阵得到的矩阵称为“模型视图矩阵”。

视图矩阵可以称为模型矩阵的逆矩阵。

                   

  3)、投影矩阵

      模型视图矩阵的作用是确定某一帧中,空间里每个顶点的坐标,而投影矩阵则将这些顶点坐标映射到二维的屏幕上

  主要有两种投影方式

image.png

四、定时循环操作接口

       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) image.png