沿D3.js中的简单线路径对外部svg对象进行动画处理

时间:2020-08-15 15:09:18

标签: javascript d3.js svg

我正在尝试使滑雪者沿斜坡动画。我在SVG中画了这样的滑雪者:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M314.71 209.12C348.44 217.53 361.94 235.23 355.21 262.21C342.09 314.83 334.8 344.06 333.35 349.91C326.62 376.89 306.39 386.18 272.66 377.77C272.66 377.77 272.66 377.77 272.66 377.77C238.93 369.36 225.43 351.66 232.16 324.68C245.28 272.06 252.57 242.83 254.02 236.98C260.75 210 280.98 200.71 314.71 209.12C314.71 209.12 314.71 209.12 314.71 209.12Z" id="a8xhEeVzU"></path><path d="M137.26 239.45L450.11 329.83" id="c4PTA7jJrE"></path><path d="M172.26 447.53L502.5 517.05" id="d8oLNEQwv"></path><path d="M290.45 156.35C290.45 133.32 309.13 114.64 332.17 114.64C355.2 114.64 373.88 133.32 373.88 156.35C371.1 156.35 357.2 156.35 332.17 156.35C309.92 156.35 296.01 156.35 290.45 156.35Z" id="cLdavstPZ"></path><path d="M373.88 156.35C373.88 179.39 355.2 198.07 332.17 198.07C309.13 198.07 290.45 179.39 290.45 156.35C293.23 156.35 307.14 156.35 332.17 156.35C354.41 156.35 368.32 156.35 373.88 156.35Z" id="cEtIeZWr3"></path><path d="M274.12 375.48C318.82 386.63 346.03 431.91 334.88 476.62C334.41 478.53 333.86 480.42 333.25 482.29C332.59 482.08 327.3 480.35 326.64 480.14C339.73 439.98 317.79 396.81 277.64 383.72C275.92 383.16 274.19 382.66 272.43 382.23C272.77 380.88 273.78 376.83 274.12 375.48Z" id="b3SpnZzX4B"></path><path d="M395.32 321.12C349.94 329.12 306.67 298.82 298.67 253.44C298.33 251.51 298.06 249.56 297.85 247.6C298.54 247.52 304.08 246.95 304.77 246.88C309.14 288.89 346.74 319.4 388.75 315.02C390.55 314.84 392.34 314.59 394.11 314.27C394.35 315.64 395.08 319.75 395.32 321.12Z" id="ailpBmbkR"></path></defs><g><g><g><use xlink:href="#a8xhEeVzU" opacity="1" fill="#009999" fill-opacity="1"></use><g><use xlink:href="#a8xhEeVzU" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="7" stroke-opacity="1"></use></g></g><g><use xlink:href="#c4PTA7jJrE" opacity="1" fill="#000000" fill-opacity="1"></use><g><use xlink:href="#c4PTA7jJrE" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="6" stroke-opacity="1"></use></g></g><g><use xlink:href="#d8oLNEQwv" opacity="1" fill="#000000" fill-opacity="1"></use><g><use xlink:href="#d8oLNEQwv" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="6" stroke-opacity="1"></use></g></g><g><use xlink:href="#cLdavstPZ" opacity="1" fill="#ff0066" fill-opacity="1"></use><g><use xlink:href="#cLdavstPZ" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="6" stroke-opacity="1"></use></g></g><g><use xlink:href="#cEtIeZWr3" opacity="1" fill="#ffffff" fill-opacity="1"></use><g><use xlink:href="#cEtIeZWr3" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="6" stroke-opacity="1"></use></g></g><g><use xlink:href="#b3SpnZzX4B" opacity="1" fill="#000000" fill-opacity="1"></use><g><use xlink:href="#b3SpnZzX4B" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="3" stroke-opacity="1"></use></g></g><g><use xlink:href="#ailpBmbkR" opacity="1" fill="#000000" fill-opacity="1"></use><g><use xlink:href="#ailpBmbkR" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="4" stroke-opacity="1"></use></g></g></g></g></svg>

我接下来要做的就是沿着我在D3中创建的直线路径为他设置动画。我的作品是这样的:


var width = 800;
var height = 600;

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

// linjekonstruktor
var line = d3.svg.line()
  .x(function(d) { return d.x; })
  .y(function(d) { return d.y; })
  .interpolate('linear');

// mine data
var lineData = [
  { "x": 30,   "y": 5},
  { "x": 550,  "y": 200},
];

var lineGraph = svg.append("path")
  .attr("d", line(lineData))
  .attr("stroke", "blue")
  .attr("stroke-width", 2)
  .attr("fill", "none");

我的问题是如何使该对象遵循行路径?我找到了一些相关的work,但很难理解该动画的实际工作原理。我花了整整一天的时间试图弄清楚这一点,所以如果有人可以帮助我,至少将我指出正确的方向,我将很高兴。

1 个答案:

答案 0 :(得分:4)

您所链接的示例的方向正确。基本上,您要做的就是用一个指向您的滑雪者的<image>标签交换圈子:

var skier = svg.append("image")
    .attr("href", "path/to/my/skier.svg")
    .attr("x", 0)        // play around with this for appropriate positioning
    .attr("y", 0)
    .attr("width", 100)  // ... and appropriate size
    .attr("height", 100)
    .attr("transform", "translate(" + Object.values(lineData[0]) + ")");

只要您的路径仅包含两点,就可以将过渡定义为简单的

skier.transition()
    .duration(10000)
    .attr("transform", "translate(" + Object.values(lineData[1]) + ")");

有关更复杂的动画,请参见https://github.com/d3/d3-transition/,以获取有关过渡和补间功能如何工作的文档。