Reputation: 1433
I have the following SVG:
<?xml version="1.0" encoding="UTF-8"?>
<svg width="480" height="1080" version="1.1" viewBox="0 0 480 1080" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="wpi" width="100%" height="100%" patternUnits="userSpaceOnUse">
<image width="100%" height="100%" preserveAspectRatio="none" xlink:href="h_img.jpg" x="0" y="0"/>
</pattern>
</defs>
<rect class="wallpaper" width="100%" height="250" fill="url(#wpi)"/>
</svg>
The h_img jpg might vary on time, loading different images, so I can't be aware of its size in advance, yet I know that, most of the time, its height value is greater than its width but I need to apply it to a rect element that has a smaller height compared to its own width and this is for sure (despite I'm using a relative 100% value for that one). I need the pattern to fill that rect with the image maintaining its aspect ratio and the height being crop (or hide overflow) centered. I know I can use JavaScript to calculate the image relative width, resize the height accordingly to maintain the aspect ratio and calculate the offset needed to provide the centering (and I did) but... Do you know maybe is there a way to do what I need simply using the right parameters on the SVG element and no JavaScript?
I tried with:
<pattern id="wpi" width="100%" height="100%" patternContentUnits="objectBoundingBox">
<image width="1" height="1" preserveAspectRatio="xMidYMid" xlink:href="h_img.jpg" x="0" y="0"/>
</pattern>
But that doesn't get me the desired effect I need... Thanks for your help
SOLVED EDIT:
Thanks to @ccprog for his suggestion took me on the right direction, I managed to find a way to solve like this:
<?xml version="1.0" encoding="UTF-8"?>
<svg width="480" height="1080" viewBox="0 0 480 1080" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<pattern id="wpi" width="1" height="1">
<image width="100%" height="250" preserveAspectRatio="xMidYMid slice" xlink:href="h_img.jpg"/>
</pattern>
</defs>
<rect class="wallpaper" width="100%" height="250" fill="url(#wpi)"/>
</svg>
Notice: you need to set for the <image>
just the same height
and width
values used for the pattern image container area (= that means the size of the element on which the pattern is going to be applied, in this case it's a <rect>
).
As final words I'll say there are at least a couple of reasons for I wanted the image to stay applied within a pattern:
one is that, in this way, I can be able to use javascript code to shift the centering of the image by y
and x
attributes values while letting the rectangle stay in its position;
and another reason is I could change the rectangle fill to a solid color easily if I need doing it.
Upvotes: 2
Views: 3096
Reputation: 21856
If you want to display an image once in a rectangular area, you do not need a pattern. Patterns are for repeating content more than once.
The attribute you were searching for is preserveAspectRatio="xMidYMid slice"
. See the spec.
<svg width="480" height="1080" viewBox="0 0 480 1080"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image class="wallpaper" width="100%" height="250"
preserveAspectRatio="xMidYMid slice" xlink:href="h_img.jpg"/>
</svg>
Upvotes: 3