19

I'm am trying to create an SVG which masks an image with a particular path however, when I try to fill the area using a pattern, the image does not cover the entire area.

Expected

Actual

In my defs I am defining the pattern:

<pattern id="image" patternUnits="userSpaceOnUse" width="83.38" height="100" x="0" y="0">
  <image xlink:href="http://goo.gl/kVVuy1" x="0" y="0" width="100%" height="100%" />
</pattern>

and the shape:

<path id="shape" d="M80.4,0c0,33.3,0,66.7,0,100c-26.8,0-53.6,0-80.4,0c0,0,0-0.1,0-0.1 c3.3-12.3,6.5-24.6,9.8-37c0.9-21,1.9-41.9,2.8-62.9C35.2,0,57.8,0,80.4,0z" />

then I include the shape:

<use xlink:href="#shape" fill="url(#image)"></use>

The image I'm using is dynamic asset (user uploaded), however I can obtain the dimensions if necessary.

Any solution that would solve this issue would help, I tried using an image with a mask but had no luck. As long as the blue background pattern shows through and no red does then my problem should be solved.

Here is the working example: http://codepen.io/Godwin/pen/hazqA

Godwin
  • 9,739
  • 6
  • 40
  • 58

3 Answers3

44

To fix this, add an appropriate preserveAspectRatio attribute to the <image> in your <pattern> to tell it that you want the image to be zoomed and sliced.

<pattern id="image" patternUnits="userSpaceOnUse" width="83.38" height="100" x="0" y="0">
  <image xlink:href="http://goo.gl/kVVuy1"
         x="0" y="0" width="100%" height="100%"
         preserveAspectRatio="xMinYMin slice"/>
</pattern>

Demo here

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
  • 1
    Perfect! I had no idea that `preserveAspectRatio` could be used on anything other than the `svg` root. Thanks! – Godwin Apr 23 '14 at 15:07
12

If background-position is needed as well as background-size: cover;

preserveAspectRatio="xMidYMid slice" // Will center the image

This link has all options available for the preserveAspectRatio attribute. And can help with centering the image within the pattern

All Options

user3436035
  • 141
  • 1
  • 3
  • Welcome to Stack Overflow! [How to Answer](http://stackoverflow.com/help/how-to-answer) can help you write answers that will be accepted and upvoted. – zhon Nov 24 '16 at 03:06
  • Thanks I didn't notice the difference first ! **Min** and **Mid** – amd Oct 27 '18 at 21:43
1
<div class="wrap">
  <svg viewBox="0 0 595.5 383.75" preserveAspectRatio="xMinYMin slice">
  </svg>
</div>
.wrap svg {
  width:  100%;
  height: 100%;
  position: absolute;
}

.wrap {
    height: 100%;
    display: grid;
}

CyberT33N
  • 78
  • 5