I rule (.svg)

March 8, 2016

Here’sActually, “there”, as in up there at top:0; a neat little ruler in SVG for your enjoyment. It fills whatever size it’s parent allows it to fill. Unfortunately, I couldn’t get the JS to work when it’s loaded as an external file, so for now it has to be inline in the html or css.


<div style="height: 30px; width: 100%; position:fixed; top:0">
  <svg xmlns="http://www.w3.org/2000/svg" style="width:100%; height:100%;" version="1.1">
    <!-- Small tick marks at 5px intervals -->
    <pattern id="5px" width="5px" height="100%" x="0" y="0" patternUnits="userSpaceOnUse">
      <line stroke="#999" stroke-width="1px" x1="0" y1="0" x2="0" y2="50%"/>
    </pattern>
    <!-- Larger tick marks at 50px intervals -->
    <pattern id="50px" width="50px" height="100%" x="0" y="0" patternUnits="userSpaceOnUse">
      <line stroke="#000" stroke-width="1px" x1="0" y1="0" x2="0" y2="60%"/>
    </pattern>
    <!-- Full-height tick marks at 100px intervals -->
    <pattern id="100px" width="100px" height="100%" x="0" y="0" patternUnits="userSpaceOnUse">
      <line stroke="#000" stroke-width="1px" x1="0" y1="0" x2="0" y2="100%"/>
    </pattern>
    <script type="text/javascript">
      <![CDATA[
      // SVG does not (apparently) not have a way to access variables such as the current X/Y
      // position in texts. There's probably a really cool way it could be done with i. e. a
      // text matrix and some smart clipping/transforming, but for now we render the positions with
      // Javascript.
      function ticks() {
        if (document.readyState != "complete") {
          document.onreadystatechange = function () {
            ticks();
          }
          return;
        }

        window.onresize = function () {
          ticks();
        }
        var svg         = document.getElementsByTagName("svg")[0];
        var width       = svg.getClientRects()[0].width;

        for (var i = 0; i < width; i += 100) {
          var tickMark = document.createElementNS("http://www.w3.org/2000/svg", "text");
          var textNode = document.createTextNode(i);

          tickMark.appendChild(textNode);
          tickMark.setAttribute("x", i + 4)
          tickMark.setAttribute("y", "100%");
          tickMark.setAttribute("width", "96px");
          tickMark.setAttribute("height", "100%");
          tickMark.setAttribute("fill", "#000000");
          svg.appendChild(tickMark);
        }
      }
      ticks();

      ]]>
    </script>
    <!== putting it all together -->
    <rect fill="url(#text-100)" x="0" y="0" height="100%" width="100%"/>
    <rect fill="url(#100px)" x="0" y="0" height="100%" width="100%"/>
    <rect fill="url(#50px)" x="0" y="0" height="100%" width="100%"/>
    <rect fill="url(#5px)" x="0" y="0" height="100%" width="100%"/>
    <line stroke="black" stroke-width="1px" x1="0" y1="0" x2="0" y2="10"/>

  </svg>
  <div style="right:10px; position:fixed; text-align:right; size:0.8em">Ruler by<br/><a href="https://matthi.coffee/2016/i-rule-dot-svg">Matthias Winkelmann</a><br/> License: CC-0</div>
</div>


<!== putting it all together -->
I rule (.svg) - March 8, 2016 - mw