Using an SVG Filter to Create an Internal Beat

I would like to simulate the "inner move" on the svg path. I have an svg card with several complex paths (countries), each with a different fill color. And I would like to add a “fake internal move” in the first. I managed to do a few things with a shadow trick (with a Gaussian blur filter), but it cannot have it as “not blurred”.

An ideal solution would be like an svg filter, so I can apply it dynamically through JS without changing the path or manipulating dom.

Thank you so much! Edit 1: While I tried this trick, but the fake shadow is sometimes stroke-like and always blurry, so I'm not sure even the best way ...

  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="150" height="150" style="transform:scale(2);transform-origin:0 0 ">
     <defs>
  <filter id='inset' x='-50%' y='-50%' width='200%' height='200%'>
  
    <feFlood fill-color="black"/>
    <feComposite in2="SourceAlpha" operator="out"/>
    
    <feGaussianBlur stdDeviation='10' edgeMode="none" />
    <feOffset dx='0' dy='0' result='offsetblur'/>
    <feFlood flood-color='#00ff00' result='color'/>
    <feComposite in2='offsetblur' operator='in'/>
    <feComposite in2='SourceAlpha' operator='in' />
    <feMerge>
      <feMergeNode in='SourceGraphic'/>
        <feMergeNode/>
    </feMerge>
  </filter> 
       
	</defs>
  
<path class="st0" d="M144.7,126.2l-2.8,8.8l-3.9-2.3l-2-7.7l1.7-4.3l5.5-4.4L144.7,126.2z M93.5,24.2l6,6.3l4.4-1l7.5,6l1.9,1.1
	l2.5-0.3l4,3.4l12.3,2.4l-4.3,8.9l-1.1,9.1l-2.4,2.2l-3.9-1.2l0.3,3.2l-6.3,7l-0.1,5.6l4.1-1.9l2.9,5.4L121,84l2.5,4.6l-3,3.7
	l2.2,9.3l4.6,1.5l-1,5.1l-7.8,6.6l-16.9-3.2l-12.5,3.8l-1,7l-9.9,1.5l-9.6-5.3l-3.1,2.5l-15.8-5.3l-3.4-4.6l4.4-7.1l1.6-24.1
	l-8.8-13l-6.3-6.4l-13.1-4.9l-0.9-9.4l11.1-2.8L48.9,47l-2.7-14.8l8.1,5.7l20-10.3l2.6-11l7.5-2.8l1.3,4.8l4,0.2L93.5,24.2z" stroke-width="1" fill="#00ffff"  stroke="#FF0000" filter="url(#inset)"/>
</svg>
Run codeHide result
+4
2

, SVG- CSS- svg.

" ", feMorphorogy . ( ) , " /" .

<svg xmlns="http://www.w3.org/2000/svg" 
  xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="300">
  <defs>
    <filter id='inset' x='-50%' y='-50%' width='200%' height='200%'>
      <!--outside-stroke-->
      <feFlood flood-color="red" result="outside-color"/>
      <feMorphology in="SourceAlpha" operator="dilate" radius="2"/>
      <feComposite in="outside-color" operator="in" result="outside-stroke"/>
      <!--inside-stroke-->
      <feFlood flood-color="blue" result="inside-color"/>
      <feComposite in2="SourceAlpha" operator="in" result="inside-stroke"/>
      <!--fill-area-->
      <feMorphology in="SourceAlpha" operator="erode" radius="2"/>
      <feComposite in="SourceGraphic" operator="in" result="fill-area"/>
      <!--merge graphics-->
      <feMerge>
        <feMergeNode in="outside-stroke"/>
        <feMergeNode in="inside-stroke"/>
        <feMergeNode in="fill-area"/>
      </feMerge>
    </filter>
  </defs>
  <g transform="scale(2)">
    <path class="st0" d="M144.7,126.2l-2.8,8.8l-3.9-2.3l-2-7.7l1.7-4.3l5.5-4.4L144.7,126.2z M93.5,24.2l6,6.3l4.4-1l7.5,6l1.9,1.1
  l2.5-0.3l4,3.4l12.3,2.4l-4.3,8.9l-1.1,9.1l-2.4,2.2l-3.9-1.2l0.3,3.2l-6.3,7l-0.1,5.6l4.1-1.9l2.9,5.4L121,84l2.5,4.6l-3,3.7
  l2.2,9.3l4.6,1.5l-1,5.1l-7.8,6.6l-16.9-3.2l-12.5,3.8l-1,7l-9.9,1.5l-9.6-5.3l-3.1,2.5l-15.8-5.3l-3.4-4.6l4.4-7.1l1.6-24.1
  l-8.8-13l-6.3-6.4l-13.1-4.9l-0.9-9.4l11.1-2.8L48.9,47l-2.7-14.8l8.1,5.7l20-10.3l2.6-11l7.5-2.8l1.3,4.8l4,0.2L93.5,24.2z"
