Skip to content

S07-01 数据可视化-CSS3动画

[TOC]

概述

概念

数据可视化(英语:Data visualization),主要旨在借助于图形化手段,清晰有效地传达与沟通信息。

  • 为了清晰有效地传递信息,数据可视化通常使用柱状图折线图饼图玫瑰图散点图等图形来传递信息。

  • 也可以使用线地图来对数字数据进行编码展示,以便在视觉上快速传达关键信息。

  • 可视化可以帮助用户分析和推理数据,让复杂的数据更容易理解和使用,有利于做出决策。

image-20240819162526738

image-20240819162532436

发展史

萌芽阶段

17 世纪以前

  • 早在 17 世纪以前,可视化就开始萌芽了,其中最早的地图在公元前 6200 年于土耳其地区出现。

    image-20240819162544271

  • 现代考古发现我国最早的地图实物,是出土于甘肃天水放马滩战国墓地一号墓中的《放马滩地图》

    image-20240819162550102

17-19 世纪

  • 17 世纪末随着几何兴起、坐标系、以及人口统计学开端,人类开始了可视化思考的新模式,从此标记可视化的开端。

    image-20241029113515612

  • 1800-1849 年:随着工艺设计的完善,统计图形爆炸性增长,包括柱状图, 饼图, 直方图, 折线图等。

  • 1826 年,查尔斯·杜品发明了使用连续黑白底纹来显示法国识字分布,这可能是第一张现代形式主题统计地图。

    image-20241029113609045

黄金阶段

19 世纪中

  • 1850-1899:人们开始认识到数字信息对社会计划,工业化,商业和运输的重要性,此时统计理论开始诞生。

  • 1869 年查尔斯·约瑟夫·米纳德,发布的拿破仑对 1812 年俄罗斯东征事件流图,被誉为有史以来最好的数据可视化。

    他的流图呈现了拿破仑军队的位置和行军方向、军队汇集、分散和重聚的时间和地点等信息。

    image-20240819162611154

  • 1879 年 Luigi Perozzo 绘制立体图(三维人口金字塔)。标记着可视化开始进入了三维立体图

    image-20240819162618161

重生阶段

20 世纪

  • 1950-1974 年:引领这次大潮的,首先是一个划时代的事件——计算机的诞生

    计算机的出现彻底地改变了数据分析工作,计算机高分辨率和交互式的图形分析,提供了手绘时代无法实现的表现能力。

    随着统计应用的发展,数理统计把数据可视化变成了一门科学(如:计算机图形学统计学分析学),并运用到各行各业。

  • 1969 年 John W. Tukey 在探索数据分析的图形时,发明箱型图

    image-20241029114006140

  • 1982 年乔治·罗里克(George Rorick)绘制彩色天气图开创了报纸上的彩色信息图形时代。

    image-20241029114024962

  • 1996 年 Jason Dykes 发明了制图工具:一种地图可视化工具包,可以实时查看数据的图形工具。

    image-20241029114035587

分析学阶段

2004 年至今

  • 以前可视化难以应对海量、高维、多源的动态数据的分析,进入 21 世纪,随着计算机的升级,对于以前难以应对数据,可以借用计算机来综合可视化、图形学、数据挖掘理论与方法来研究新的科学理论模型。通过这种模型来辅助用户从海量、复杂、矛盾的数据中快速挖掘出有用的数据,做出有效决策,这门新兴学科称为可视化分析学

    image-20240819162823305

  • 可视化分析现在已大量应用在地图、物流、电力、水利、环保、交通、医学、监控、预警等领域。可视化分析降低了数据理解的难度,突破了常规统计分析的局限性。如下交通拥挤分析图。随着大数据的应用,如今可视化开发也变得越来越重要了。

    多维度展示交通拥堵数据

    image-20240819162817392

应用

