Maria
Maria

Reputation: 1

How to scale a PNG image in SVG pattern properly

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

Answers (1)

Shahzad Umar
Shahzad Umar

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

Related Questions