Search code examples
svgbezierweb-frontendtexture-mapping

How to add a texture to the stroke of a Bezier curve in an svg?


Not to fill a region bounded by a bezier curve and a line.

E.g. here's a very simple stroked Bezier curve

<?xml version="1.0" standalone="no"?>
<svg width="160" height="80" xmlns="http://www.w3.org/2000/svg" version="1.1">
    <polyline points="40 60 80 20 120 60" stroke="black" stroke-width="20"
        stroke-linecap="butt" fill="none" stroke-linejoin="miter"/>
</svg>

Then intuitively we would want to set the stroke attribute value from "black" to something like "./assets/62562367236.jpg". But it doesn't work this way.

<?xml version="1.0" standalone="no"?>
<svg width="160" height="80" xmlns="http://www.w3.org/2000/svg" version="1.1">
    <polyline points="40 60 80 20 120 60" stroke="https://media.freestocktextures.com/cache/0d/42/0d42eeb83ad3a56c97468d69721b2c18.jpg" stroke-width="20"
        stroke-linecap="butt" fill="none" stroke-linejoin="miter"/>
</svg>

Whereas practically what I'd want is something like what's depicted here:

enter image description here


Solution

  • As pointed out in the comment @Mike 'Pomax' Kamermans

    create a pattern definition with an id, then point to that by fragment identifier in the attribute

    I added the curve code and calculated the required dimensions for the pattern

    <style>
    .container {
    width:25vw;
    height:auto;
    }
    </style>
    <div class="container">
    <svg xmlns="http://www.w3.org/2000/svg"  viewBox="0 0 180 180">
          <defs>
            <pattern id="patt" patternUnits="userSpaceOnUse" width="170" height="170">
              <image href="https://media.freestocktextures.com/cache/0d/42/0d42eeb83ad3a56c97468d69721b2c18.jpg"
                     x="0" y="0" width="680" height="460" />
            </pattern>
          </defs>
           <path id="path" d="M25.21 135.78s55.95 5.97 81.76-14.4c38.26-30.2  31.7-76.72 31.7-76.72" 
           fill="none" stroke="url(#patt)" stroke-width="32"
             stroke-linecap="round" />
        </svg> 
    </div>