jquerysvgjquery-svgjquery.panzoom

Attach background image to nested SVG element


I'm attempting to append a PNG or JPG background image to a SVG. Currently the background image does not show up, after trying multiple different methods of attaching it.

I am using jQuery.panzoom as well as jquery.svg (only if I need to for this issue).

The zoom and pan feature is working for the <g> element which then moves all the polygons and text elements inside of it together. What I want to have is a background image that is essentially attached to the <g> (or <svg>), so that it moves when I move the <g> and its children. (I know you cannot attach a background image to a <g> element).

Basic SVG markup

My basic grouping of SVG elements looks like this...

<svg id="pnlShapes" width="640" height="480">
    <svg id="shapes" width="640" height="480">
        <g id="shapes-group" width="640" height="480">
            <polygon id="svgSection_Floor" points="222.61,199.75,222.61,295.19,380.62,295.19,380.62,199.75,222.61,199.75,368.46,283.92,233.54,283.92,233.54,209.12,368.46,209.12,368.46,283.92" title="Floor" link="Primary" style="color: rgb(211, 211, 211); font-size: 0px; left: 0px; top: 0px; opacity: 0.82; fill: rgb(211, 211, 211); cursor: not-allowed;"></polygon>
            <text x="302.61" y="289.4705" fill="white" font-size="9" font-weight="bold" text-anchor="middle">Floor</text>
            <!-- plus a bunch more polygon and text element... -->
        </g>
    </svg> 
</svg>

What I've Tried...

I have tried to use a pattern fill to attach a background image. jsFiddle

    <svg id="pnlShapes" width="640" height="480">
        <defs xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg">
            <pattern id="image" x="0" y="0" patternunits="userSpaceOnUse" height="480" width="640">
                <image x="0" y="0" width="640" height="480" xlink:href="http://localhost:44000/Content/images/theImage.jpg"></image>
            </pattern>
       </defs>
        <svg id="shapes" width="640" height="480" fill="url(#image)">
            <g id="shapes-group" width="640" height="480">
                <polygon id="svgSection_Floor" points="222.61,199.75,222.61,295.19,380.62,295.19,380.62,199.75,222.61,199.75,368.46,283.92,233.54,283.92,233.54,209.12,368.46,209.12,368.46,283.92" title="Floor" link="Primary" style="color: rgb(211, 211, 211); font-size: 0px; left: 0px; top: 0px; opacity: 0.82; fill: rgb(211, 211, 211); cursor: not-allowed;"></polygon>
                <text x="302.61" y="289.4705" fill="white" font-size="9" font-weight="bold" text-anchor="middle">Floor</text>
            </g>
        </svg> 
    </svg>

I also tried using jquery.svg to attach a background image jsFiddle:

$('#shapes').svg();
var foo = $('#shapes').svg('get');
foo.filters.image(null, '', "http://localhost:44000/Content/images/theImage.jpg");


Here's my pan & zoom code also (using jquery.panzoom), if it helps:

var $section = $('#svg-container').first();
$section.find('g').panzoom({
    $zoomIn: $section.find(".zoom-in"),
    $zoomOut: $section.find(".zoom-out"),
    $zoomRange: $section.find(".zoom-range"),
    $reset: $section.find(".reset")
});

Final Thoughts

If using a plugin is the best way to accomplish that then I have no problem using it. I just need to have a background image on the <svg id="shapes"> or inside of that or the <g> element.


Solution

  • SVG doesn't support CSS background images. You can simulate it by creating a <rect> element that occupies the whole space as the first child though

    <svg id="pnlShapes" width="640" height="480">
        <defs>
            <pattern id="image" patternUnits="userSpaceOnUse" height="480" width="640">
                <image width="640" height="480" xlink:href="https://octodex.github.com/images/octoliberty.png"></image>
            </pattern>
        </defs>
        <svg id="shapes" width="640" height="480">
            <rect width="100%" height="100%" fill="url(#image)"/>
            <g id="shapes-group">
                <polygon id="svgSection_Floor" points="222.61,199.75,222.61,295.19,380.62,295.19,380.62,199.75,222.61,199.75,368.46,283.92,233.54,283.92,233.54,209.12,368.46,209.12,368.46,283.92" title="Floor" link="Primary" style="color: rgb(211, 211, 211); font-size: 0px; left: 0px; top: 0px; opacity: 0.82; fill: rgb(211, 211, 211); cursor: not-allowed;"></polygon>
                <text x="302.61" y="289.4705" fill="white" font-size="9" font-weight="bold" text-anchor="middle">Floor</text>
            </g>
        </svg>
    </svg>