Search code examples
svgfill

Matching SVG fill pattern with repeated background image on containing element?


I am trying to create some ornate page dividers using SVGs with a fill pattern using the same image as the containing element's background image but I am having difficulty getting the SVG pattern to match the repeated background image of the containing element. I found a few similar questions on StackOverflow which mentioned using preserveAspectRatio but none of the solutions I've found are creating the desired effect.

Here's what my SVG code looks like:

<svg id="Layer_1" class="divider" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 150" >
    <defs>
        <pattern id="imgpattern" patternUnits="userSpaceOnUse" width="576" height="576" preserveAspectRatio="xMinYMin slice">
            <image width="576" height="576" xlink:href="http://s12.postimg.org/730a258rx/pattern2.jpg"/>
        </pattern>
        <filter id="dropshadow" height="130%">
            <feGaussianBlur in="SourceAlpha" stdDeviation="3"/>
                <feOffset dx="0" dy="2" result="offsetblur"/>
                <feMerge> 
                <feMergeNode/> 
                <feMergeNode in="SourceGraphic"/> 
            </feMerge>
        </filter>
    </defs>
    <path d="M-394.09,367.9V295.34l1400,0v70s-3.39.9-4.92,1.38c-56.68,17.79-114.85,25.72-174.22,26.17-36.9.27-73.6-2.7-110.25-6.28q-67.4-6.59-134.7-14.08c-49.65-5.51-99.28-8.74-149-1.64-35.12,5-68.54,15.05-99.24,33.08-6,3.53-12.09,7-18.13,10.48-8.94,5.18-17.93,5.51-27,.36-3.47-2-7.14-3.6-10.51-5.71-48.22-30.22-101-43.79-157.83-41.84-29.13,1-58.27,2.45-87.3,4.94-40.49,3.48-80.88,8.18-121.32,12.27-24.37,2.46-48.71,5.26-73.14,7a714.52,714.52,0,0,1-96.42.34,605.73,605.73,0,0,1-96.81-13.9C-368.07,374.88-394.09,367.9-394.09,367.9Z" transform="translate(394.09 -295.32)" stroke="none" fill="url(#imgpattern)" filter="url(#dropshadow)" />
</svg>

And here's a JSFiddle which recreates my issue. Notice how the background pattern of the SVG appears more stretched and because of that does not completely match the repeated background image of the container.


Solution

  • One option is just to move the pattern fill into the filter like so - although there is a small problem that your texture has a one pixel black border, so the tiling isn't perfect.

        <filter id="dropshadowandfill" height="130%" >
        <feImage x="0" y="0" width="575" height="575" xlink:href="http://s12.postimg.org/730a258rx/pattern2.jpg"></feImage>
        <feTile/>
        <feComposite operator="in" in2="SourceGraphic" result="filledOriginal"/>
            <feGaussianBlur in="SourceAlpha" stdDeviation="3"/>
                <feOffset dx="0" dy="2" result="offsetblur"/>
                <feMerge> 
                <feMergeNode/> 
                <feMergeNode in="filledOriginal"/> 
            </feMerge>
        </filter>
    </defs>
    <path d="M-394.09,367.9V295.34l1400,0v70s-3.39.9-4.92,1.38c-56.68,17.79-114.85,25.72-174.22,26.17-36.9.27-73.6-2.7-110.25-6.28q-67.4-6.59-134.7-14.08c-49.65-5.51-99.28-8.74-149-1.64-35.12,5-68.54,15.05-99.24,33.08-6,3.53-12.09,7-18.13,10.48-8.94,5.18-17.93,5.51-27,.36-3.47-2-7.14-3.6-10.51-5.71-48.22-30.22-101-43.79-157.83-41.84-29.13,1-58.27,2.45-87.3,4.94-40.49,3.48-80.88,8.18-121.32,12.27-24.37,2.46-48.71,5.26-73.14,7a714.52,714.52,0,0,1-96.42.34,605.73,605.73,0,0,1-96.81-13.9C-368.07,374.88-394.09,367.9-394.09,367.9Z" transform="translate(394.09 -295.32)" stroke="none" filter="url(#dropshadowandfill)"  />