Подтвердить что ты не робот

Как я могу обрезать одну фигуру внутри другой?

Есть ли способ вырезать одну форму из другого в SVG? Например, у меня есть прямоугольник и эллипс, и я хочу сделать прямоугольник с прозрачным отверстием посередине. Я бы предположил, что это будет выглядеть примерно так:

<set operation="difference" fill="black">
    <rect x="10" y="10" width="50" height="50/>
    <ellipse cx="35" cy="35" rx=10 ry=10/>
</set>

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

Я просмотрел Inkscape и есть опция разницы в меню пути, но это преобразует фигуры в пути, а затем создает новый путь. Личность форм теряется, поэтому нет простого способа, например, зайти в файл svg и изменить радиус эллипса.

Есть ли идеи, как я могу это сделать?

4b9b3361

Ответ 1

Вы должны иметь возможность использовать свойство fill-rule: evenodd для достижения этого эффекта, если вы хотите предотвратить рисование заливки прямоугольника там, где находится круг. Посмотрите этот пример из спецификации SVG (изображение ниже будет отображаться, только если ваш браузер поддерживает SVG):

A pentagram and two circles, filled in red, with the centers cut showing the white background

По какой-то причине я не могу заставить это работать с такими фигурами, как rect и ellipse которые вы указали в вопросе. Вот моя попытка:

A blue square with a circle inside

Ответ 2

Вы должны использовать элемент пути, чтобы разрезать отверстие.

См. пример из спецификации SVG: (вы можете щелкнуть эту ссылку или следующее изображение, чтобы просмотреть реальный файл svg)

svg hole example

<g fill-rule="evenodd" fill="red" stroke="black" stroke-width="3">
    <path d="M 250,75 L 323,301 131,161 369,161 177,301 z"/>

    <path d="M 600,81 A 107,107 0 0,1 600,295 A 107,107 0 0,1 600,81 z
             M 600,139 A 49,49 0 0,1 600,237 A 49,49 0 0,1 600,139 z"/>

    <path d="M 950,81 A 107,107 0 0,1 950,295 A 107,107 0 0,1 950,81 z
             M 950,139 A 49,49 0 0,0 950,237 A 49,49 0 0,0 950,139 z"/>
</g>

В вашем случае:

<path d="M10 10h50v50h-50z M23 35a14 10 0 1 1 0 0.0001 z"
    stroke="blue" stroke-width="2" fill="red" fill-rule="evenodd" />

M10 10h50v50h-50z нарисует прямоугольник.

M25 35a10 10 0 1 1 0 0.0001 z будет рисовать эллипс.

fill-rule="evenodd" сделает отверстие.


Ключевым моментом является вытяжка наружной формы и внутренних форм (отверстий) в другом направлении (по часовой стрелке против против часовой стрелки).

  • Нарисуйте внешнюю форму по часовой стрелке и нарисуйте внутренние (отверстия) фигуры против часовой стрелки.
  • Или наоборот, нарисуйте внешнюю форму (отверстия) против часовой стрелки и нарисуйте внутренние фигуры по часовой стрелке.
  • Конкатентные данные о внешней форме и внутренних формах (отверстиях).

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

Это изображение объясняет, как вырезать отверстие:

Это изображение объясняет, как разрезать отверстие

См. документы w3c: Команды SVG Arc а также Свойство свойства заполнения SVG.

Ответ 3

Вам нужно использовать <path>, если вы хотите использовать fill-rule. Но, конечно, возможно изменить радиус круга, который является подпутью <path>, вам просто нужно освоить команду arc path.

Ответ 4

К сожалению, похоже, что нет никакого способа сделать это. Ни SVG 1.0, ни SVG 1.1 не поддерживают операции булевой формы, обрезание поддерживается по другим причинам. Самое близкое, что вы можете получить, это попытка получить "перевернутую" форму для обрезки.