简体   繁体   中英

Animate an external svg object along a simple line path in D3.js

I am trying to animate a skier along a slope. I have drawn the skier in SVG like this:

<?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>

The next thing I want to do is to animate him along a line path I have created in D3. My work looks like this:


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");

My question is how can I get this object to follow the line path? I have found some relevant work but I find it difficult to understand how this animation actually work. I have spent the whole day trying to figure this out, so I would be happy if someone can help me out, at least point me in the right direction.

You were looking in the right direction with the example you linked. Basically, all you have to do is exchange the circle with an <image> tag referencing your skier:

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]) + ")");

The transition can be defined as simple as this als long as your path only consists of two points:

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

For more complex animations, look at https://github.com/d3/d3-transition/ for the documentation how transitions and tween functions work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM