1

I'm trying to dynamically fill round svg objects with a background image in javascript.

I've created a pattern with an image inside of it but instead of the actual image, the svg elements are filled with a solid black background instead and I just can't seem to figure out what I'm doing wrong.

Here's my html:

<svg style="height: 405px;">
<g class="item-view" data-id="8" transform="translate(186.50687741518976,99.62945152749784)">
    <circle id="circle-8" r="60" opacity="1" style="fill:rgb(255,255,255); stroke: rgb(0, 132, 215); stroke-width: 3px;"></circle>
    <text x="-35.5" y="-27" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">New item</text>
    <text x="-46" y="-9" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">created with</text>
    <text x="-42.5" y="9" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">moderation</text>
    <text x="-30.5" y="27" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">disabled</text>
</g>
<g class="item-view" data-id="9" transform="translate(186.36080783220538,219.60697802343384)">
    <circle id="circle-9" r="60" opacity="1" style="fill: rgb(255,255,255); stroke: rgb(0, 132, 215); stroke-width: 3px;"></circle>
    <text x="-47" y="-9" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">New item by</text>
    <text x="-23" y="9" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">Seppo</text>
</g>
<g class="item-view" data-id="3" transform="translate(559.4999999997835,332.46850012177873)">
    <circle id="circle-3" r="60" opacity="1" style="fill:rgb(255,255,255); stroke: rgb(0, 132, 215); stroke-width: 3px;"></circle>
    <text x="-29" y="-27" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">Another</text>
    <text x="-40.5" y="-9" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">moderated</text>
    <text x="-41" y="9" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">item of the</text>
    <text x="-35" y="27" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">customer</text>
</g>
<g class="item-view" data-id="10" transform="translate(187.48988498687854,339.60166617577994)">
    <circle id="circle-10" r="60" opacity="1" style="fill:rgb(255,255,255); stroke: rgb(0, 132, 215); stroke-width: 3px;"></circle>
    <text x="-47" y="-9" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">New item by</text>
    <text x="-43" y="9" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">anonymous</text>
    <text x="-16" y="27" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 15px; line-height: 18px; font-family: verdana; opacity: 1; fill: rgb(0, 0, 0);">user</text>
</g>
</svg>

And here's the javascript:

var SVG_NS = $('svg')[0].namespaceURI;

var pattern = document.createElementNS(SVG_NS, 'pattern');

pattern.setAttribute('id', 'SVGBackgroundImage');
pattern.setAttribute('patternUnits', 'userSpaceOnUse');

var image = document.createElementNS(SVG_NS, 'image');
image.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', 'http://upload.wikimedia.org/wikipedia/en/e/ec/Soccer_ball.svg');
image.setAttribute('x', '0');
image.setAttribute('y', '0');

pattern.appendChild(image);

$('g.item-view circle').each(function (index) {
    $('g.item-view circle')[index].setAttribute('style', 'fill: url(#' + pattern.id + ');');
});

Here's a jsFiddle further illustrating the problem: http://jsfiddle.net/ubLr4/9/

Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204
jesseniem
  • 177
  • 3
  • 10
  • 1
    this [question](http://stackoverflow.com/questions/19202450/adding-an-image-within-a-circle-object-in-d3-javascript/19204833#19204833) might help – user1614080 Apr 12 '14 at 11:32

2 Answers2

2

There were several things wrong.

  1. As Francis said, you didn't attach the pattern to your SVG.
  2. You need to specify a width and height for your pattern
  3. You need to specify a width and height for your image

To simplify things, I switched to using "objectBoundingBox" units for patternUnits and patternContentUnits. So the pattern automatically scales to fit the circle's bounds.

pattern.setAttribute('patternContentUnits', 'objectBoundingBox');
pattern.setAttribute('width', '1');
pattern.setAttribute('height', '1');

You didn't really need to use a pattern here. It would have been simpler just to replace the circle with the image.

Anyway, here is a working version

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
1

Your pattern element was not appended to your root SVG element

Francis Hemsher
  • 3,478
  • 2
  • 13
  • 15