【问题标题】:best options for flowing dotted lines (svg path animation) in ie?在ie中流动虚线(svg路径动画)的最佳选择?
【发布时间】:2024-04-24 07:00:02
【问题描述】:

我被分配创建一个带有虚线(路径)的图表,这些虚线(路径)流向图表中的圆圈。使用以下示例,我得到了一个基于 d3.js 的原型:

http://bl.ocks.org/nitaku/6354551

但是上面的 url 在 IE 中不起作用,即使是最新版本也不行。我需要支持 IE 回到 IE9。我的 svg 动画要求是相当基本的。只需要圆之间的流线(svg 路径)。

支持此要求的最优雅的方式是什么?寻找最简单、直接的方法,该方法将支持在所有主要浏览器中循环 svg 路径到可追溯到 IE9 的圆。

【问题讨论】:

  • 最简单?向 IE9 用户显示动画 gif。
  • 寻找可重复使用的东西。该图表也是使用不同的参数动态生成的,因此 1-off 动画 gif 不适用于此。考虑使用 js 解决方案为线条设置动画。似乎这可能是最直接的解决方案
  • 看起来有几个 js 库可以做一些高级的 svg 动画,比如maxwellito.github.io/vivus。然而,我的场景是非常基本的 - 直线虚线动画以可变速度流动。所以我在想一个简单的函数或者几个js函数可以用来完成我需要做的事情

标签: javascript css d3.js svg internet-explorer-9


【解决方案1】:

您的示例代码正在使用一些高级 CSS 制作动画。这是使用 d3 transition 编写的相同动画。

更新

我在d3第4版中写的下面的版本在IE9中似乎不起作用...这是一个d3第3版示例:

<!DOCTYPE html>
<html>

<head>
  <script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
  <style>
    .node {
      fill: #dddddd;
      stroke: gray;
      stroke-width: 4;
    }
    
    .flowline {
      fill: none;
      stroke: black;
      opacity: 0.5;
      stroke-width: 4;
      stroke-dasharray: 10, 4;
    }
  </style>
</head>

<body>
  <script>
    var width = 960,
      height = 500;

    var svg = d3.select('body').append('svg')
      .attr('width', width)
      .attr('height', height);

    var ex1 = svg.append('g')
      .attr('transform', 'translate(50 50)');

    ex1.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M100 100 L300 100');

    ex1.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M200 300 L300 100');

    ex1.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M200 300 L300 250');

    ex1.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M300 250 L100 100');

    ex1.append('circle')
      .attr('class', 'node')
      .attr('cx', 100)
      .attr('cy', 100)
      .attr('r', 20);

    ex1.append('circle')
      .attr('class', 'node')
      .attr('cx', 300)
      .attr('cy', 100)
      .attr('r', 20);

    ex1.append('circle')
      .attr('class', 'node')
      .attr('cx', 200)
      .attr('cy', 300)
      .attr('r', 20);

    ex1.append('circle')
      .attr('class', 'node')
      .attr('cx', 300)
      .attr('cy', 250)
      .attr('r', 20);

    var ex2 = svg.append('g')
      .attr('transform', 'translate(450 50)');

    ex2.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M100 100 S200 0 300 100');

    ex2.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M200 300 S200 200 300 100');

    ex2.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M200 300 S300 350 300 250');

    ex2.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M300 250 L100 100');

    ex2.append('circle')
      .attr('class', 'node')
      .attr('cx', 100)
      .attr('cy', 100)
      .attr('r', 20);

    ex2.append('circle')
      .attr('class', 'node')
      .attr('cx', 300)
      .attr('cy', 100)
      .attr('r', 20);

    ex2.append('circle')
      .attr('class', 'node')
      .attr('cx', 200)
      .attr('cy', 300)
      .attr('r', 20);

    ex2.append('circle')
      .attr('class', 'node')
      .attr('cx', 300)
      .attr('cy', 250)
      .attr('r', 20);

    function animate(){
      d3.select(this)
        .transition()
        .ease('linear')
        .duration(1000)
        .styleTween("stroke-dashoffset", function() {
          return d3.interpolate(0, 14);
        })
        .each("end", animate);
    }

    d3.selectAll(".flowline")
      .each(animate);

  </script>
