Skip to content Skip to sidebar Skip to footer

Svg + Sprite Sheet + D3 + Clippath + Position + Size

Need to apologize in advance: for length and for my ignorance. I'm trying to teach myself new concepts: d3.js and sprite sheets. The sprite sheet concept is simple to understand, b

Solution 1:

I'm not sure what's going on with <pattern> example, but the problem with your <image> element is that you're not translating the image so that the icon you want is at the (0,0) point of the SVG.

This is what you need:

<svgid="mySvg1"width="100%"height="100%"viewBox="0 0 150 150"><defs><clipPathid="c"><rectx="135"y="0"width="150"height="150"/></clipPath></defs><imagetransform="translate(-135,0)"width="550"height="420"xlink:href="static/img/iconSheet.png"clip-path="url(#c)"/><svg>

Of course, if you're going to be making lots of icons and using them multiple places, I would suggest:

  1. defining the icons within a <defs> element, and then referencing them when needed with <use> elements;
  2. using a <use> element to position the image in each icon, so you only have to define the image url, height, and width once;
  3. nesting each image/use element within a <g> element, and applying the clipping path to it, so that you only have to define the clipping path once (assuming all icons are the same size).

Example here: http://codepen.io/AmeliaBR/pen/mwzBD

Key code for defining the icons:

<svg class="icon-defs">
  <defs><!-- The icons are defined in an SVG <defs> element;
        it could be in a different file,
        since the icons will be referenced by url. --><!-- One clipping path defines icon size --><clipPathid="icon-cp" ><rectx="0"y="0"width="150"height="100" /></clipPath><!-- One image element imports the file --><imageid="icon-sprite"width="969"height="293"xlink:href="http://i.stack.imgur.com/TPx5h.png" /><!-- Each icon fragment uses the same image 
         with a different translation --><gid="icon1"clip-path="url(#icon-cp)"><usexlink:href="#icon-sprite"transform="translate(0,0)" /></g><gid="icon2"clip-path="url(#icon-cp)"><usexlink:href="#icon-sprite"transform="translate(-240,0)" /></g><gid="icon3"clip-path="url(#icon-cp)"><usexlink:href="#icon-sprite"transform="translate(-240,-193)" /></g></defs>

Then you reference the icons like this:

<svgclass="icon"viewBox="0 0 150 100"height="4em"width="6em"><usexlink:href="#icon3"/></svg>

The viewBox attribute sets the internal dimensions for laying out the image and will be the same every time you use the icon; the height and width can be anything you want (although scaling down will of course look better than scaling up). If the height/width ratio doesn't match the icon, it will be squished or stretched, but you can prevent that with a preserveAspectRatio attribute.

Now, on to d3. It will probably be easiest to define the SVG fragments that represent the icons ahead of time, possibly in a separate file, although you could construct that DOM dynamically. When you actually want to insert an icon, you

For example, to add an inline icon image at the end of every element with the class "warning", you would do something like this:

d3.selectAll(".warning")
    .append("svg")
      .attr("viewBox", "0 0 "+ iconWidth + " " + iconHeight)
      .style("display", "inline")
      .style("height", "1em")
      .style("width", (iconWidth/iconHeight) + "em")
    .append("use")
      .attr("xlink:href", "#warning");

Of course, if you're using d3, you've probably got some data variable that tells you which icon to use, instead of a class, but you get the idea.

Solution 2:

I think a much simpler way to clip and position the icon is by using a nested <svg> with an appropriate viewBox.

<svgwidth="100%"height="100%"><!-- Repeat this for ever icon instance you want.
         Just change x and y attributes to set position of the icon in your SVG,
         and minX,minY (first two coords) of viewBox to select icon from sprite sheet. --><svgx="0"y="0"width="150px"height="150px"viewBox="135 0 150 150"><imagewidth="550px"height="420px"xlink:href="http://i.stack.imgur.com/qAO2h.png" /></svg></svg>

Post a Comment for "Svg + Sprite Sheet + D3 + Clippath + Position + Size"