How did they do this with SVG's, a static image, hotspots and javascript

Viewed 500

About half way down on the following site there is an image of a house with SVG animations and hotspots.

https://enphase.com/en-us/homeowners

I see all the individual elements but I don't understand how the they put it all together. The elements are positioned using percentages to 5 decimal places. I'm assuming they used some software to create the SVGs put more importantly, the layout. Any idea what that software is? There is now way they hand coded the layout and calculated the positioning.

1 Answers

You can have the same functionality using SVG stroke-dasharray and stroke-dashoffset attributes mainipulation with javascript animation timers, I usually use D3.js to do this type of animation/SVG manipulation, but you can also do it purely in javascript, here is a block example by Noah Veltman on bl.ocks.org:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <style>
    path {
      fill: none;
      stroke: #d3008c;
      stroke-width: 2px;
    }

    #arrowhead {
      fill: #d3008c;
      stroke: none;
    }

  </style>
</head>
<body>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="960" height="500">
  <path d="M636.5,315c-0.4-18.7,1.9-27.9-5.3-35.9
   c-22.7-25-107.3-2.8-118.3,35.9c-7,24.4,20.6,37.2,16,71c-4,29.6-30.8,60.7-56.5,61.1c-30.8,0.4-32.9-43.8-81.7-70.2
   c-50.9-27.6-110.1-12.9-125.2-9.2c-66.1,16.4-82.2,56.9-109.2,47.3c-38-13.6-55.9-112.1-19.8-143.5c39-34,121.2,27.7,148.1-3.8
   c18-21.1,3.1-74.3-25.2-105.3c-31.1-34.1-70.1-32.4-105.3-76.3c-8.2-10.2-16.9-23.8-15.3-39.7c1.2-11.4,7.5-23.3,15.3-29
   c33.8-25,101.6,62.6,193.1,59.5c40.1-1.3,38.7-18.5,99.2-38.9c126.2-42.6,242.4-4.9,297.7,13c54.7,17.7,105.4,35,129.8,82.4
   c13,25.3,22.9,67.7,4.6,87c-11.6,12.3-25.1,5.1-46.6,20.6c-2.8,2-28.9,21.4-32.1,49.6c-3.1,27.4,18.7,35,29,70.2
   c8.8,30.1,8.5,77.8-18.3,99.2c-32.3,25.8-87,0.6-100-5.3c-69.6-32-67.2-88.4-73.3-109.2z"/>
    <defs>
      <path id="arrowhead" d="M7,0 L-7,-5 L-7,5 Z" />
    </defs>
</svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

  var path = document.querySelector("path"),
      totalLength = path.getTotalLength(),
      group = totalLength / 20,
      start;

  var arrowheads = d3.select("svg").selectAll("use")
    .data(d3.range(20).map(function(d){ return d * group + 50; }))
    .enter()
    .append("use")
      .attr("xlink:href", "#arrowhead");

  path.style.strokeDasharray = "50," + (group - 50);

  requestAnimationFrame(update);

  function update(t) {
    if (!start) {
      start = t;
    }

    var offset = -group * ((t - start) % 900) / 900;

    path.style.strokeDashoffset = offset;

    arrowheads.attr("transform",function(d){

      var l = d - offset;

      if (l < 0) {
        l = totalLength + l;
      } else if (l > totalLength) {
        l -= totalLength;
      }

      var p = pointAtLength(l);
      return "translate(" + p + ") rotate( " + angleAtLength(l) + ")";
    });

    requestAnimationFrame(update);
  }

  function pointAtLength(l) {

    var xy = path.getPointAtLength(l);
    return [xy.x, xy.y];

  }

  // Approximate tangent
  function angleAtLength(l) {

    var a = pointAtLength(Math.max(l - 0.01,0)), // this could be slightly negative
        b = pointAtLength(l + 0.01); // browsers cap at total length

    return Math.atan2(b[1] - a[1], b[0] - a[0]) * 180 / Math.PI;

  }

</script>

And this is how the <path> looks like without animations:

path {
  fill: none;
  stroke: #d3008c;
  stroke-width: 2px;
}

#arrowhead {
  fill: #d3008c;
  stroke: none;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="960" height="500">
  <path d="M636.5,315c-0.4-18.7,1.9-27.9-5.3-35.9
   c-22.7-25-107.3-2.8-118.3,35.9c-7,24.4,20.6,37.2,16,71c-4,29.6-30.8,60.7-56.5,61.1c-30.8,0.4-32.9-43.8-81.7-70.2
   c-50.9-27.6-110.1-12.9-125.2-9.2c-66.1,16.4-82.2,56.9-109.2,47.3c-38-13.6-55.9-112.1-19.8-143.5c39-34,121.2,27.7,148.1-3.8
   c18-21.1,3.1-74.3-25.2-105.3c-31.1-34.1-70.1-32.4-105.3-76.3c-8.2-10.2-16.9-23.8-15.3-39.7c1.2-11.4,7.5-23.3,15.3-29
   c33.8-25,101.6,62.6,193.1,59.5c40.1-1.3,38.7-18.5,99.2-38.9c126.2-42.6,242.4-4.9,297.7,13c54.7,17.7,105.4,35,129.8,82.4
   c13,25.3,22.9,67.7,4.6,87c-11.6,12.3-25.1,5.1-46.6,20.6c-2.8,2-28.9,21.4-32.1,49.6c-3.1,27.4,18.7,35,29,70.2
   c8.8,30.1,8.5,77.8-18.3,99.2c-32.3,25.8-87,0.6-100-5.3c-69.6-32-67.2-88.4-73.3-109.2z"/>
    <defs>
      <path id="arrowhead" d="M7,0 L-7,-5 L-7,5 Z" />
    </defs>
</svg>

Related