Home > Net >  Can I style individual dashes in an SVG path?
Can I style individual dashes in an SVG path?

Time:01-24

enter image description here

Can I style dashes in my SVG path, so that each of them would be slightly irregular? As in the image above?

Tried looking for a CSS-only solution. But adding individual elements along the path would work as well

CodePudding user response:

You can make them irregular with a displacement map (see below), or you can find a font with a glyph that you can use and use text along a textPath with that font to make it look like a customized dash. But you can't style each individual dash in a normal path.

<svg width="600px" height="400px">
  
  <filter id="custom-stroke">

    <feTurbulence baseFrequency= "0.02" type="turbulence" numOctaves="2"/>
    <feDisplacementMap in="SourceGraphic" xChannelSelector="R" yChannelSelector="G" scale="15"/>
    <feMorphology operator="erode" radius="1"/>
    <feMorphology operator="dilate" radius="1" />
    
    <feGaussianBlur stdDeviation="1.5" />
      <feColorMatrix type="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 11 -7" result="goo" />
  </filter>
  
  
  <g filter="url(#custom-stroke)">
  <path fill="none" stroke="blue" stroke-dasharray="10 10" stroke-width="8" d="M 10 10 a 100 80 0 0 1 100 40  200 300 0 0 0 200 100"/>
  </g>
</svg>

CodePudding user response:

<animateMotion rotate="auto"> rotates an SVG element on a <path>

I took my yesterdays answer (see that SO answer for explanation),
simplified it, added Michael his filter, and dabbled a bit with the filter settings.

Question for the SVG experts: Can we get that rotate="auto" value for each "marker" with JS?
If so, each "marker" could be customized to make it "curve" better


JSFiddle: https://jsfiddle.net/WebComponents/7muns9La/

<svg-path-markers count="25" filter>
  <svg viewBox="0 0 500 300" style="background:pink;max-height:180px">
    <defs><g id="marker"><path fill="green" d="m0 -10q29 4 0 10a8 7 90 110-10z"/></g></defs>
    <filter id="F">
      <feTurbulence baseFrequency= "0.001" type="turbulence" numOctaves="1"/>
      <feDisplacementMap in="SourceGraphic" xChannelSelector="R" yChannelSelector="G" scale="15"/>
      <feMorphology operator="erode" radius=".1"/><feMorphology operator="dilate" radius=".1" />
      <feGaussianBlur stdDeviation="1"/><feColorMatrix type="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 11 -7"/>
    </filter>    
    <path fill="none" stroke="black" d="m50 20a10 10 90 00230 100c30-140-160 0-90 120 30 50 370 40 260-60" />
    <g id="markers"/>
  </svg>
</svg-path-markers>
<script>
  customElements.define("svg-path-markers", class extends HTMLElement {
    connectedCallback() {
      setTimeout(() => { // wait till innerHTML is parsed
        this.querySelectorAll("path").forEach( path => {
          let duration = "2"; // set to 0.00001 for instant display
          let count = ~~this.getAttribute("count");
          let filter = this.hasAttribute("filter") ? 'filter="url(#F)"' : '';
          let id = path.id || (path.id = this.localName   Math.random()*1e9);
          let marker = dist => 
            `<use href="#marker" ${filter}>
              <animateMotion dur="${duration}" fill="freeze"calcMode="linear" 
                             rotate="auto" keyPoints="0;${dist}" keyTimes="0;1">
                <mpath href="#${id}"/></animateMotion></use>`;
          this.querySelector("#markers").innerHTML =Array(count).fill(0)
                                        .map((_,i) => marker(i*(1/(count-1)))).join("");
        } )
      })}})
</script>

  • Related