随着近几年大数据的快速发展,数据可视化技术也迅速被普及。目前数据可视化的应用非常广:

  • 淘宝双十一活动时,借助于数据可视化展示公司实时交易数额,并可以实时动态观察。

    image-20240819162835716

  • 交管部门可实现对交通形态、卡口数据统计、违章分析、警力部署、出警分析、行车轨迹分析等智能交通大数据分析。

    image-20240819162840186

  • 企业各层可以借助数据可视化工具,可以直接在手机等设备上远程查看企业运营数据状况和关键指标。

  • 医院可以利用数据可视化工具,对医疗卫生数据进行可视化分析和研究应用,进而获取医疗卫生数据隐藏的价值。

    image-20240819162846272

  • 其他应用

    image-20241029114707573

解决方案

前端可视化技术

  • 底层图形引擎: Skia 、OpenGL 等。

  • W3C 提供CSS3CanvasSVG、WebGL。

  • 第三方的可视化库: ZRender、Echarts、 AntV 、Highcharts、D3.js 、Three.js 和 百度地图、高德地图等等。

  • 低代码可视化平台:阿里云(DataV)、腾讯云图、网易有数(EasyScreen)、帆软等。

image-20240819162921803

image-20240819162929746

低代码平台-阿里云 DataV(付费)

官网:https://datav.aliyun.com/portal

image-20240819162945177

2D 动画

transform

transform<transform-function>:用于对元素进行变换的属性,可以应用于 2D 和 3D 变换。可以平移、旋转、缩放和倾斜。

  • transform-function-2D

  • translate()(x,y):平移元素。

    css
    transform: translate(50px, 100px);
  • scale()(x,y):缩放元素,xy 分别表示水平方向和垂直方向的缩放因子。

    css
    transform: scale(1.5, 2);
  • rotate()(angle):旋转元素,角度可以是正值(顺时针)或负值(逆时针)。

    css
    transform: rotate(45deg);
  • skew()(x,y):倾斜元素,x 是水平方向的倾斜角度,y 是垂直方向的倾斜角度。

    css
    transform: skew(20deg, 10deg);
  • perspective()(d):用于创建 3D 效果的属性,它定义了观察者与 Z=0 平面之间的距离。用于启用 3D 变换。

    css
    .container {
      perspective: 1000px; /* 设置透视距离 */
    }
    
    .box {
      transform: rotateY(45deg); /* 应用 3D 旋转 */
    }

坐标系

CSS3 transform 属性允许你在二维或三维空间中直观地变换元素。

  • transform 属性会转换元素的坐标系,使元素在空间中转换。

  • 用 transform 属性变换的元素会受 transform-origin 属性值的影响,该属性用于指定形变的原点

▸ 元素的坐标系:

CSS 中的每个元素都有一个坐标系,其原点位于元素的左上角,左上角这被称为初始坐标系

image-20240819163014903

用 transform 时,坐标系的原点默认会移动到元素的中心。因为 transform-origin 属性的默认值为 50% 50%,即该原点将会作为变换元素的中心点。

image-20240819163024541

用 transform 属性旋转或倾斜元素,会变换或倾斜元素的坐标系。并且该元素所有后续变换都将基于新坐标系的变换。因此,transform 属性中变换函数的顺序非常重要——不同的顺序会导致不同的变换结果。

例如:

  • 如果将一个元素绕 y 轴旋转 90 度:那么它的 x 轴将指向屏幕内部,即远离你。

  • 此时如再沿着 x 轴平移:元素不会向右移动,它会向内远离我们。

  • 因此,要注意编写转换函数的顺序,其中 transform 属性中的第一个函数将首先应用,最后一个函数将最后应用。

【TODO:实现该功能】


▸ 示例: 变换函数的顺序不同会导致不同的变换结果

css
.box {
  transform: translateX(100px) rotate(45deg);
}

image-20241029131057025

css
.box {
  transform: rotate(45deg) translateX(100px);
}

image-20241029131404558

transform-origin

transform-originx y? z?,用于定义一个元素进行变换时的原点。只能在配合 transform 属性使用时生效。

  • xlength | percentage | keyword默认:50%,水平位置

  • y?length | percentage | keyword默认:50%,垂直位置

  • z?length默认:0,表示在 3D 变换中的深度位置

    css
    .box {
      transform-origin: 100px 50% 0; /* 水平100px,垂直50%的位置,Z轴0 */
      transform: rotate(30deg) scale(1.2); /* 旋转30度并放大1.2倍 */
    }

