Reputation: 1
I have a task - create an ability to fill SVG paths with PNG image and scale up and down this image to create a certain texture.
One solution is to create a pattern with image and fill paths with that pattern, and then scale image by css transform: scale(0.7). Image will scale ok, but this solution depends on image dimension - e.g for SVG 1000x1000px with path ~ 800x500px, image 1000x1000 will not cover all path space for scale 0.5.
Here is some code example with another solution I found:
<svg width="1000" height="1000" viewBox="0 0 1000 1000">
<defs>
<pattern id="patternImg" height="100%" width="100%" x="0" y="0" preserveAspectRatio="none" patternUnits="objectBoundingBox" viewBox="0 0 1000 1000">
<image preserveAspectRatio="none" xlink:href="data:image/....." x="0" y="0" width="100%" height="100%" style="transform: scale(0.7);/>
</pattern>
</defs>
<path d="....." fill="url(#patternImg)" stroke="black"/>
<path d="....." fill="url(#patternImg)" stroke="black"/>
</svg>
In this case PNG image will fully fit into paths within viewBox 1000x1000, the more dimension, the smaller scaling, and then I can scale up to have bigger size. But the issue with such approach is that paths can have different width/height, and applying viewBox="0 0 1000 1000" to all of them will stretch/compress image.
What is the proper solution to solve such tasks?
Note, that it's not possible to create pattern image by myself, e.g using <rect> and then repeat it. It's important to use a specific images.
Upvotes: 0
Views: 55
Reputation: 29
Use patternUnits="objectBoundingBox" with aspect ratio control.Pattern uses meet (contain behavior) Image uses slice (cover behavior) Remove CSS scaling - handle via pattern/image dimensions.
<defs>
<pattern id="texPattern"
patternUnits="objectBoundingBox"
width="1" height="1"
preserveAspectRatio="xMidYMid meet">
<image xlink:href="image.png"
width="1" height="1"
preserveAspectRatio="xMidYMid slice"/>
</pattern>
</defs>
<path fill="url(#texPattern)" d="..."/>
</svg>```
Upvotes: 1