fill="#00ffff" filter="url(#inset)"/>
  </g>
</svg>
Hide result
+2

, . , , , ( 100% - , , ).

"" , feColorMatrix. , 100% . ( feMorphology - def-, - .)

  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="150" height="150" style="transform:scale(2);transform-origin:0 0 ">
     <defs>
  <filter id='fake-stroke' x='-50%' y='-50%' width='200%' height='200%' color-interpolation-filters="sRGB">
  
   <!-- select just the red outline and zero out the opacity of everything that not 100% red. -->
   <feColorMatrix type="matrix" values="1 0 0 0 0 
                                        0 0 0 0 0 
                                        0 0 0 0 0 
                                        255 -255 -255 -254 0" result="outline-only"/>
    <feGaussianBlur stdDeviation="1"/>

   <!-- select just the blur - not the original stroke. -->
    <feComposite operator="out" in2="outline-only"/>

   <!-- select just the blur that overlaps the original content -->
    <feComposite operator="in" in2="SourceGraphic" />

   <!-- increase its opacity to 100% except the most blurred - to fake anti-aliasing -->
    <feComponentTransfer>
      <feFuncA type="table" tableValues="0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"/>
    </feComponentTransfer>

   <!-- change the color of the fake stroke to the desired value -->
    <feColorMatrix type="matrix" values ="0 0 0 0 0
                                          0 0 0 0 0
                                          0 0 0 0 1 
                                          0 0 0 1 0"/>
   <!-- put it on top of the original -->
    <feComposite operator="over" in2="SourceGraphic"/>

  </filter> 
       
	</defs>
  
<path class="st0" d="M144.7,126.2l-2.8,8.8l-3.9-2.3l-2-7.7l1.7-4.3l5.5-4.4L144.7,126.2z M93.5,24.2l6,6.3l4.4-1l7.5,6l1.9,1.1
	l2.5-0.3l4,3.4l12.3,2.4l-4.3,8.9l-1.1,9.1l-2.4,2.2l-3.9-1.2l0.3,3.2l-6.3,7l-0.1,5.6l4.1-1.9l2.9,5.4L121,84l2.5,4.6l-3,3.7
	l2.2,9.3l4.6,1.5l-1,5.1l-7.8,6.6l-16.9-3.2l-12.5,3.8l-1,7l-9.9,1.5l-9.6-5.3l-3.1,2.5l-15.8-5.3l-3.4-4.6l4.4-7.1l1.6-24.1
	l-8.8-13l-6.3-6.4l-13.1-4.9l-0.9-9.4l11.1-2.8L48.9,47l-2.7-14.8l8.1,5.7l20-10.3l2.6-11l7.5-2.8l1.3,4.8l4,0.2L93.5,24.2z" stroke-width="2" fill="#00ffff"  stroke="#FF0000" filter="url(#fake-stroke)"/>
</svg>
Hide result
+3

Source: https://habr.com/ru/post/1670767/


All Articles