▸ 单位:

  • keyword: left, center, right, top, bottom 关键字

  • length:从左上角开始计算,单位 px

  • percentage:参考元素本身大小的百分比,单位%


▸ 示例: 修改坐标系的原点

css
.box {
  transform-origin: left;
  transform: rotate(45deg);
}

image-20241029132529469

3D 动画

transform

transform<transform-function>:用于对元素进行变换的属性,可以应用于 2D 和 3D 变换。可以平移、旋转、缩放和倾斜。

  • transform-function-3D

  • translate3d()(x,y,z):在二、三维平面上平移元素。

    • 分拆函数:translateX(x),translateY(y),translateZ(z)

    • xpx | %,移动向量的x坐标。

    • ypx | %,移动向量的y坐标。

    • zpx,移动向量的z坐标。它不能是<percentage>值;那样的移动是没有意义的。

    • 注意: 百分比单位参照元素本身。

    • css
      transform: translate3d(100px, 200px, 0);
      
      transform: perspective(300px) translate3d(0, 0, 100px);
  • scale3d()(x,y,z):缩放元素,xyz 分别表示水平方向、垂直方向和Z轴方向的缩放因子。

    • 分拆函数:scaleX(x),scaleY(y),scaleZ(z)

    • xnumber,缩放向量的横坐标。

    • ynumber,缩放向量的纵坐标。

    • znumber缩放向量的 z 分量的 a(再讲到 3D 正方体再演示)。

    • scss
      transform: scale3d(2, 1, 1); // 等价于 transform: scaleX(2);
      transform: scale3d(1, 2, 1); // 等价于 transform: scaley(2);
      transform: scale3d(1, 1, 2); // 等价于 transform: scaleZ(2);
  • rotate3d()(x?,y?,z?,angle):旋转元素,角度可以是正值(顺时针)或负值(逆时针)。

    • 分拆函数:rotateX(x),rotateY(y),rotateZ(z)
    • x?number,可以是 0 到 1 之间的数值,表示旋转轴 X 坐标方向的矢量( 用来计算形变矩阵中的值 )。
    • y?number,可以是 0 到 1 之间的数值,表示旋转轴 Y 坐标方向的矢量。
    • z?number,可以是 0 到 1 之间的数值,表示旋转轴 Z 坐标方向的矢量。
    • angledeg,表示旋转角度。正的角度值表示顺时针旋转,负值表示逆时针旋转。
    • css
      /* 一个值:表示 z 轴 旋转的角度 */
      transform: rotate3d(45deg);
      
      /* 四个值:表示在3D空间之中,旋转有x,y,z个旋转轴和一个旋转角度。 */
      transform: rotate3d(0, 0, 1, 45deg);
  • perspective()(d):通过定义观察者与Z=0平面之间的距离,在 3D 空间中设置一个元素的透视效果。作为transform样式的函数使用

    • dpx | em | rem | none,一个长度值,定义了观察者与 z = 0 平面的距离。常见的值有:

      • 100px:较强的透视效果,深度感显著。
      • 500px适中的透视效果
      • 1000px 或更大:较弱的透视效果,深度感较轻微。
      • none:没有应用 perspective 样式时的默认值。
      • 0px | 负值:无透视效果。
    • 注意:

      • perspective样式是设置在父元素上的,只有其子元素在进行 3D 变换时,才能看到透视效果。

      • 当前元素上使用perspective()函数

    • html
      <style>
      .box {
        transform: perspective(200px) rotateY(45deg); /* 使用透视函数,应用3D旋转 */
      }
      </style>
      <body>
          <box class="box"></box>
      </body>

注意: 3D 形变函数会创建一个合成层来启用 GPU 硬件加速,提高渲染速度。如: xxx3d()、 xxxZ()函数

