9

Прочитал эти статьи по теории масок, но не уверен, что понял всё правильно

https://developer.mozilla.org/en-US/docs/Web/SVG/Element/mask
http://css.yoksel.ru/svg-masks/

Вот пример по маскам, пробую изменять параметры, хочется понять основные закономерности, чтобы в будущем уверенно применять svg маски.

<style>
.container {
width:50%;
height:50%;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
        viewBox="0 0 600 800" preserveAspectRatio="xMinYMin meet" style="border:1px solid red;" >  
 <defs>
  <mask id="msk1">
    <rect width="100%" height="100%" fill="red" />
 <g fill="white">
       <!-- Left eye --> 
    <circle cx="400" cy="350" r="90"  />
    <!-- Right eye -->
   <circle cx="200" cy="350" r="90"  />
    </g> 
 </mask>
 </defs>

<image xlink:href="https://i.stack.imgur.com/WHYc7.jpg" width="100%" height="100%" mask="url(#msk1)" /> </svg>
</div>

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384
  • если это перевод вопроса с en.so, то нелишним будет вставить ссылку на оригинал – Alex Dec 12 '18 at 18:34
  • 1
    @Alex нет, это моя собственная статья, которую я написал сегодня :)))) – Alexandr_TT Dec 12 '18 at 18:36
  • 1
    понятно) вопрос и ответ опубликованы в одно время, поэтому возникла мысль, что это перевод – Alex Dec 12 '18 at 18:39

2 Answers2

9

Примеры использования маски

Немного теории плюс примеры и можно сформулировать простые правила, которые будут помогать в освоении и практическом применении масок.

Можно представить маску в виде 2D объекта, например лист любого материала, который расположен между нашими глазами и объектом наблюдения. В листе будут вырезаться отверстия, форма которых задаются элементами svg между тегами <mask>

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

  1. Если маска полностью непрозрачна fill="black" мы ничего не увидим.

