Несколько полигональных элементов SVG clipPpath не работают, потому что xor

Это первый раз, когда я использую SVG, чтобы сделать прозрачные области на картинке (отмечены красным), и, вероятно, у меня очень наивный вопрос, я написал этот код в соответствии с этим ответом, и все элементы закрыты />, как указано в этом ответ. Проблема в том, что это не работает, потому что с моими точками элементы многоугольника работают как «исключающее ИЛИ», как можно сделать элементы многоугольника «И»?

<img src = "https://i.stack.imgur.com/iZ7xG.jpg" style = "clip-path: url(#myClip);">

<svg width = "0" height = "0" xmlns = "http://www.w3.org/2000/svg">
  <defs>
    <clipPath id = "myClip"  clipPathUnits = "objectBoundingBox">
      <polygon points = "0 0, 0 1, .54 .99, .5682 .156, .746 .151, .7397 .557, .51 .508, .54 .99, 1 1, 1 0" />
      <polygon points = "0 0, 0 1, .737 1, .747 .321, .816 .321, .81 .666, .74 .645, .74 1, 1 1, 1 0" />
      /*  It doesn't work, but if delete one of them so its work with only one polygon */
    </clipPath>
  </defs>
</svg>
Создание фильтров для вашего сайта
Создание фильтров для вашего сайта
Фильтры - удобный инструмент в арсенале веб-дизайнера. Они позволяют изменять элементы на странице с помощью всего нескольких строк кода. Эти...
Анимация SVG-узоров без единой строки CSS
Анимация SVG-узоров без единой строки CSS
Недавно я работал над веб-проектом, который позволил мне поэкспериментировать с шаблонами SVG. С SVG очень приятно работать, как только вы получите...
Как использовать d3.js для рисования 2D SVG-элементов в приложении Angular?
Как использовать d3.js для рисования 2D SVG-элементов в приложении Angular?
D3.js - это обширная библиотека, используемая для привязки произвольных данных к объектной модели документа (DOM). Мы разберем основные варианты...
1
0
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Не очень удивительно, что это не работает. Вы пытаетесь сделать «обратные» пути клипа. Пути обрезки скрывают все, что находится за пределами их формы. но вы хотите скрыть только то, что находится внутри фигуры. Для этого вы рисуете тор, состоящий из ограничивающей рамки и вашей формы, а затем разрезаете линию, чтобы получился один непрерывный многоугольник.

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

В зависимости от того, как формируются ваши многоугольники, области, которые вы хотите скрыть, находятся внутри одной формы и снаружи другой. Соответственно, они остаются видимыми.

В этом случае гораздо проще использовать маску. Он работает, раскрашивая фигуры. Все белое (яркость = 1) отображается, все черное (яркость = 0) скрыто.

<img src = "https://i.stack.imgur.com/iZ7xG.jpg" style = "mask: url(#myMask);">

<svg width = "0" height = "0" xmlns = "http://www.w3.org/2000/svg">
  <defs>
    <mask id = "myMask"  maskContentUnits = "objectBoundingBox">
      <!--white surrounding rectangle: visible-->
      <rect width = "1" height = "1" fill = "white" />
      <!-- black cutout shapes: hidden -->
      <polygon points = ".556 .518, .5682 .156, .746 .151, .7397 .557" fill = "black" />
      <polygon points = ".747 .321, .816 .321, .81 .666, .74 .645" fill = "black" />
    </mask>
  </defs>
</svg>

Спасибо, понятно. Но, кажется, ваш код не работает.

Sevi 09.10.2022 08:16
Ответ принят как подходящий

Вы также можете использовать составной путь с чередующимися направлениями пути.
Как описано здесь: Порядок намотки правила заполнения

<path> будет содержать 3 супата:

M 0 0 ,0 1, 1 1, 1 0 z внешний прямоугольник: нарисован против часовой стрелки
M .747 .321 L .816 .321 L .81 .666 L .74 .645z 1-я форма экрана: рисуется по часовой стрелке
M 0.56 0.508 L 0.5682 0.156 L 0.746 0.151 L 0.7397 0.557 z 2-я форма экрана: рисуется по часовой стрелке

Вы можете легко преобразовать <polygon>points в <path>d команды, добавив команду M к значениям points и добавив z (для закрытия пути). См. также: «Преобразовать полигон SVG в путь»

Пример: несколько полигонов против составного пути

body{
  background:#999;
}

img, svg{
  width:25%;
}
<img src = "https://i.stack.imgur.com/iZ7xG.jpg" style = "clip-path: url(#myClipPoly1); ">
<img src = "https://i.stack.imgur.com/iZ7xG.jpg" style = "clip-path: url(#myClipPoly2); ">
<img src = "https://i.stack.imgur.com/iZ7xG.jpg" style = "clip-path: url(#myClipCompoundPath); ">


<svg width = "0" height = "0" xmlns = "http://www.w3.org/2000/svg">
  <defs>
    <clipPath id = "myClipPoly1"  clipPathUnits = "objectBoundingBox" >
      <polygon id = "poly1" points = ".747 .321 , .816 .321 , .81 .666 , .74 .64" />
      <polygon id = "poly2" points = "0.56 0.508 , 0.5682 0.156 , 0.746 0.151 , 0.7397 0.557"  />
    </clipPath>
    <clipPath id = "myClipPoly2"  clipPathUnits = "objectBoundingBox" >
      <polygon id = "outerRect" points = "0 0 , 1 0, 1 1, 0 1"  />
      <polygon id = "poly1" points = ".747 .321 , .816 .321 , .81 .666 , .74 .64" />
      <polygon id = "poly2" points = "0.56 0.508 , 0.5682 0.156 , 0.746 0.151 , 0.7397 0.557"  />
    </clipPath>
    
    <clipPath id = "myClipCompoundPath"  clipPathUnits = "objectBoundingBox" >
      <path d = "
      M 0 0 ,0 1, 1 1, 1 0  z
      M  .747 .321 L .816 .321 L .81 .666 L .74 .645z
      M 0.56 0.508 L 0.5682 0.156 L 0.746 0.151 L 0.7397 0.557 z
      " />
    </clipPath>
  </defs>
</svg>

Как видите, во втором примере ничего не обрезается, так как обе области заполнения тора перекрываются.

Другие вопросы по теме