[TOC]

自定义动画

动画注册机制

使用动画注册机制以达到动画函数的复用。使用方式如下:

  1. // 加载动画注册类
    2. const Animate = require('@antv/f2/lib/animation/animate');
    3. /**
    4.  * @param  {String} animationName   动画名称,用户自定义即可
    5.  * @param  {Function} animationFun  动画执行函数
    6.  **/
    7. Animate.registerAnimation('animationName', animationFun); // 注册名为 animationName 的动画函数
    8.  
    9.  
    10. // 使用上述注册的函数
    11. chart.line().animate({
    12.   appear: {
    13.     animation: 'animationName'  // 对应上述注册的动画函数名
    14.   }
    15. })

自定义动画详解

F2 提供了完善的动画自定义机制,用户可对任意支持动画的图形元素定制不同状态下的动画行为,这里所说的状态即为 appear enter leave update 这四种动画类型。 在 F2 中执行的都是 Shape(图形) 元素的动画,通过逐帧改变 shape 对象的图形属性来达到动画的效果,以下面圆的移动动画为例:
自定义 Animate - 图1
这个动画的实现非常简单,由于动画的最终效果是将圆移至 B 点(画布坐标为 { x: 230, y: 50 }),那么我们只需要通过调用 shape.animate() 方法指定 shape 的最终状态(图形属性)即可:

  1. // circle 初始画布位置为 x: 100, y: 100
    2. circle.animate().to({
    3.   attrs: {
    4.     x: 230, // 最终的 x 坐标
    5.     y: 50   // 最终的 y 坐标
    6.   }, // 指定最终的图形属性
    7.   easing: 'linear', // 指定动画的缓动效果
    8.   duration: 1500 // 指定动画的执行时间
    9. })
    10.  

各类型 shape 的图形属性说明见 graphic 图形 api。 F2 会为用户自定义的动画函数传递三个参数,按照顺序,分别为 shape、animateCfg、coord

  1. chart.line().animate({
    2.   appear: {
    3.     animation: (shape, animateCfg, coord) => {}
    4.   }
    5. })
  • shape,shape 对象,当前执行动画的主体
    通过操作该 shape 对象的图形属性,即可进行动画的个性化定制。

shape 对象具体提供了以下属性来帮助用户进行操作: 属性名 | 获取方式 | 类型 | 解释
—-|—-|—-|—-
attrs | shape.get(‘attrs’) | Object | 获取 shape 全部的图形属性
className | shape.get(‘className’) | String | 获取当前 shape 的图形元素类型
origin | shape.get(‘origin’) | Object | 获取当前 shape 的绘制数据以及对应的原始数据记录
index | shape.get(‘index’) | Number | 获取当前 shape 的索引值,即顺序
另外图形属性的获取还可以通过调用 shape.attr(name) 方法来获取,更多 shape 对象的方法请阅读 Shape API。 另外对于处理 update 更新状态下的 shape 对象,我们还会提供一个 cacheShape 属性,该属性为一个 Object 对象,存储的是当前 shape 在上一个状态(数据变更前)的内容,以便于用户进行变更动画的定制,该属性包含的内容如下:

  1. {
    2.   animateCfg: {}, // 动画效果配置
    3.   attrs: {}, // 上一个状态的图形属性
    4.   className: "", // 图形元素名称
    5. }
  • animateCfg,Object 类型,动画的配置
    该对象包含的内容如下:

    1. {
      1. easing: , // 缓动函数配合
      2. duration: , // 动画执行时间
      3. delay: // 动画延迟时间
      4. }
  • coord,Coord 坐标系对象,表示当前 chart 的坐标系,该对象包含的属性详见 Coordinate API

示例

下面的示例对柱状图的初始化出场动画(appear)进行了自定义: column1.gif

  1.   const { Chart, Animate, Util, G } = F2;
    2.   // 注册函数名为 delayScaleInY 的自定义动画,实现柱子 y 轴方向的放大效果
    3.   Animate.registerAnimation('delayScaleInY', function(shape, animateCfg) {
    4.     const box = shape.getBBox(); // 获取图形的包围盒
    5.     const origin = shape.get('origin'); // 获取当前 shape 的绘制数据
    6.     const points = origin.points; // 获取柱子的各个顶点
    7.     const centerX = (box.minX + box.maxX) / 2;
    8.     let centerY;
    9.     if (points[0].y - points[1].y <= 0) { // 当顶点在零点之下
    10.       centerY = box.maxY;
    11.     } else {
    12.       centerY = box.minY;
    13.     }
    14.  
    15.     shape.transform([
    16.       [ 't', centerX, centerY ],
    17.       [ 's', 1, 0.1 ],
    18.       [ 't', -centerX, -centerY ]
    19.     ]); // 进行矩阵变换,将 shape 的原始状态改变,y 方向缩小至 0.1 倍
    20.     const index = shape.get('index');
    21.     let delay = animateCfg.delay; // 获取动画配置
    22.     if (Util.isFunction(delay)) {
    23.       delay = animateCfg.delay(index); // 根据 shape 的索引设置不同的延迟时间
    24.     }
    25.     const easing = animateCfg.easing; // 获取动画配置
    26.  
    27.     const matrix = shape.getMatrix(); // 获取当前矩阵
    28.     const endMatrix = G.Matrix.transform(matrix, [
    29.       [ 't', centerX, centerY ],
    30.       [ 's', 1, 10 ],
    31.       [ 't', -centerX, -centerY ]
    32.     ]); // shape 最终状态下的矩阵
    33.  
    34.     shape.animate().to({
    35.       attrs: {
    36.         matrix: endMatrix
    37.       },
    38.       delay,
    39.       easing,
    40.       duration: animateCfg.duration
    41.     }); // 执行动画
    42.   });
    43.  
    44.   const data = [];
    45.   for (let i = 0; i < 50; i++) {
    46.     data.push({
    47.       x: i,
    48.       y: (Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5
    49.     });
    50.   }
    51.   const chart = new Chart({
    52.     id: 'mountNode',
    53.     width: 375,
    54.     height: 200,
    55.     pixelRatio: window.devicePixelRatio
    56.   });
    57.   chart.axis('x', false);
    58.   chart.legend(false);
    59.   chart.source(data);
    60.   chart.interval()
    61.     .position('x*y')
    62.     .color('y', '#4a657a-#308e92-#b1cfa5-#f5d69f-#f5898b-#ef5055')
    63.     .animate({ // 进行自定义的动画配置
    64.       appear: {
    65.         animation: 'delayScaleInY', // 使用上面注册过的动画 delayScaleInY,当然也可以使用回调函数
    66.         easing: 'elasticOut', // 定义缓动函数
    67.         delay(index) {
    68.           return index * 10;
    69.         } // 根据索引值为各个 shape 设置不同的动画延迟执行时间
    70.       }
    71.     });
    72.   chart.render();

原文: https://antv.alipay.com/zh-cn/f2/3.x/api/custom-animate.html