简介

2.1.x 版本后,G2 有了简单的自定义动画的方法,发展到现在的 2.3.x 版本,我们给自定义动画设计了一套更加完善的体系和接口,让用户能更系统、更全面的控制 G2 的动画。

动画注册 Animate.registAnimation()

  var Animate = G2.Animate;

  Animate.registAnimation(animationType, animationName, animationFun);

动画配置 Geom.animate()

 chart.interval().position('x*y').animate({
    enter: {
      animation: 'myAnimation',
    }
  });

上述方法更详细的使用说明详见: G2 Animate API

1分钟上手自定义动画

以柱状图为例:

第一步:获取 Animate 对象

  var Animate = G2.Animate;

第二步:自定义动画(核心)

  • 首先获取每根柱子的包围盒。包围盒的意思是能包围图形的最小矩形,所以包围盒含有 minX、minY、maxX、maxY 四个属性,这四个参数限定的区间即为图形的包围盒。
  • 计算变换中点。当顶点在零点之上时,延 Y 轴正向放大,所以变换的中点在包围盒底部中间;当顶点在零点之下时,延 Y 轴反向放大。所以变换的中点在包围盒顶部中间;
  • 设置动画初始状态。要实现柱子的放大,需要先将柱子缩到最小。调用 shape 的 transform() 方法,先将坐标系的原点移到变换中点,然后将柱子的 y 值缩小到 0.1 倍,最后将坐标系的原点移到原处。
  • 实现延迟放大效果的动画。调用 shape 的 animate() 方法,传入变换的结束状态、动画时间和缓动函数。结束状态中可以配置延迟参数 delay ,给每个 shape 的动画添加一个跟序号成正比的延迟,即可实现依次放大的效果。
  // shape 是柱子对象,animateCfg 是动画配置
  var animateFun = function(shape, animateCfg) {
    var box = shape.getBBox(); // 获取柱子包围盒
    var origin = shape.get('origin'); // 获取柱子原始数据
    var points = origin.points; // 获取柱子顶点
    var i = origin.index; // 获取柱子序列号

    // 计算柱子的变换中点
    var centerX  = (box.minX + box.maxX) / 2; 
    var centerY;
    if (points[0].y - points[1].y <= 0) { // 当顶点在零点之下
      centerY = box.maxY;
    } else {
      centerY = box.minY;
    }

    // 设置初始态
    shape.transform([
      ['t', -centerX, -centerY],
      ['s', 1, 0.1],
      ['t', centerX, centerY]
    ]);

    // 设置动画目标态
    shape.animate({
      transform: [
        ['t', -centerX, -centerY],
        ['s', 1, 10],
        ['t', centerX, centerY]
      ],
      delay: animateCfg.delay // 延迟参数
    }, animateCfg.duartion, animateCfg.easing);
  };

第三步:注册动画

  Animate.registAnimation('appear', 'delayScaleInY', animationFun);

第四步:绘制柱状图,配置动画参数

  var data = [];
  for (var i = 0; i < 50; i++) {
    data.push({
      x: i,
      y: (Math.sin(i / 5) * (i / 5 -10) + i / 6) * 5
    });
  }
  var chart = new G2.Chart({
    id: 'c1',
    width: 800,
    height: 500
  });
  chart.axis('x', false);
  chart.legend(false);
  chart.source(data);
  chart.interval()
       .position('x*y')
       .color('y', '#4a657a-#308e92-#b1cfa5-#f5d69f-#f5898b-#ef5055')
       .animate({
        appear:{
          animation: 'delayScaleInY',
          easing: 'easeOutElastic',
          delay:function(index){
            return index * 20;
          }
        }
       });
  chart.render();