旋转 rotate3d()

  • rotate3d()(x?,y?,z?,angle):旋转元素,角度可以是正值(顺时针)或负值(逆时针)。

    • 分拆函数:rotateX(x),rotateY(y),rotateZ(z)

    • x?number,可以是 0 到 1 之间的数值,表示旋转轴 X 坐标方向的矢量( 用来计算形变矩阵中的值 )。

    • y?number,可以是 0 到 1 之间的数值,表示旋转轴 Y 坐标方向的矢量。

    • z?number,可以是 0 到 1 之间的数值,表示旋转轴 Z 坐标方向的矢量。

    • angledeg,表示旋转角度。正的角度值表示顺时针旋转,负值表示逆时针旋转。

    • css
      /* 一个值:表示 z 轴 旋转的角度 */
      transform: rotate3d(45deg);
      
      /* 四个值:表示在3D空间之中,旋转有x,y,z个旋转轴和一个旋转角度。 */
      transform: rotate3d(0, 0, 1, 45deg);

      image-20241030162601362


rotate3d 函数定义一个变换,它将元素围绕固定轴旋转。旋转量由指定的角度定义; 为正,运动将为顺时针,为负,则为逆时针。

注意: 旋转的原点受 transform-origin 影响

示例:

▸ 示例: 在X轴旋转45度的基础上再沿Y轴旋转45度

注意: :hover中必须写成transform: rotateX(45deg) rotateY(45deg);,不能写成transform: rotateY(45deg);

html
<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>

20241030173810

rotateXYZ 对比 rotate3d:

旋转函数,最终会生成一个 4*4 的矩阵

image-20240819163110891

image-20240819163117676

透视 perspective()

  • perspectived:通过定义观察者与Z=0平面之间的距离,在 3D 空间中设置一个元素的透视效果。作为单独的样式使用

  • perspective()(d):通过定义观察者与Z=0平面之间的距离,在 3D 空间中设置一个元素的透视效果。作为transform样式的函数使用

    • dpx | em | rem | none,一个长度值,定义了观察者与 z = 0 平面的距离。常见的值有:

      • 100px:较强的透视效果,深度感显著。
      • 500px适中的透视效果
      • 1000px 或更大:较弱的透视效果,深度感较轻微。
      • none:没有应用 perspective 样式时的默认值。
      • 0px | 负值:无透视效果。
    • 注意:

      • perspective样式是设置在父元素上的,只有其子元素在进行 3D 变换时,才能看到透视效果。

      • 当前元素上使用perspective()函数

    • html
      <style>
      .box {
        transform: perspective(200px) rotateY(45deg); /* 使用透视函数,应用3D旋转 */
      }
      </style>
      <body>
          <box class="box"></box>
      </body>

perspective定了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果(z 表示 Z 轴)。

z>0 的三维元素比正常的大,而 z<0 时则比正常的小,大小程度由该属性的值决定。

image-20240819163147157

使用方式:

  • 方式一:在父元素上使用perspective属性

  • 方式二:在当前元素上使用perspective()函数

透视演练场:

用法:

▸ 方式一:在父元素上使用perspective属性

html
<style>
.container {
  perspective: 200px; /* 设置透视距离 */
}

.box {
  transform: rotateY(45deg); /* 应用3D旋转 */
}
</style>
<body>
    <div class="container">
        <box class="box"></box>
    </div>
</body>

▸ 方式二:在当前元素上使用perspective()函数

html
<style>
.box {
  transform: perspective(200px) rotateY(45deg); /* 使用透视函数,应用3D旋转 */
}
</style>
<body>
    <box class="box"></box>
</body>

位移 translate3d()

  • translate3d()(x,y,z):在二、三维平面上平移元素。

    • 分拆函数:translateX(x),translateY(y),translateZ(z)

    • xpx | %,移动向量的x坐标。

    • ypx | %,移动向量的y坐标。

    • zpx,移动向量的z坐标。它不能是<percentage>值;那样的移动是没有意义的。

    • 注意: 百分比单位参照元素本身。

    • css
      transform: translate3d(100px, 200px, 0);
      
      transform: perspective(300px) translate3d(0, 0, 100px);

      image-20241031091919599


translate3d该 CSS 函数在 3D 空间内移动一个元素的位置。这个移动由一个三维向量来表达,分别表示他在三个方向上移动的距离。

