Javascript 为Svg路径D坐标设置动画

Javascript 为Svg路径D坐标设置动画,javascript,jquery,html,animation,svg,Javascript,Jquery,Html,Animation,Svg,具有svg路径坐标: M 8,21 L 12,21 L 17,26 L 17,10 L 12,15 L 8,15 L 8,21 z M 19,14 L 19,22 C 20.48,21.32 21.5,19.77 21.5,18 C 21.5,16.26 20.48,14.74 19,14 z M 19,11.29 C 21.89,12.15 24,14.83 24,18 C 24,21.17 21.89,23.85 19,24.71 L 19,26.77 C 23.01,25.86 26,22

具有
svg
路径
坐标:

M 8,21 L 12,21 L 17,26 L 17,10 L 12,15 L 8,15 L 8,21 z M 19,14 L 19,22 C 20.48,21.32 21.5,19.77 21.5,18 C 21.5,16.26 20.48,14.74 19,14 z M 19,11.29 C 21.89,12.15 24,14.83 24,18 C 24,21.17 21.89,23.85 19,24.71 L 19,26.77 C 23.01,25.86 26,22.28 26,18 C 26,13.72 23.01,10.14 19,9.23 L 19,11.29 z
按下这些按钮时,如何协调svg路径的平滑变化:

M 8,21 L 12,21 L 17,26 L 17,10 L 12,15 L 8,15 L 8,21 Z M 19,14 L 19,22 C 20.48,21.32 21.5,19.77 21.5,18 C 21.5,16.26 20.48,14.74 19,14 Z
提前感谢。

使用JQuery解决此问题的方法: 坐标新坐标
opt-动画的速度或实现的参数。它只需要两个参数:持续时间(执行速度;只接受数字;默认值为-1000)和放松(动画类型,需要两个参数:线性和swing默认值为-linear)

外部编辑器示例:
在线示例:

