前言
随着前端越来越卷,如果只懂得前端三件套、Vue
、React
,未来在职场的竞争力可能会比较弱。随着5G时代的到来以及浏览器内核的不断优化和增强,前端未来在数据可视化、AR、AI
等领域会比较香。本着只要卷不死就往死里卷的原则,从本篇开始就开始系统学习可视化,这个系列将分为以下几部分进行:
- canvas && svg基础
- ECharts基础
- WebGL基础
- three.js基础
- 地图可视化基础
- 数据报表项目实战
- 数据大屏展示实战
- 移动报表实战
- 打造自己的3D博客网站
数据可视化解决方案
如上图所示,前端领域可视化的技术非常多,每个技术都够你折腾一年半载的。Skia
,OpenGL
这种底层的我们前端cv工程师基本接触不到,如果你从事的是web
网页开发(比如我),平时开发可能就会用到canvas
绘制个图片,svg
做个动图,展示类项目可能会用到ECharts
图表。
入门一个技术,前期最重要是快!先学会使用,所以本文开始,我将通过3篇文章光速过入门一下前置基础知识(canvas、svg、webGL、ECharts
)。我是文章作者,也是学习者,文中如有不对还请指出。文章只涉及各个技能点的基本使用,想深度学习的同学可自行网上冲浪🚤。
ok,本篇开始学习canvas
和svg
1. Canvas
canvas
是 HTML5
的新特性,它允许我们使用 canvas
元素在网页上通过 JavaScript
绘制图像。
Canvas
拥有多种绘制路径、矩形、圆形、字符以及图片的方法。Canvas
可用于动画、游戏、数据可视化、图片编辑器、实时视频处理等领域。
1.1 入门案例:绘制文本/线条/点/矩形/圆形
总结:
- 编写 canvas 标签(注意指定宽高)
- 获取 canvas DOM 对象
- 获取 Canvas 对象
- 设置绘图属性
- 调用绘图 API
1.2 canvas动画
由上面的的入门案例可以看到我们需要调用canvas
提供的API
绘制完之后才能在浏览器看到,所以想要实现动画我们需要借助window
对象提供的3个setInterval
、setTimeout
、requestAnimationFrame
API配合canvas API
提供的几何变换(translate(平移)、rotate(旋转)、scale(缩放)、transform(可实现各种变换)
)和状态来实现动画。ok,下面我们用requestAnimationFrame
实现一个小时候家里彩色电视机的简单小球屏保动画。
ok,再写一个经常在博客网站看到的粒子动画背景。之前看到类似的粒子动画就很好奇是如何实现的,今天就现学现卖画一个。说一下大概思路:
-
通过canvas的fillRect()方法创建一定数量的粒子放到
dots[]
中 -
遍历粒子,并使粒子做随机运动
-
判断两个粒子之间的距离,当距离小于某个数值时将两个粒子相连
-
添加鼠标事件进行交互
tip:传送门--> Canvas 教程 - Web API 接口参考 | MDN (mozilla.org)
2. SVG
SVG
是一种基于XML
的图像文件格式,它的英文全称为Scalable Vector Graphics
,意思为可缩放的矢量图形。
语法:
<svg> <rect width="100" height="100" fill="gold" /> </svg>
需要注意的点:
- 因为XML和HTML不同,XML是区分大小写的,而SVG是使用XML格式来定义图形,所以在编写SVG的的时候元素和属性必须按标准格式书写。
- SVG默认为宽高为300 * 150,如果不设置svg尺寸,当内部元素大于300 * 150时,大于部分会被隐藏。
2.1 入门案例
下面就直接上代码实现上面canvas一样的功能。
2.2 path拓展
上面的入门案例中path
标签是所有图形中最复杂的,但他也是最强大的。可以绘制圆形、椭圆、矩形、线条、折线、多边形、贝塞尔曲线等。如果你刚接触svg可能会一脸懵,现在对path
做如下拓展:
path
标签的图形形状通过属性d(命令+参数)来定义,有如下10个命令:
M = Move to(把画笔移动到某个点,如果有多个M命令则表示新路径的开始)
L = Line to(与之前的点连成一条线)
<svg width="300" height="300">
<!-- 从起始点(50, 20)画一条到(250, 20)的直线 -->
<path d="M50 20 L250 20" style="stroke: #000;" />
<!-- M命令为多个时,后面的M命令为先线段的起始点 -->
<path d="M50 50 L250 50 M50 100 L250 50" style="stroke: #000;" />
<!-- 从起始点(50, 150)画一条到(250, 150)的直线 -->
<!-- M命令后面连续跟着多个坐标点,除了第一个坐标点,后面的全部默认为隐式的L命令 -->
<path d="M50 150 250 150 " style="stroke: #000;" />
<!-- 多个L命令连续可以省略后面的L命令 -->
<path d="M50 200 L250 200 250 250 300 250" fill="none" style="stroke: #000;" />
</svg>
H = Horizontal Line to(从之前的点绘制一条水平的直线,H命令可以等价于y值和之前点相同的L命令)
<svg width="300" height="300">
<!-- 从起始点(50, 20)画一条X轴为300的水平直线 -->
<path d="M50 20 H300" style="stroke: #00FFFF;" />
</svg>
V = Vertical Line to(从之前的点绘制一条垂直的直线,V命令可以等价于x值和之前点相同的L命令)
<svg width="300" height="300">
<!-- 从起始点(50, 20)画一条Y轴为300的垂直直线 -->
<path d="M50 20 V300" style="stroke: #000;" />
</svg>
Q = Quadratic Bezier Curve to(绘制一条二次贝塞尔曲线)
语法:Q x1 y1, x y 或者 q x1 y1, x y
参数:x、y为终点位置,x1、y1为控制点。
<svg width="300px" height="300px">
<path d="M50 100 Q 175 200 300 100" fill="none" style="stroke: #00FFFF;" />
</svg>
T = Smooth Quadratic Bezier Curve to(延长二次贝塞尔曲线的简化命令,T命令的的前面必须有一个Q命令或者其他的T命令。如果T命令单独使用,那么控制点就会被认为和终点是同一个点,所以画出来的将是一条直线)
语法:T x y 或者 t x y
参数:x、y为终点位置。
<svg width="600px" height="300px">
<path d="M50 100 Q 175 200 300 100 T 600 100 " fill="none" style="stroke: #b6dd49;" />
</svg>
C = Curve to(绘制一条三次贝塞尔曲线)
语法:C x1 y1, x2 y2, x y 或者 c x1 y1, x2 y2, x y
参数:x、y为终点位置,x1、y1为曲线起始点的控制点,x2、y2为曲线终止的控制点。
<svg width="300" height="300">
<path d="M50 50 C 100 100, 200 100, 250 50" fill="none" style="stroke: #dc4242;" />
<path d="M50 200 C 100 250, 200 150, 250 200" fill="none" style="stroke: #6099df;" />
</svg>
S = Smooth Curve to(三次贝塞尔曲线的S命令和二次贝塞尔曲线的T命令比较相似)
语法:S x2 y2, x y 或者 s x2 y2, x y
参数:x、y为终点位置,x2、y2为曲线终止的控制点。
<svg width="300px" height="300px">
<path d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" fill="none" style="stroke: #ff0000;" />
</svg>
A = Elliptical Arc(用于画弧形,它可以截取圆或椭圆的弧形成的曲线)
语法: A rx ry x-axis-rotation large-arc-flag sweep-flag x y 或者 a rx ry x-axis-rotation large-arc-flag sweep-flag x y
参数:
- rx、ry分别为X轴的半径和Y轴的半径
- x-axis-rotation为弧度在X轴的旋转角度
- large-arc-flag决定弧线是大于还是小于180度,0表示小角度弧,1表示大角度弧
- sweep-flag为弧的方向,0表示从起点到终点沿逆时针画弧,1表示从起点到终点沿顺时针画弧
- x、y为弧形的终点
<svg width="300px" height="1000px">
<path d="M10 50 50 50 A 30 50 0 0 1 100 50 L 200 50" fill="none" style="stroke: #000" />
<!-- 旋转45度的弧(第三个参数) -->
<path d="M10 100 50 100 A 30 60 40 0 1 100 100 L 200 100" fill="none" style="stroke: #000" />
<!-- 1表示大角度弧(第四个参数) -->
<path d="M10 150 50 150 A 30 30 -45 1 1 150 150 L 200 150" fill="none" style="stroke: #000" />
<!-- 0逆时针(第五个参数) -->
<path d="M10 200 50 200 A 30 20 0 0 0 150 200 L 200 200" fill="none" style="stroke: #000" />
</svg>
Z = close path(闭合命令,从当前点画一条直线到路径的起始点)
<svg width="300" height="300">
<path d="M50 20 H200 V200 Z" fill="none" style="stroke: #000;" />
</svg>
2.3 SVG动画
从以上对path
命令的说明我们可以看到其实要我们手写svg
代码其实不现实,简单的形状还好,复杂点的形状,手写代码会变得很吃力。所以svg
文件一般都是UI设计好直接导出给我们前端。svg
的动画也一样,虽然可以配合JavaScript
或者css
来实现,但是复杂的动画写起来会很费劲,加上大量使用css
实现动画性能会跟不上。这里我就直接推荐一些优秀的svg
动画库了。
优秀的 SVG 类库
类库 | 描述 |
---|---|
GSAP | Sarah Drasner Recommend, The best one. |
Snap.svg | The "jQuery" of SVG |
Velocity.js | Velocity offers a lot of the sequencing that GreenSock does, but without a lot of the bells and whistles |
React-Motion | React TechStack |
Vivus.js | Vivus is a lightweight JavaScript class (with no dependencies) that allows you to animate SVGs, giving them the appearence of being drawn |
anime.js | Anime.js (/ˈæn.ə.meɪ/) is a lightweight JavaScript animation library with a simple, yet powerful API. It works with CSS properties, SVG, DOM attributes and JavaScript Objects. |
SVG.js | The lightweight library for manipulating and animating SVG. |
d3.js | Bring data to life with SVG, Canvas and HTML. |
Sprite.js | SpriteJS 是跨平台的高性能图形系统,它能够支持web、node、桌面应用和小程序的图形绘制和实现各种动画效果。 |
这里比较推荐GreenSock(GSAP)相比之下 GSAP 有以下优点:
- 几乎可以让任何元素动起来,包括 SVG
- 语法简洁,容易上手
- 拥有操作时间轴功能,对制作线性动画有很大帮助
- 样例丰富,在 CodePen 上有大量 Demo
- 插件功能强大,包括 DrawSVG、MorphSVG 等
- 性能良好,兼容性良好
下面我们就简单上手一下,开整:
简单的动画
gsap.to
有很多属性,如下:
x: 100 // transform: translateX(100px)
y: 100 // transform: translateY(100px)
z: 100 // transform: translateZ(100px)
scale: 2 // transform: scale(2)
scaleX: 2 // transform: scaleX(2)
scaleY: 2 // transform: scaleY(2)
scaleZ: 2 // transform: scaleZ(2)
skew: 15 // transform: skew(15deg)
skewX: 15 // transform: skewX(15deg)
skewY: 15 // transform: skewY(15deg)
rotation: 180 // transform: rotate(180deg)
rotationX: 180 // transform: rotateX(180deg)
rotationY: 180 // transform: rotateY(180deg)
rotationZ: 180 // transform: rotateZ(180deg)
perspective: 1000 // transform: perspective(1000px)
transformOrigin: '50% 50%' // transform-origin: 50% 50%
上面的属性只要你是前端看着应该都很熟悉CSS transform
,所以还是比较容易上手的,是吧。
上面例子用到的.to()
这样的方法叫补间,类似的还有3个:
-
gsap.to():这是最常见的补间类型。 .to()补间将从元素的当前状态开始 “到” 补间中定义的值。
-
gsap.from():和 .to() 正好相反,.from()补间中定义的值为动画开始的状态。
-
gsap.fromTo():定义了起始值和结束值。
-
gsap.set():立即设置属性(无动画)。
时间轴线
gsap.timeline()
是 GSAP
提供的另一个神器,拥有操纵时间轴线的能力,会让动画有序进行,在我们需要控制一组动画的时候非常有用。尤其是复杂动画都会用到timeline
。ok,我们接着看例子:
控制动画的暂停、开始、回放
接着上面的例子,把动画的状态控制加上:
最后,我们来实现一个文字动画特效:
GSAP
的简单使用介绍就到这里,它的功能远不止这些。还有一些强大的插件,能写出更复杂、更有意思的动画效果。等你去尝试。
GSAP Tools
GreenSock Animation Platform
提供了一些优秀的助手/调试工具,有助于我们在开发动画时候进行调试。这些工具有一些需要加入 Club GreenSock
才能使用
canvas
和 svg
基础入门就学到这,下一篇我将和你一起入门ECharts
,敬请期待~
💕看完三件事:
- 点赞 | 你可以
点击——>收藏——>退出
一气呵成,但别忘了点赞🤭 - 关注 | 点个关注,下次不迷路😘
- 也可以到GitHub拿我所有文章源文件🤗
参考: