Cmagelssen
Cmagelssen

Reputation: 660

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.

Upvotes: 0

Views: 129

Answers (1)

ccprog
ccprog

Reputation: 21811

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.

Upvotes: 4

Related Questions