$.prototype.animatePathD=函数(d,o){
// Подстраиваем под разные браузера
变量i=$('body*')。长度;
$('body')。追加('');
d=$('#animatepathd'+i+'path').attr('d');
$('#animatepathd'+i).remove();
var e=这个,
d={
主要:{
框架:$(e).attr('d')。替换(/\\-[0-9.]+/g,{n}')。替换(/[0-9.]+/g,{n}'),
坐标:$(e).attr('d')。替换(/[^0-9-.]+/g',',')。替换(/([0-9.]+)\-([0-9.]+)/g',$1,$2')。替换(/^\,(.+)\,$/,'$1')。拆分(','))
},
最终:{
框架:d.replace(/\\-[0-9.]+/g,{n}')。replace(/[0-9.]+/g,{n}'),
坐标:d.replace(/[^0-9-.]+/g',,')。replace(/([0-9.]+)\-([0-9.]+)/g',$1,$2')。replace(/^\,(.+)\,$/,“$1')。拆分(','))
}
},
opt=o;
if(opt==未定义){
选择={
持续时间:1000,
放松:“线性”
};
}如果(/^\d+$/.exec(opt)!=null,则为else){
选择={
持续时间:选择,
放松:“线性”
};
if(opt.duration==undefined | |/^\d+$/.exec(opt.duration)==null){
opt.duration=1000
};
}否则{
if(opt.duration==undefined | |/^\d+$/.exec(opt.duration)==null){
opt.duration=1000
};
如果(选择缓和!='swing'&选择缓和!='linear'){
opt.easing='线性'
};
};
if(d.primary.frame==d.final.frame){
var funPoint={
主:{},
最后:{},
列表:“”,
帧:““+d.final.frame+””
};
对于(变量i=0;i
@import url('data:text/css;charset=UTF-8,body{font-family:Tahoma,sans-serif;font-size:0.8rem;}a{display:inline block;color:#427fed;cursor:pointer;text-decoration:none;margin-right:5px;}a:hover{text-decorcorcoration:under;}按钮{-webkit padding end:10px;-webkit padding start:10px;最小高度:2em;最小宽度:4em;padding bottom:1px;-webkit外观:无;-webkit用户选择:无;背景图像:-webkit线性渐变(#eded,#eded 38%,#dedede);边框:1px实心rgba(0,0,0,0.25);边框半径:2px;方框阴影:0 1px 0 rgba(0,0,0.08),插入0 1px 2px rgba(255,255,255,0.75);颜色:#444;字体:继承;边距:0 1px 0 0;轮廓:无;文本阴影:0 1px 0 rgb(240,240,240);}按钮:悬停{背景图像:-webkit线性渐变(#F0F0F0F0F0,#F0F0F0F0 38%,#E0E0E0E0E00);边框颜色:rgba(0,0,0,0,0.3);方框阴影:0 1px 0 rgba(0,0,0,0,0.12),插入rgba(255,255,255,0.95);颜色:黑色;}按钮:活动{背景图像:-webkit线性渐变(#e7e7e7,#e7e7e7 38%,#d7d7d7);框阴影:无;文本阴影:无;}按钮:焦点{-webkit转换:边框颜色200ms;边框颜色:rgb(77,144,254);轮廓:无;}选择{-webkit填充结束:20px;-webkit填充开始:6px;背景位置:右中心;背景重复:无重复;最小高度:2em;最小宽度:4em;填充底部:0;-webkit用户选择:无;背景图像:-webkit线性渐变(#eded,#eded 38%,#dede);边框:1px实心rgba(0,0,0.25);边框半径:2px;框阴影:0 1px 0 rgba(0,0,0,0.08),插入0 1px 2px rgba(255,255,255,0.75);颜色:#444;字体:继承;边距:0 1px 0 0;轮廓:无;文本阴影:0 1px 0 rgb(240,240);}选择:悬停{背景图像:url(数据:图片/png;base64,IVBorW0KggoaaaAnsuhueugaabmaaaaaicaqaacxSawfaaaaukleq%E2%80%A6bbclciucsaw21qHxxFirWkAmpFnseuyRxGVCqWbQqCqCctu4VgaaabjRu5erkJggg==),-webkit线性渐变(#f0f0f0f0f0f0f0,#f0f0f0 38%,#e0e0e0e0e0e0e0e0);边框颜色:rgba(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.3);方框阴影:0.1px0,0,0,0,255,0,255,255;颜色:黑色;}选择:活动{背景图像:url(数据:image/png;base64,ivborw0kgoaansuhueugaabmaaaicaqaacxsawfaaaaukleq%E2%80%a6bbclciucsaw21qhxxfiirwkampfnseuyrxgvcefc6cqwqq4ccctu4vgaaabjru5erkjggg=),-webkit线性渐变(#e7e7e7e7,#e7e7e7 38%,#d7d7%);方框阴影:无;文本:无;选择阴影;}{-webkit转换:边框颜色200ms;边框颜色:rgb(77144254);轮廓:无;}
$.prototype.animatePathD = function(d, o) {
  // Подстраиваем под разные браузера
  var i = $('body *').length;
  $('body').append('<svg id="animatepathd' + i + '" style="display:none"><path d="' + d + '"></svg>');
  d = $('#animatepathd' + i + ' path').attr('d');
  $('#animatepathd' + i).remove();

  var e = this,
    d = {
      primary: {
        frame: $(e).attr('d').replace(/\ \-[0-9.]+/g, ' {n}').replace(/[0-9.]+/g, '{n}'),
        coord: $(e).attr('d').replace(/[^0-9-.]+/g, ',').replace(/([0-9.]+)\-([0-9.]+)/g, '$1,$2').replace(/^\,(.+)\,$/, '$1').split(',')
      },
      final: {
        frame: d.replace(/\ \-[0-9.]+/g, ' {n}').replace(/[0-9.]+/g, '{n}'),
        coord: d.replace(/[^0-9-.]+/g, ',').replace(/([0-9.]+)\-([0-9.]+)/g, '$1,$2').replace(/^\,(.+)\,$/, '$1').split(',')
      }
    },
    opt = o;
  if (opt == undefined) {
    opt = {
      duration: 1000,
      easing: 'linear'
    };
  } else if (/^\d+$/.exec(opt) != null) {
    opt = {
      duration: opt,
      easing: 'linear'
    };
    if (opt.duration == undefined || /^\d+$/.exec(opt.duration) == null) {
      opt.duration = 1000
    };
  } else {
    if (opt.duration == undefined || /^\d+$/.exec(opt.duration) == null) {
      opt.duration = 1000
    };
    if (opt.easing != 'swing' && opt.easing != 'linear') {
      opt.easing = 'linear'
    };
  };
  if (d.primary.frame == d.final.frame) {
    var funPoint = {
      primary: {},
      final: {},
      list: '',
      frame: "'" + d.final.frame + "'"
    };
    for (var i = 0; i < d.primary.coord.length; i++) {
      funPoint.primary['c' + i] = d.primary.coord[i];
      funPoint.final['c' + i] = d.final.coord[i];
      funPoint.list = ', c' + i;
      if (d.primary.coord.length != 0) {
        funPoint.frame = funPoint.frame.replace(/\{n\}/, "'+obj.elem.c" + i + "+'")
      } else {
        funPoint.frame = funPoint.frame.replace(/\{n\}/, "'+c" + i + "+'")
      };
    };
    funPoint.list = funPoint.list.replace(/^\,\ (.+)$/, '$1');
    $(funPoint.primary).animate(funPoint.final, {
      duration: opt.duration,
      easing: opt.easing,
      step: function(c0, obj) {
        $(e).attr('d', eval(funPoint.frame));
      }
    });
  } else {
    console.error('Frameworks coordinates do not match!');
  };
};
$(svg path).animatePathD('coordinates', opt);
$.prototype.animatePathD = function(d) {
  var e = this,
      animate = $(e).find('animate[data-animatePathD]');
  if(animate.length){
    animate.attr({
      'attributeName': 'd', 
      'attributeType': 'XML',
      'from': animate.attr('to') || $(e).attr('d'),
      'to': d,
      'fill': 'freeze'
    });
    animate[0].beginElement();
  };
};
<path>
  <animate data-animatePathD dur="0.15s" begin="none" />
</path>