因为项目需要svg做一个连线动画,网上找了很多插件都不是很满意,于是自己写了一个动画.
思想是
画直线
1.能用css实现的尽量不用js,css就能完全实现直线的连线动画
2.获取线的长度
3.设置线的初始小段长度和间隔都为线的长度本身
4.设置线的偏移量为线的长度本身
5.参数和虚线参数意义一样
drawStrightLine:function(obj,duration){
if(arguments.length<2){
return '参数错误';
}
return (function(){
var totalLength = $('#' + obj.id)[0].getTotalLength();
var anmt = 'drawStrightLine '+duration+'s linear 1 ';
$('#' + obj.id).css('strokeDasharray', totalLength+','+totalLength);
$('#' + obj.id).css('strokeDashoffset',totalLength);
$('#' + obj.id).css('animation', anmt);
})()
}
css代码
@keyframes drawStrightLine{
100%{
stroke-dashoffset: 0;
}
}
画虚线
1.先获取到线的长度.
2.计算虚线一个轮回每一段的平均长度
3.计算动画要执行的次数
4.设置定时器,将动画重复执行达到画线效果.
5.在绘画完成后,将线strokeDasharray设置成简单模式
6.画每一段长度相同的虚线时.dotted参数数组只有两个值
drawLongShortLine:function(obj,duration,dotted){
//参数少于3个的时候不执行
if(arguments.length<3){
return '参数错误';
}
return (function(){
/*
* 传入的参数:
* obj:要做动画的线;
* duration:动画的总时间,单位秒;
* dotted:传入数组,前n个参数是每一段的长度,最后一个参数是每一段间隔距离;
* 变量名解释:
* totalLength:线的总长度;
* dottedLength:前n段的平均长度;
* total:需要把整个动画分成的段数;=>总长度/(前n段的平均长度+间隔长度)
* str:每一小段的样式;
* duration:每一次执行时间;
* count:已经执行的次数;
* current:当前执行到第几段
* finish:结束时候线的样式
*/
var arrayLength = dotted.length;
var lineSpace = dotted[arrayLength-1];
var dottedLength = 0;
var finish = '';
//算出所有段的长度,求出平均长度
for(var i=0;i<arrayLength-1;i++){
dottedLength+=parseInt(dotted[i]);
finish = finish+dotted[i]+','+ lineSpace+',';
}
/*
* finish,结束时候线的样式,slice把最后的逗号去掉
*/
finish = finish.slice(0,-1);
dottedLength/=(arrayLength-1);
var totalLength = Math.ceil($('#' + obj.id)[0].getTotalLength())*2+100;total = Math.ceil(totalLength/(dottedLength+parseInt(lineSpace)));str = dotted[0] + ',';duration = duration*1000/total;count = 0;current = 1;
drawline(true);
function drawline(first){
speed = first?0:duration;
//开启定时器,在每一个时间小段画上一个片段
setTimeout(function(){
//小段个数拼接,按照顺序拼接
str= str + lineSpace + ',' + dotted[current] + ',';
//改变线的样式
$('#'+obj.id).css('strokeDasharray',str+totalLength*3);
count++;
current = current>=(arrayLength-2)?0:current+=1;
//判断是否执行完毕
if(count<total){
drawline(false);
}else{console.log(str)
//绘画完成后将改成初始样式
setTimeout(function(){
$('#'+obj.id).css('strokeDasharray',finish);
},speed)
}
},speed)
}
})()
}
本次传入的obj是我自己封装的线对象,不是jq对象,不是我多此一举 -_-也可以直接传入jq对象,后面的$('#+obj.id')全部换成obj