Почему не работает svg mask?

Необходимо вырезать по форме path

 <svg width="100" height="100" viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
            <mask id="p" maskContentUnits="objectBoundingBox">
                <path d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path>
            </mask>
            <image mask="url(#p)" href="img.png" width="100" height="100" preserveAspectRatio="xMidYMid slice"></image>
    </svg>


Ответы (2 шт):

Автор решения: Alexandr_TT
  • Во-первых нужно привести в соответствие размеры viewBox="0 0 100 100" При этих значениях он будет захватывать размер холста SVG 100х100px

  • <path d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path> - 'это сектор, который укладывается в размеры меньшие одного пикселя. Поэтому, без преобразований вы его вряд ли увидите. Нужно либо его увеличить, либо уменьшить viewBox, чтобы они соответствовали друг другу.

Выбираю вариант viewBox="0 0 1 1"

Вот так выглядит форма маски:

<svg width="100" height="100" viewbox="0 0 1 1" xmlns="http://www.w3.org/2000/svg">
   <path fill="red" d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path>
</svg>

Теперь есть два варианта работы маски:

  1. Вырезать по форме маски: fill="white" остальное, что вне формы маски отбрасывается
    Такой режим соответствует работе clipPath:

Исходное изображение:

введите сюда описание изображения

  1. Вырезаем

<svg width="100" height="100" viewbox="0 0 1 1" xmlns="http://www.w3.org/2000/svg" >
        <mask  id="p"  maskContentUnits="objectBoundingBox"> 
                <path fill="white"  d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path>
        </mask>
        <image mask="url(#p)"  href="https://i.stack.imgur.com/JVNrx.jpg" width="100%" height="100%" ></image>
        </svg>

  1. Вырезать отверстие по форме path и показать, что находится вне его

То же интересный вариант. Можно увидеть фон или вторую картинку, которая находится под верхней картинкой, к которой применен фон Подробнее здесь

<svg width="100" height="100" viewbox="0 0 1 1" xmlns="http://www.w3.org/2000/svg" >  
        
        <mask  id="p"  maskContentUnits="objectBoundingBox">  
            <rect width="100%" height="100%" fill="white" />
                <path fill="blue"  d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path>
        </mask>
        <image mask="url(#p)"  href="https://i.stack.imgur.com/JVNrx.jpg" width="100%" height="100%" ></image>
        </svg>

Update

Если нужен адаптивный вариант, то указывается в процентах width height в шапке SVG

<svg width="100%" height="100%" viewbox="0 0 1 1" xmlns="http://www.w3.org/2000/svg" >
        <mask  id="p"  maskContentUnits="objectBoundingBox"> 
                <path fill="white"  d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path>
        </mask>
        <image mask="url(#p)"  href="https://i.stack.imgur.com/JVNrx.jpg" width="100%" height="100%" ></image>
        </svg>

Или оборачиваете SVG в родительский контейнер и задаете его размеры в относительных координатах

.container {
width:75vw;
height:auto;
}
<div class="container">
<svg  viewbox="0 0 1 1" xmlns="http://www.w3.org/2000/svg" >
        <mask  id="p"  maskContentUnits="objectBoundingBox"> 
                <path fill="white"  d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path>
        </mask>
        <image mask="url(#p)"  href="https://i.stack.imgur.com/JVNrx.jpg" width="100%" height="100%" ></image>
        </svg>
 </div>   

→ Ссылка
Автор решения: Alexandr_TT

Работа маски с двумя изображениями

Нижнее изображение будет абстрактный узор

введите сюда описание изображения

Верхнее изображение, к которому будет применяться маска

введите сюда описание изображения

  • При <path fill="black" d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path>

    Верхнее изображение с ромашками прорезается и становится видимым через это отверстие нижнее абстрактное изображение

<svg width="100%" height="100%" viewbox="0 0 1 1" xmlns="http://www.w3.org/2000/svg" >  
        
        <mask  id="p"  maskContentUnits="objectBoundingBox">  
            <rect width="100%" height="100%" fill="white" />
                <path fill="black"  d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path>
        </mask>   
        
               <!-- Абстрактный узор -->
        <image   href="https://i.stack.imgur.com/JVNrx.jpg" width="100%" height="100%" ></image>
           <!-- Ромашки -->
        <image mask="url(#p)" href="https://i.stack.imgur.com/3KF4L.jpg" width="100%" height="100%" ></image>
        </svg>

<rect width="100%" height="100%" fill="black" />
    <path fill="white"  d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path>

Верхнее изображение (ромашки) при fill="white" остается нетронутым по форме маски, а остальное, что не вошло в маску вырезается и становится видимым нижнее абстрактное изображение fill="black" у <rect

<svg width="100%" height="100%" viewbox="0 0 1 1" xmlns="http://www.w3.org/2000/svg" >  
        
        <mask  id="p"  maskContentUnits="objectBoundingBox">  
            <rect width="100%" height="100%" fill="black" />
                 <path fill="white"  d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path> 
        </mask>   
        
               <!-- Абстрактный узор  -->
        <image   href="https://i.stack.imgur.com/JVNrx.jpg" width="100%" height="100%" ></image>
           <!-- Ромашки -->
        <image mask="url(#p)" href="https://i.stack.imgur.com/3KF4L.jpg" width="100%" height="100%" ></image>
        </svg>

При fill="red" маска становится полупрозрачной

<svg width="100%" height="100%" viewbox="0 0 1 1" xmlns="http://www.w3.org/2000/svg" >  
        
        <mask  id="p"  maskContentUnits="objectBoundingBox">  
            <rect width="100%" height="100%" fill="red" />
                 <path fill="red"  d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path>
        </mask>   
        
               <!-- Абстрактный узор  -->
        <image   href="https://i.stack.imgur.com/JVNrx.jpg" width="100%" height="100%" ></image>
           <!-- Ромашки -->
        <image mask="url(#p)" href="https://i.stack.imgur.com/3KF4L.jpg" width="100%" height="100%" ></image>
        </svg>

  • При добавлении в маску строки с окраской в белый цвет, появляются новые возможности
  <path fill="red" stroke="white" stroke-width="0.035" 
    d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path>

<svg width="100%" height="100%" viewbox="0 0 1 1" xmlns="http://www.w3.org/2000/svg" >  
        
        <mask  id="p"  maskContentUnits="objectBoundingBox">  
            <rect width="100%" height="100%" fill="red" />
                 <path fill="red" stroke="white" stroke-width="0.035" d="M.5,0 A.5,.5 0 1 0 1,.5 L.5,.5 L.5,-.1"></path>
        </mask>   
        
               <!-- Абстрактный узор  -->
        <image   href="https://i.stack.imgur.com/JVNrx.jpg" width="100%" height="100%" ></image>
           <!-- Ромашки -->
        <image mask="url(#p)" href="https://i.stack.imgur.com/3KF4L.jpg" width="100%" height="100%" ></image>
        </svg>

→ Ссылка