缩放 scale3d()

  • scale3d()(x,y,z):缩放元素,xyz 分别表示水平方向、垂直方向和Z轴方向的缩放因子。

    • 分拆函数:scaleX(x),scaleY(y),scaleZ(z)

    • xnumber,缩放向量的横坐标。

    • ynumber,缩放向量的纵坐标。

    • znumber缩放向量的 z 分量的 a(再讲到 3D 正方体再演示)。

    • scss
      transform: scale3d(2, 1, 1); // 等价于 transform: scaleX(2);
      transform: scale3d(1, 2, 1); // 等价于 transform: scaley(2);
      transform: scale3d(1, 1, 2); // 等价于 transform: scaleZ(2);

scale3d该 CSS 函数定义了在 3D 空间中调整元素的缩放比例因子 。

transform-style 空间

transform-styleflat | preserve-3d,指定子元素如何在 3D 空间中呈现。主要与 transform 属性配合使用。

  • flat默认,元素的子元素位于元素本身的平面内。

  • preserve-3d:元素的子元素位于 3D 空间中。

  • 注意: 该样式需要设置在父元素上。

  • css
    .container {
        perspective: 1000px; /* 为子元素设置透视 */
        transform-style: preserve-3d; /* 允许子元素保持 3D 变换 */
    }
    
    .box {
        transform: rotateY(45deg) translateZ(50px); /* 在Y轴旋转,并向Z轴前移 */
    }

transform-style:该 CSS 属性用于设置元素的子元素是定位在 3D 空间中还是平展在元素的 2D 平面中。在 3D 空间中同样是可以使用透视效果。

应用:

▸ 基本使用:创建3D空间

html
<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>

image-20241031101132864


▸ 案例:制作正方体

需求:制作一个正方体

  • 绘制正方体的侧面图

  • 绘制正方体的个六面

image-20241031110607963

image-20241031110523536

image-20240819163237713

backface-visibility 背面可见性

backface-visibilityvisible | hidden,指定某个元素当背面朝向观察者时是否可见。常与 transform 属性结合使用。

  • visible默认,元素的背面在 3D 变换时是可见的。

  • hidden:元素的背面在 3D 变换时是不可见的。

  • css
    backface-visibility: visible;
    
    backface-visibility: hidden;

backface-visibility:该 CSS 属性指定某个元素当背面朝向观察者时是否可见

image-20241031111338405


示例:

html
<style>
    .front {
        transition: transform 5s linear; /* 设置过渡效果 */
        backface-visibility: hidden; /* 隐藏背面 */
    }
    .front:hover {
        transform: perspective(500px) rotateY(180deg); /* 翻转效果 */
    }
</style>

<body>
	<div class="front">正面</div>
</body>

需求:制作一个 webpack logo

  • 绘制小正方体的侧面图

  • 绘制小正方体的六个面

  • 绘制大正方体的侧面图

  • 绘制大正方体的六个面

  • 添加旋转动画

案例:2.5D动画-数据平台可视化

动画实现

image-20241031134143210

image-20241031134541721

image-20241031135304140

image-20241031140000468

image-20241031141848666

image-20241031142541308

image-20241031142849620

image-20241031143131367

动画性能优化

浏览器渲染流程

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 性能优化策略和过度使用。

image-20241031144901366

动画性能优化▸

优化一:创建新渲染层,可以减少回流

可以通过以下方法创建渲染层

  • 有明确的定位属性:relativefixedstickyabsolute

  • 透明度:opacity小于1

  • transform属性:不为 none

  • 当前有对 opacitytransformfliterbackdrop-filter 应用动画

  • backface-visibility 属性为 hidden

  • ...

优化二:创建合成层

合成层会开始 GPU 加速页面渲染,但不能滥用。可以通过以下方法创建合成层

  • 在animation或transition动画进行中应用了opacitytransformfliterbackdropfilter属性。

  • 使用了transform的3D函数translate3dtranslateZscale3dscaleZrotate3drotateZ

  • 使用will-change属性告知浏览器提前做好优化准备:设置 opacity、transform、top、left、bottom、right,比如:will-change: opacity , transform;

    • 其中 top、left 等需要设置明确的定位属性,如 relative 等

注意:

  • 尽量少用fliterbackdrop-filter,会大量消耗性能。
  • 尽量少用will-change,会让浏览器常时间处于优化状态,消耗性能。

image-20240819163416185