</body>

</html>

原答案

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
  <!--[if lte IE 9]>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/aight/1.2.2/aight.d3.min.js"></script>
  <![endif]-->
  
  
  <style>
    .node {
      fill: #dddddd;
      stroke: gray;
      stroke-width: 4;
    }
    
    .flowline {
      fill: none;
      stroke: black;
      opacity: 0.5;
      stroke-width: 4;
      stroke-dasharray: 10, 4;
    }
  </style>
</head>

<body>
  <script>
    var width = 960,
      height = 500;

    var svg = d3.select('body').append('svg')
      .attr('width', width)
      .attr('height', height);

    var ex1 = svg.append('g')
      .attr('transform', 'translate(50 50)');

    ex1.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M100 100 L300 100');

    ex1.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M200 300 L300 100');

    ex1.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M200 300 L300 250');

    ex1.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M300 250 L100 100');

    ex1.append('circle')
      .attr('class', 'node')
      .attr('cx', 100)
      .attr('cy', 100)
      .attr('r', 20);

    ex1.append('circle')
      .attr('class', 'node')
      .attr('cx', 300)
      .attr('cy', 100)
      .attr('r', 20);

    ex1.append('circle')
      .attr('class', 'node')
      .attr('cx', 200)
      .attr('cy', 300)
      .attr('r', 20);

    ex1.append('circle')
      .attr('class', 'node')
      .attr('cx', 300)
      .attr('cy', 250)
      .attr('r', 20);

    var ex2 = svg.append('g')
      .attr('transform', 'translate(450 50)');

    ex2.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M100 100 S200 0 300 100');

    ex2.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M200 300 S200 200 300 100');

    ex2.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M200 300 S300 350 300 250');

    ex2.append('path')
      .attr('class', 'flowline')
      .attr('d', 'M300 250 L100 100');

    ex2.append('circle')
      .attr('class', 'node')
      .attr('cx', 100)
      .attr('cy', 100)
      .attr('r', 20);

    ex2.append('circle')
      .attr('class', 'node')
      .attr('cx', 300)
      .attr('cy', 100)
      .attr('r', 20);

    ex2.append('circle')
      .attr('class', 'node')
      .attr('cx', 200)
      .attr('cy', 300)
      .attr('r', 20);

    ex2.append('circle')
      .attr('class', 'node')
      .attr('cx', 300)
      .attr('cy', 250)
      .attr('r', 20);
      
    animate();
    function animate() {
      d3.selectAll(".flowline")
        .transition()
        .duration(1000)
        .ease(d3.easeLinear)
        .styleTween("stroke-dashoffset", function() {
          return d3.interpolate(0, 14);
         })
        .on("end", animate);
    }
  </script>
</body>

</html>

【讨论】:

  • 感谢您将样本放在一起。当我在 ie11 和 ie10 中运行它时它运行良好,但是当我在 ie9 中运行它时崩溃。 ie9 需要额外的调整吗?我不需要比 ie9 更进一步,但我需要支持 ie9。 d3不是声称支持ie9吗?或者是否需要 polyfills/mixins 来支持某些浏览器的某些场景?
  • @user6867266,请参阅上面的更新。我没有意识到d3 版本 4 放弃了 IE9 支持。我在 d3 第 3 版中重写了它,并在运行 IE9 仿真的 IE11 中对其进行了测试。似乎工作。
  • 感谢标记-您的示例运行良好。谢谢你把它放在一起。我正在尝试将您的方法纳入我正在研究的特定实现中。这是带有路径/流线的svg:[dropbox.com/s/svcx1lonuy9l267/NeSeFlow.svg?dl=0].这是 html/js:[jsbin.com/timixuq/edit?html,output].该解决方案在 ie10 中有效,但在 ie9 中引发 d3 错误。如果您发现问题,请看一下并 lmk 吗?
  • @user6867266,看起来 IE9 不喜欢将笔画属性与stroke-dashoffset 样式混合。代替.styleTween("stroke-dashoffset",使用.attrTween("stroke-dashoffset"...
  • 谢谢马克!你是一个救生员。你有一个带有“发送啤酒”按钮的网站吗?