<style>
.container {
width:50%;
height:50%;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
        viewBox="0 0 600 800" preserveAspectRatio="xMinYMin meet" style="border:1px solid red;" >  
 <defs>
  <mask id="msk1">
    <g fill="black">
       <!-- Left eye --> 
    <circle cx="400" cy="350" r="90"  />
    <!-- Right eye -->
   <circle cx="200" cy="350" r="90"  />
    </g> 
 </mask>
 </defs>

<image xlink:href="https://i.stack.imgur.com/WHYc7.jpg" width="100%" height="100%" mask="url(#msk1)" /> </svg>
</div>

  1. Маска имеет форму двух окружностей, которые полностью прозрачны,- fill="white"
    Видим после применения маски, вырезанные части объекта, как они есть на оригинальном изображении.

<style>
.container {
width:50%;
height:50%;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
        viewBox="0 0 600 800" preserveAspectRatio="xMinYMin meet" style="border:1px solid red;" >  
 <defs>
  <mask id="msk1">
   <g fill="white">
   <!-- Left eye --> 
 <circle cx="400" cy="350" r="90"  />
   <!-- Right eye -->
  <circle cx="200" cy="350" r="90"  />
 </g> 
   </mask>
 </defs>

<image xlink:href="https://i.stack.imgur.com/WHYc7.jpg" width="100%" height="100%" mask="url(#msk1)" /> </svg>
</div>

  1. Цвет заполнения маски находится между чёрным и белым цветом, то есть прозрачность маски будет между 0 и 1

На примере часть маски для левого глаза fill="gray" для правого fill="red"

<style>
.container {
width:50%;
height:50%;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
        viewBox="0 0 600 800" preserveAspectRatio="xMinYMin meet" style="border:1px solid red;" >  
 <defs>
  <mask id="msk1">
   <g >
   <!-- Left eye --> 
 <circle cx="400" cy="350" r="90" fill="gray"  />
   <!-- Right eye -->
  <circle cx="200" cy="350" r="90" fill="red" />
 </g> 
   </mask>
 </defs>

<image xlink:href="https://i.stack.imgur.com/WHYc7.jpg" width="100%" height="100%" mask="url(#msk1)" /> </svg>
</div>

Обработка фона вне маски

Для этой цели в теги <mask> добавляется прямоугольник занимающий всё пространство маскируемого объекта

<rect width="100%" height="100%" fill="white" />

Принцип тот же,- для фона вне маски, если fill="white" этот участок останется неизменным. В итоге фон как есть, а зона действия маски зависит от прозрачности, то есть от выбора цвета заливки. Для маски,- это глаза fill="black" становятся непрозрачными.

<style>
.container {
width:50%;
height:50%;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
        viewBox="0 0 600 800" preserveAspectRatio="xMinYMin meet" style="border:1px solid red;" >  
 <defs>
  <mask id="msk1">
    <rect width="100%" height="100%" fill="white" />
 <g fill="black">
       <!-- Left eye --> 
    <circle cx="400" cy="350" r="90"  />
    <!-- Right eye -->
   <circle cx="200" cy="350" r="90"  />
    </g> 
 </mask>
 </defs>

<image xlink:href="https://i.stack.imgur.com/WHYc7.jpg" width="100%" height="100%" mask="url(#msk1)" /> </svg>
</div>

Теперь фон непрозрачный fill="black" маска fill="white"

В этой комбинации маска работает, как clipPath

<style>
.container {
width:50%;
height:50%;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
        viewBox="0 0 600 800" preserveAspectRatio="xMinYMin meet" style="border:1px solid red;" >  
 <defs>
  <mask id="msk1">
    <rect width="100%" height="100%" fill="black" />
 <g fill="white">
       <!-- Left eye --> 
    <circle cx="400" cy="350" r="90"  />
    <!-- Right eye -->
   <circle cx="200" cy="350" r="90"  />
    </g> 
 </mask>
 </defs>

<image xlink:href="https://i.stack.imgur.com/WHYc7.jpg" width="100%" height="100%" mask="url(#msk1)" /> </svg>
</div>

Фон полупрозрачный fill="red" маска прозрачна fill="white"

<style>
.container {
width:50%;
height:50%;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
        viewBox="0 0 600 800" preserveAspectRatio="xMinYMin meet" >  
 <defs>
  <mask id="msk1">
    <rect width="100%" height="100%" fill="red" />
 <g fill="white">
       <!-- Left eye --> 
    <circle cx="400" cy="350" r="90"  />
    <!-- Right eye -->
   <circle cx="200" cy="350" r="90"  />
    </g> 
 </mask>
 </defs>

<image xlink:href="https://i.stack.imgur.com/WHYc7.jpg" width="100%" height="100%" mask="url(#msk1)" /> </svg>
</div>

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384
4

Примеры с подключением прозрачности stroke

У базовых элементов SVG: line; polyline, polygon, rect,circle',ellipse,'path

  • есть атрибут - stroke-width задавая ширину и прозрачность которого, можно ещё расширить возможности маски.

  • также представляет интерес использование stroke-dasharray и stroke-dashoffset

    #1
    <circle cx="500" cy="300" r="250" fill="#5F5F5F" stroke-width="250" stroke="white"

    Окружность полупрозрачна, широкая строка прозрачна

<style>
.container {
width:50%;
height:50%;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
        viewBox="0 0 1000 667" preserveAspectRatio="xMinYMin meet"  >  
 <defs>
  <mask id="msk1">
    <rect width="100%" height="100%" fill="red" stroke-width="1" stroke="white" />
&lt;circle cx="500" cy="300" r="250" fill="#5F5F5F" stroke-width="250" stroke="white"  /&gt;

</mask> </defs> <image xlink:href="https://i.stack.imgur.com/OWG1v.jpg" width="100%" height="100%" mask="url(#msk1)" /> </svg>
</div>

#2

Несколько окружностей
Центр - окружность с самым малым радиусом сделан наиболее прозрачным по сравнению с внешними окружностями

<circle cx="500" cy="300" r="100" fill="#5F5F5F" stroke-width="25" stroke="white" />

<style>
.container {
width:50%;
height:50%;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
        viewBox="0 0 1000 667" preserveAspectRatio="xMinYMin meet"  >  
 <defs>
  <mask id="msk1">
    <rect width="100%" height="100%" fill="red"
      stroke-width="1" stroke="white" />
&lt;circle cx="500" cy="300" r="250" fill="#5F5F5F"
   stroke- width="25" stroke="white" /&gt;
&lt;circle cx="500" cy="300" r="200" fill="#5F5F5F"
   stroke-width="25" stroke="white" /&gt;
 &lt;circle cx="500" cy="300" r="150" fill="#5F5F5F" 
   stroke-width="25" stroke="white" /&gt;
 &lt;circle cx="500" cy="300" r="100" fill="#C7C7C7"
  stroke-width="25" stroke="white" /&gt;   

</mask> </defs>

<image xlink:href="https://i.stack.imgur.com/OWG1v.jpg" width="100%" height="100%" mask="url(#msk1)" /> </svg>
</div>

#3

<style>
.container {
width:50%;
height:50%;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
        viewBox="0 0 2110 1410" preserveAspectRatio="xMinYMin meet"  >  
 <defs>
  <mask id="msk1">
    <rect width="100%" height="100%" fill="red" stroke-width="1"  />
  <circle cx="1250" cy="1000" r="290" fill="#979797" stroke-width="70" stroke="white"  />
 </mask>
</defs>

<image xlink:href="https://i.stack.imgur.com/npNcn.jpg" width="100%" height="100%" mask="url(#msk1)" /> </svg>
</div>

#4

Использование stroke-dasharray

Делим окружность на 6 равных сегментов, у которых длина черты - 250px, пробел - 64px

<circle cx="1200" cy="850" r="300" fill="red" stroke-width="200" stroke="white" stroke-dasharray="250 64" />


<style> .container { width:50%; height:50%; } </style> <div class="container"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 2110 1410" preserveAspectRatio="xMinYMin meet" >
<defs> <mask id="msk1"> <rect width="100%" height="100%" fill="red" stroke-width="1" stroke="white" /> <circle cx="1200" cy="850" r="300" fill="red" stroke-width="200" stroke="white" stroke-dasharray="250 64" />

</mask> </defs>

<image xlink:href="https://i.stack.imgur.com/npNcn.jpg" width="100%" height="100%" mask="url(#msk1)" /> </svg>
</div>

#5

Ещё пример с stroke-dasharray и очень широкой строкой - stroke-width="400"

<style>
.container {
width:50%;
height:50%;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
        viewBox="0 0 1000 667" preserveAspectRatio="xMinYMin meet"  >  
 <defs>
  <mask id="msk1">
    <rect width="100%" height="100%" fill="red" stroke-width="1" stroke="white" />
    <circle cx="500" cy="300" r="300" fill="#5F5F5F" stroke-width="400" stroke="white" stroke-dasharray="25 64" />

</mask> </defs>

<image xlink:href="https://i.stack.imgur.com/OWG1v.jpg" width="100%" height="100%" mask="url(#msk1)" /> </svg>
</div>

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384