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, but I'm confused how to integrate this into d3. Basically what I want to do is to select the sprite that I want to use as an image from the sprite sheet and then use d3 to display this selected sprite somewhere else on the page, and most likely multiple copies of the same sprite.
The actual sprite sheet for reference (see disclaimer below):
Here are the issues:
1) I add the sprite sheet to my html, hard code the <clipPath>
for now, this displays the particular sprite I want, however, the dimensions/positioning of the sprite is just as though the entire sprite sheet is displayed. How can I only "capture" the sprite itself, not just hide the unused ones? In the image below, I want to use a single "icon" in a d3 mouseover event (part 2).
Modifying this example: SO: Display CSS image sprite in SVG without using foreignObject
HTML
<svg id="mySvg1" width="100%" height="100%">
<defs>
<clipPath id="c">
<rect x="135" y="0" width="150" height="150"/>
</clipPath>
</defs>
<image transform="scale(1.0)" x="0" y="0" width="550" height="420" xlink:href="static/img/iconSheet.png" clip-path="url(#c)"/>
<svg>
Result
2) I can use <pattern>
to determine an image to show in a d3 object/event. Like show a graphic in a rectangle. But this doesn't seem to work for large images (sprite sheets)? It becomes weird and blurry if I try to use the sprite sheet itself and its native dimensions in the pattern. If we solve part 1 we can probably ignore part 2, but this would be good to understand for general knowledge/future use.
Modifying this example: SO: Adding an image within a circle object in d3 javascript?
HTML
<svg id="mySvg" width="550" height="420">
<defs id="mdef">
<pattern id="image" x="0" y="0" height="550" width="420">
<image transform="scale(1.0)" x="0" y="0" width="550" height="420" xlink:href="static/img/iconSheet.png"></image>
</pattern>
</defs>
</svg>
Javascript:
var svgContainer = d3.select("div#content-main").append("svg")
.attr("width", 740)
.attr("height", 760)
.attr("class", "mySvg")
.style("border", "none");
svgContainer.append("rect")
.attr("class", "logo")
.attr("x", 0)
.attr("y", 0)
.attr("width", 550)
.attr("height", 420)
.style("fill", "transparent")
.style("stroke", "black")
.style("stroke-width", 0.25)
.on("mouseover", function(){
d3.select(this)
.style("fill", "url(#image)");
})
.on("mouseout", function(){
d3.select(this)
.style("fill", "transparent");
});
Result
3) IF there is a more efficient way to accomplish this I am open to suggestion. I'm simply sticking with the d3 model because I've already rendered an svg object and I just need to add things to it.
DISCLAIMER: The icons are not my work! I am using these icons for educational purposes only. The author's link is here: Fitness Icons