svg和canvas都是我们平时常用的html5图形开发技术。一般情况下常见的图形和图表使用它们来完成都没有太大的问题。但是两者在使用场景上还有一些差别。

Canvas VS SVG

  • canvas是基于位图的。
    • 适合动态渲染和对象数据量大的绘制。
    • 但是canvas只能采用js驱动,不提供图形元素的标签,只有一个<canvas>标签,像圆呀,矩形呀等等基本图形都得使用js来实现。
    • 再者,与用户交互的单位是像素点。并且绘制完成后,不能进行修改,只能擦除画布后重新绘制。
  • svg是矢量图形,基于图形元素。
    • 除了<svg>标签之外,还提供<circle>,<path>等元素。更适合静态图形,对象数据量小,面积大的动画。
    • 可以修改svg中的dom,更容易编辑。所以,更适合做动态交互。
    • 同时,某些场景下,我们可以缓存svg中的dom结构,会比canvas的重绘减少工作量。

怎么让趋势线动起来

这里默认我们已经有了一定的svg基础,就是知道如何绘制基本图形。让趋势线动起来,方法大致可以有3种,demo,分别有各自的优缺点。

首先第一种,是利用stroke-dasharray和stroke-dashoffset + css3的animation

  • stroke-dasharray: x, y
    线长x-空隙长y-线长x-…..
    x = y时:stcok-dasharray: x, y的效果与stock-dasharray: x的相同

  • stroke-dashoffset: x
    决定stock-dasharray从x处开始。蓝色的是stock-dash的线,dashoffset决定了整条线向左移动多远

这三条线中stroke-dasharray: 10,stroke-dashoffset分别为0, 5, 10

这样呢,我们就可以现将趋势图path的stroke-dasharray,stroke-dashoffset都设置的非常大,然后最终stroke-dashoffset减少到0,这样趋势图就会有逐渐出现的效果。关键代码如下:

1
2
3
4
5
6
7
8
9
10
11
.chart path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 1.5s linear forwards;
}
@keyframes dash {
to {
stroke-dashoffset: 10;
}
}

还有2行可能会用到的代码:

1
2
var path = document.querySelector('path'); // 准确路径
var length = path.getTotalLength(); //线条长度

这种方式不仅可以针对规则图形来做动画,也可以针对任意不规则的图形。
不过若图形是一个组合图形,想要有逐渐出现的效果就稍微麻烦些,需要对变化项不是stroke的元素,单独设置动画,比如demo中几个拐点的圆圈。
兼容性: IE10-不支持, 主要是animation中不支持stroke相关属性的动画

第二种方法是,利用js来动态改变趋势图容器的宽度

这种方法就可以较好的解决组合图形的问题;同时兼容性也比较好。主要是利用定时器来逐渐增大容器的宽度。关键代码如下:

1
2
3
4
5
6
7
8
var width = 0;
var st = setInterval(function(){
if( width > 900){
clearInterval( st );
}
$('.chart1').css('width', width);
width += 5;
}, .1);

第三种方法是,利用animateTransform标签
虽然有进入的效果,但是确是将整个path作为一个整体进行移入的,没有逐渐显示的效果;同时,IE下不支持svg的<animate>标签。
这里提到这种方法,主要是想说明svg也可以利用标签完成css3中的animation动画效果。

##参考的文章