S07-01 数据可视化-CSS3动画
[TOC]
API-CSS3
形变
- transform:
<transform-function>
:用于对元素进行变换的属性,可以应用于 2D 和 3D 变换。可以平移、旋转、缩放和倾斜。 - transform-origin:
x y? z?
,用于定义一个元素进行变换时的原点。只能在配合transform
属性使用时生效。 - transform-style:
flat | preserve-3d
,指定子元素如何在 3D 空间中呈现。主要与transform
属性配合使用。 - backface-visibility:
visible | hidden
,指定某个元素当背面朝向观察者时是否可见。常与transform
属性结合使用。 - perspective:
d
:通过定义观察者与Z=0平面之间的距离,在 3D 空间中设置一个元素的透视效果。设置在父元素上。
动画
- animation:
name duration timing-function? delay? iteration-count? direction? fill-mode? play-state?
,创建动画效果的属性。通过定义多个关键帧(keyframes)来控制元素在一定时间内的状态变化。可以指定动画的持续时间、延迟、播放次数、播放速度等。 - @keyframes animation-name:
{from, to} | {0%, ..., 100%}
,定义动画的关键帧(从一个状态到另一个状态的过渡)的规则。通过from
和to
或者百分比值来定义。
概述
概念
数据可视化(英语:Data visualization),主要旨在借助于图形化手段,清晰有效地传达与沟通信息。
为了清晰有效地传递信息,数据可视化通常使用柱状图、折线图、饼图、玫瑰图、散点图等图形来传递信息。
也可以使用点、线、面、地图来对数字数据进行编码展示,以便在视觉上快速传达关键信息。
可视化可以帮助用户分析和推理数据,让复杂的数据更容易理解和使用,有利于做出决策。
发展史
萌芽阶段
17 世纪以前
早在 17 世纪以前,可视化就开始萌芽了,其中最早的地图在公元前 6200 年于土耳其地区出现。
现代考古发现我国最早的地图实物,是出土于甘肃天水放马滩战国墓地一号墓中的《放马滩地图》
17-19 世纪
17 世纪末随着几何兴起、坐标系、以及人口统计学开端,人类开始了可视化思考的新模式,从此标记可视化的开端。
1800-1849 年:随着工艺设计的完善,统计图形爆炸性增长,包括柱状图, 饼图, 直方图, 折线图等。
1826 年,查尔斯·杜品发明了使用连续黑白底纹来显示法国识字分布,这可能是第一张现代形式主题统计地图。
黄金阶段
19 世纪中
1850-1899:人们开始认识到数字信息对社会计划,工业化,商业和运输的重要性,此时统计理论开始诞生。
1869 年查尔斯·约瑟夫·米纳德,发布的拿破仑对 1812 年俄罗斯东征事件流图,被誉为有史以来最好的数据可视化。
他的流图呈现了拿破仑军队的位置和行军方向、军队汇集、分散和重聚的时间和地点等信息。
1879 年 Luigi Perozzo 绘制立体图(三维人口金字塔)。标记着可视化开始进入了三维立体图。
重生阶段
20 世纪
1950-1974 年:引领这次大潮的,首先是一个划时代的事件——计算机的诞生。
计算机的出现彻底地改变了数据分析工作,计算机高分辨率和交互式的图形分析,提供了手绘时代无法实现的表现能力。
随着统计应用的发展,数理统计把数据可视化变成了一门科学(如:计算机图形学、统计学、分析学),并运用到各行各业。
1969 年 John W. Tukey 在探索数据分析的图形时,发明箱型图。
1982 年乔治·罗里克(George Rorick)绘制彩色天气图开创了报纸上的彩色信息图形时代。
1996 年 Jason Dykes 发明了制图工具:一种地图可视化工具包,可以实时查看数据的图形工具。
分析学阶段
2004 年至今
以前可视化难以应对海量、高维、多源的动态数据的分析,进入 21 世纪,随着计算机的升级,对于以前难以应对数据,可以借用计算机来综合可视化、图形学、数据挖掘理论与方法来研究新的科学理论模型。通过这种模型来辅助用户从海量、复杂、矛盾的数据中快速挖掘出有用的数据,做出有效决策,这门新兴学科称为可视化分析学。
可视化分析现在已大量应用在地图、物流、电力、水利、环保、交通、医学、监控、预警等领域。可视化分析降低了数据理解的难度,突破了常规统计分析的局限性。如下交通拥挤分析图。随着大数据的应用,如今可视化开发也变得越来越重要了。
多维度展示交通拥堵数据
应用
随着近几年大数据的快速发展,数据可视化技术也迅速被普及。目前数据可视化的应用非常广:
如淘宝双十一活动时,借助于数据可视化展示公司实时交易数额,并可以实时动态观察。
交管部门可实现对交通形态、卡口数据统计、违章分析、警力部署、出警分析、行车轨迹分析等智能交通大数据分析。
企业各层可以借助数据可视化工具,可以直接在手机等设备上远程查看企业运营数据状况和关键指标。
医院可以利用数据可视化工具,对医疗卫生数据进行可视化分析和研究应用,进而获取医疗卫生数据隐藏的价值。
其他应用
解决方案
前端可视化技术
底层图形引擎: Skia 、OpenGL 等。
W3C 提供:CSS3、Canvas、SVG、WebGL。
第三方的可视化库: ZRender、Echarts、 AntV 、Highcharts、D3.js 、Three.js 和 百度地图、高德地图等等。
低代码可视化平台:阿里云(DataV)、腾讯云图、网易有数(EasyScreen)、帆软等。
低代码平台-阿里云 DataV(付费)
官网:https://datav.aliyun.com/portal
2D 动画
形变 transform
transform:<transform-function>
:用于对元素进行变换的属性,可以应用于 2D 和 3D 变换。可以平移、旋转、缩放和倾斜。
坐标系
CSS3 transform 属性允许你在二维或三维空间中直观地变换元素。
transform 属性会转换元素的坐标系,使元素在空间中转换。
用 transform 属性变换的元素会受 transform-origin 属性值的影响,该属性用于指定形变的原点。
▸ 元素的坐标系:
CSS 中的每个元素都有一个坐标系,其原点位于元素的左上角,左上角这被称为初始坐标系。
用 transform 时,坐标系的原点默认会移动到元素的中心。因为 transform-origin 属性的默认值为 50% 50%,即该原点将会作为变换元素的中心点。
用 transform 属性旋转或倾斜元素,会变换或倾斜元素的坐标系。并且该元素所有后续变换都将基于新坐标系的变换。因此,transform 属性中变换函数的顺序非常重要——不同的顺序会导致不同的变换结果。
例如:
如果将一个元素绕 y 轴旋转 90 度:那么它的 x 轴将指向屏幕内部,即远离你。
此时如再沿着 x 轴平移:元素不会向右移动,它会向内远离我们。
因此,要注意编写转换函数的顺序,其中 transform 属性中的第一个函数将首先应用,最后一个函数将最后应用。
<div class="container">
<div class="box">BOX</div>
</div>
.box {
transform: perspective(500px) rotate3d(0, 1, 0, 45deg) translateX(50px);
}
▸ 示例: 变换函数的顺序不同会导致不同的变换结果
.box {
transform: translateX(100px) rotate(45deg);
}
.box {
transform: rotate(45deg) translateX(100px);
}
原点 transform-origin
transform-origin:x y? z?
,用于定义一个元素进行变换时的原点。只能在配合 transform
属性使用时生效。
▸ 单位:
keyword
: left, center, right, top, bottom 关键字length
:从左上角开始计算,单位 pxpercentage
:参考元素本身大小的百分比,单位%
▸ 示例: 修改坐标系的原点
.box {
transform-origin: left;
transform: rotate(45deg);
}
3D 动画
形变 transform
旋转 rotate3d()
transform:<transform-function>
:用于对元素进行变换的属性,可以应用于 2D 和 3D 变换。可以平移、旋转、缩放和倾斜。
- rotate3d():
(x?,y?,z?,angle)
:旋转元素,角度可以是正值(顺时针)或负值(逆时针)。
rotate3d() 函数定义一个变换,它将元素围绕固定轴旋转。旋转量由指定的角度定义; 为正,运动将为顺时针,为负,则为逆时针。
注意: 旋转的原点受 transform-origin
影响
▸ 示例: 在X轴旋转45度的基础上再沿Y轴旋转45度
注意: :hover
中必须写成transform: rotateX(45deg) rotateY(45deg);
,不能写成transform: rotateY(45deg);
<style>
.box {
perspective: 200px; /* 设置透视 */
}
.one {
transition: all 1s linear;
transform: rotateX(45deg); /* 初始时沿X旋转了45度 */
}
.one:hover {
transform: rotateX(45deg) rotateY(45deg); /* 在上述基础上,再沿Y轴旋转45度 */
}
</style>
<body>
<div class="box">
<div class="one">2</div>
</div>
</body>
rotateXYZ 对比 rotate3d:
旋转函数,最终会生成一个 4*4 的矩阵
透视 perspective()
perspective:d
:通过定义观察者与Z=0平面之间的距离,在 3D 空间中设置一个元素的透视效果。设置在父元素上。
transform:<transform-function>
:用于对元素进行变换的属性,可以应用于 2D 和 3D 变换。可以平移、旋转、缩放和倾斜。
- perspective():
(d)
:通过定义观察者与Z=0平面之间的距离,在 3D 空间中设置一个元素的透视效果。作为transform样式的函数使用。
perspective定了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果(z 表示 Z 轴)。
z>0 的三维元素比正常的大,而 z<0 时则比正常的小,大小程度由该属性的值决定。
使用方式:
方式一:在父元素上使用perspective属性
方式二:在当前元素上使用perspective()函数
透视演练场:
用法:
▸ 方式一:在父元素上使用perspective属性
<style>
.container {
perspective: 200px; /* 设置透视距离 */
}
.box {
transform: rotateY(45deg); /* 应用3D旋转 */
}
</style>
<body>
<div class="container">
<box class="box"></box>
</div>
</body>
▸ 方式二:在当前元素上使用perspective()函数
<style>
.box {
transform: perspective(200px) rotateY(45deg); /* 使用透视函数,应用3D旋转 */
}
</style>
<body>
<box class="box"></box>
</body>
位移 translate3d()
transform:<transform-function>
:用于对元素进行变换的属性,可以应用于 2D 和 3D 变换。可以平移、旋转、缩放和倾斜。
- translate3d():
(x,y,z)
:在二、三维平面上平移元素。
translate3d该 CSS 函数在 3D 空间内移动一个元素的位置。这个移动由一个三维向量来表达,分别表示他在三个方向上移动的距离。
缩放 scale3d()
transform:<transform-function>
:用于对元素进行变换的属性,可以应用于 2D 和 3D 变换。可以平移、旋转、缩放和倾斜。
- scale3d():
(x,y,z)
:缩放元素,x
、y
和z
分别表示水平方向、垂直方向和Z轴方向的缩放因子。小于1表示缩小,大于1表示放大。
scale3d该 CSS 函数定义了在 3D 空间中调整元素的缩放比例因子 。
空间 transform-style
transform-style:flat | preserve-3d
,指定子元素如何在 3D 空间中呈现。主要与 transform
属性配合使用。
transform-style:该 CSS 属性用于设置元素的子元素是定位在 3D 空间中还是平展在元素的 2D 平面中。在 3D 空间中同样是可以使用透视效果。
▸ 基本使用:创建3D空间
<style>
.container {
transform-style: preserve-3d;
perspective: 500px;
}
.box2 {
transform: rotateX(45deg) translate3d(50px, 0px, 0px);
}
</style>
<body>
<div class="container">
<div class="box box1">被变换的元素</div>
<div class="box box2">被变换的元素</div>
</div>
</body>
背面可见性 backface-visibility
backface-visibility:visible | hidden
,指定某个元素当背面朝向观察者时是否可见。常与 transform
属性结合使用。
基本使用:翻转卡片
<style>
.front {
transition: transform 5s linear; /* 设置过渡效果 */
backface-visibility: hidden; /* 隐藏背面 */
}
.front:hover {
transform: perspective(500px) rotateY(180deg); /* 翻转效果 */
}
</style>
<body>
<div class="front">正面</div>
</body>
案例:正方体
需求:制作一个正方体
绘制正方体的侧面图
绘制正方体的六个面
<div class="box">
<div class="item item1">front</div>
<div class="item item2">back</div>
<div class="item item3">left</div>
<div class="item item4">right</div>
<div class="item item5">top</div>
<div class="item item6">bottom</div>
</div>
:root {
/* 背面是否可见 */
--backface: visible;
/* 透视设置 */
--perspective: -1;
/* z轴是否放大 */
--zoom: 2;
}
.box {
position: relative;
transform: translate(100px, 100px) rotateX(-33.5deg) rotateY(45deg) scaleZ(var(--zoom));
perspective: var(--perspective);
transform-style: preserve-3d;
}
.box .item {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: var(--backface);
}
.box .item1 {
background-color: #ff00ff99;
transform: translateZ(50px);
}
.box .item2 {
background-color: #ffff0099;
transform: rotateX(180deg) translateZ(50px);
}
.box .item3 {
background-color: #00ffff99;
transform: rotateY(-90deg) translateZ(50px);
}
.box .item4 {
background-color: #f7730099;
transform: rotateY(90deg) translateZ(50px);
}
.box .item5 {
background-color: #ffff0099;
transform: rotateX(90deg) translateZ(50px);
}
.box .item6 {
background-color: #4000ff99;
transform: rotateX(-90deg) translateZ(50px);
}
案例:webpack logo
需求:制作一个 webpack logo
绘制小正方体的侧面图
绘制小正方体的六个面
绘制大正方体的侧面图
绘制大正方体的六个面
添加旋转动画
1、HTML结构
<div class="container">
<div class="box box-outer">
<div class="item item1"></div>
<div class="item item2"></div>
<div class="item item3"></div>
<div class="item item4"></div>
<div class="item item5"></div>
<div class="item item6"></div>
</div>
<div class="box box-inner">
<div class="item item1"></div>
<div class="item item2"></div>
<div class="item item3"></div>
<div class="item item4"></div>
<div class="item item5"></div>
<div class="item item6"></div>
</div>
</div>
2、大盒子样式
.container {
background-color: #2e3a41;
}
.box {
position: absolute;
transform: translate(100px, 100px) rotateX(-33.5deg) rotateY(45deg);
perspective: var(--perspective);
transform-style: preserve-3d;
}
.box .item {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: var(--backface);
border: 1px solid #fff;
background-color: #8dd6f980;
}
.box .item1 {
transform: translateZ(50px);
}
.box .item2 {
transform: rotateX(180deg) translateZ(50px);
}
.box .item3 {
transform: rotateY(-90deg) translateZ(50px);
}
.box .item4 {
transform: rotateY(90deg) translateZ(50px);
}
.box .item5 {
transform: rotateX(90deg) translateZ(50px);
}
.box .item6 {
transform: rotateX(-90deg) translateZ(50px);
}
3、小盒子的单独样式
/** 小盒子的单独样式 */
.box-inner {
width: 50px;
height: 50px;
transform: translate(125px, 125px) rotateX(-33.5deg) rotateY(45deg);
}
.box-inner .item {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: var(--backface);
background-color: #6399c4;
border: 1px solid #fff;
}
.box-inner .item1 {
transform: translateZ(25px);
}
.box-inner .item2 {
transform: rotateX(180deg) translateZ(25px);
}
.box-inner .item3 {
transform: rotateY(-90deg) translateZ(25px);
}
.box-inner .item4 {
transform: rotateY(90deg) translateZ(25px);
}
.box-inner .item5 {
transform: rotateX(90deg) translateZ(25px);
}
.box-inner .item6 {
transform: rotateX(-90deg) translateZ(25px);
}
4、动画
/** 动画-大盒子 */
.box-outer {
animation: rotate 4s linear infinite;
}
@keyframes rotate {
0%,
75% {
transform: translate(100px, 100px) rotateX(-33.5deg) rotateY(45deg);
}
100% {
transform: translate(100px, 100px) rotateX(-33.5deg) rotateY(135deg);
}
}
/** 动画-小盒子 */
.box-inner {
animation: rotate-reverse 4s linear infinite;
}
@keyframes rotate-reverse {
0%,
75% {
transform: translate(125px, 125px) rotateX(-33.5deg) rotateY(45deg);
}
100% {
transform: translate(125px, 125px) rotateX(-33.5deg) rotateY(-45deg);
}
}
案例:2.5D动画-数据平台可视化
动画实现
1、HTML结构
<div class="container">
<div class="wrap">
<div class="banner">
<img class="item tuB" src="../assets//images//tuB.png" alt="" />
<img class="item lingxA" src="../assets//images/lingxA.png" alt="" />
<img class="item lingxB" src="../assets//images/lingxB.png" alt="" />
<img class="item lingxD" src="../assets//images/lingxD.png" alt="" />
<img class="item lingxE" src="../assets//images/lingxE.png" alt="" />
<img class="item lingxF" src="../assets//images/lingxF.png" alt="" />
<img class="item tuA" src="../assets//images//tuA.png" alt="" />
<img class="item tuA2" src="../assets//images//tuA.png" alt="" />
<img class="item chaunB" src="../assets//images/chaunB.png" alt="" />
<img class="item chaunB2" src="../assets//images/chaunB.png" alt="" />
<img class="item ziA" src="../assets//images/ziA.png" alt="" />
<img class="item ziB" src="../assets//images/ziB.png" alt="" />
<img class="item ziC" src="../assets//images/ziC.png" alt="" />
<img class="item ren" src="../assets//images/ren.png" alt="" />
<img class="item tuAn" src="../assets//images/tuAn.png" alt="" />
<img class="item tuMing" src="../assets//images/tuMing.png" alt="" />
<img class="item tuC" src="../assets//images/tuC.png" alt="" />
<img class="item guang" src="../assets//images/guang.png" alt="" />
<img class="item guang2" src="../assets//images/guang.png" alt="" />
</div>
</div>
</div>
2、帧动画
动画性能优化
浏览器渲染流程
1、解析 HTML,构建 DOM Tree
2、对 CSS 文件进行解析,解析出对应的规则树
3、DOM Tree + CSSOM 生成 Render Tree
4、布局(Layout):计算出每个节点的宽度、高度和位置信息。
- 页面元素位置、大小发生变化,往往会导致其他节点联动,需要重新计算布局,这个过程称为回流(Reflow)。
5、绘制(Paint):将可见的元素绘制在屏幕中。
默认标准流是在同一层上绘制,一些特殊属性(定位)会创建新的层绘制,这些层称为渲染层。
一些不影响布局的 CSS 修改也会导致该渲染层重绘(Repaint),回流必然会导致重绘。
6、Composite 合成层:一些特殊属性(开启3d的属性)会创建一个新的合成层( CompositingLayer ),并可以利用 GPU 来加速绘制,这是浏览器的一种优化手段。合成层确实可以提高性能,但是它以消耗内存为代价,因此不能滥用作为 web 性能优化策略和过度使用。
动画性能优化@
优化一:创建新渲染层,可以减少回流
可以通过以下方法创建渲染层:
position
: 非staticopacity
: 小于1transform
: 非nonebackface-visibility
: hidden- 当前有对
opacity
、transform
、filter
、backdrop-filter
应用动画
优化二:创建合成层
合成层会开始 GPU 加速页面渲染,但不能滥用。可以通过以下方法创建合成层:
当前有对
opacity
、transform
、filter
、backdrop-filter
应用动画使用了transform的3D函数:
translate3d
、translateZ
、scale3d
、scaleZ
、rotate3d
、rotateZ
使用will-change属性告知浏览器提前做好优化准备:设置 opacity、transform、top、left、bottom、right,比如:will-change: opacity , transform;
- 其中 top、left 等需要设置明确的定位属性,如 relative 等
注意:
- 尽量少用
filter
、backdrop-filter
,会大量消耗性能。 - 尽量少用
will-change
,会让浏览器常时间处于优化状态,消耗性能。