Search code examples
htmlcssimagesvgemoji

Emoji character outline in SVG


I'm trying to create an outline of an emoji character (meaning I want to draw just the outer shape of the emoji) in SVG. The best I could come up with so far is to use two masked rectangles, scaled and super-imposed on each other.

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">  
  <defs>
    <filter id="filter">
      <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 1 0" />
    </filter>
    <mask id="mask" x="0" y="0" width="100" height="100">  
      <text filter="url(#filter)" x="0" y="80" font-family="Helvetica" font-weight="bold" font-size="7em" fill="#000000">🦄</text>
    </mask>  
  </defs>
  <path fill="#fff" d="M0 0 L0 100 L100 100 L100 0z"/>
  <path fill="#000000" d="M0 0 L0 100 L100 100 L100 0z" mask="url(#mask)"/>
  <g transform="translate(5, 5) scale(0.9)">
    <path d="M0 0 L100 0 L100 100 L0 100z" mask="url(#mask)" fill="#fff"/>
  </g>
</svg>

Depending on the particular emoji the result isn't very satisfactory though because not all emojis fill width and height equally.

rendered SVG

Is there a better way to achieve an outline effect for emoji characters?


Solution

    1. You need a viewBox for the svg element and I am using viewBox="0 -30 157 140" slightly bigger than the bounding box of the text element.

    2. instead of a mask I'm using clipPath to clip a white rectangle

    3. The filter I'm using is feMorphology operator="dilate" and I'm applying the filter to a group wrapping the clipped rectangle.

    svg{border:solid}
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" viewBox="0 -30 157 140">
    <defs>
    <filter id="outline-indigo">
    <feMorphology in="SourceAlpha" result="expanded"
    operator="dilate" radius="3"/>
    <feFlood flood-color="indigo" result="indi" />
    <feComposite in ="indi" in2="expanded" operator="in" />
    <feComposite in="SourceGraphic"/>
    </filter>
    
    <clipPath id='emojiClipPath'> 
          <text filter="url(#filter)" x="0" y="80" font-family="Helvetica" font-weight="bold" font-size="7em" fill="#000000">🦄</text>
    </clipPath>
    </defs>
      
    <g filter="url(#outline-indigo)">
      <rect y="-30" width="157" height="140" fill="white" clip-path='url(#emojiClipPath)'/>
    </g>
      
    </svg>