PerfectVector
Автор: Irene Kim8 мин чтения

Единицы SVG clipPath: вписывание фигуры под целевой объект

Выберите единицы SVG clipPath, нормализуйте силуэт и сохраните пропорции. Проверьте широкие и высокие целевые объекты, сохраняя отверстия и исходную геометрию.

На этой странице

Используйте clipPathUnits="objectBoundingBox", если фигура обрезки должна растягиваться вместе с границами цели. Сначала нормализуйте её координаты. Используйте userSpaceOnUse, если нужны явное размещение или равномерное масштабирование, сохраняющее пропорции фигуры.

Изменение одного атрибута не превращает контур, нарисованный в сотнях единиц, в фигуру между нулём и единицей. Оно может вынести почти всю область обрезки за пределы цели. Это руководство использует собственный силуэт закладки, чтобы показать изменение координат, возникающее искажение и центрированное вписывание, при котором ромбовидное отверстие остаётся квадратным.

Обрезка управляет видимостью. Она не обрезает исходные контуры в новую редактируемую геометрию. Если качественный SVG-силуэт уже есть, используйте его напрямую; трассировка уместна только при необходимости восстановить силуэт из растра.

Выберите систему координат перед изменением размера

По умолчанию используется userSpaceOnUse. Его координаты обрезки принадлежат пользовательской системе координат элемента, ссылающегося на область обрезки. С objectBoundingBox верхний левый угол границ цели отображается в (0, 0), а нижний правый — в (1, 1). См. справочник clipPathUnits.

ТребованиеВыбор координатЧто нужно сделать
Оставить обрезку в известных локальных координатахuserSpaceOnUseРазместить контур относительно цели
Растягивать силуэт под каждую цельobjectBoundingBoxНормализовать исходный контур и принять неравное масштабирование осей
Вписать силуэт без искаженияuserSpaceOnUseРассчитать равномерный масштаб и центрирующий перенос

Ограничивающая рамка цели не обязательно совпадает с viewBox внешнего SVG. При обрезке группы используются границы группы, которые могут отличаться от прямоугольника внутри неё. Для предсказуемой первой проверки применяйте обрезку непосредственно к прямоугольнику с известными размерами.

Сравните широкую цель с высокой

Внешние границы нашей закладки — x=20, y=10, width=100, height=100. Ромб — второй подконтур внутри того же контура. Тест применяет его к прямоугольникам размером 200 × 120 и 120 × 200 в локальных единицах SVG.

Браузерное сравнение фигуры обрезки в форме закладки на широких и высоких прямоугольниках: фиксированные координаты, растянутые координаты ограничивающей рамки и равномерное вписывание с прозрачными ромбовидными отверстиями
Браузерная отрисовка исходного SVG ниже. Фиксированные координаты сохраняют фигуру 100 × 100; отображение по ограничивающей рамке растягивает её под каждую цель; равномерное вписывание сохраняет пропорции. Шахматная сетка — фон просмотра.

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

Сохраните полный пример ниже как clippath-comparison.svg и откройте в браузере. Столбцы следуют порядку изображения. Верхний ряд использует широкие прямоугольники, нижний — высокие. Переносы для отображения расставляют образцы и не меняют локальных размеров целей.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 470">
  <defs>
    <path id="silhouette" d="M20 10H120V110L70 85L20 110Z M70 30L85 45L70 60L55 45Z"/>
    <clipPath id="fixed" clipPathUnits="userSpaceOnUse">
      <use href="#silhouette" clip-rule="evenodd"/>
    </clipPath>
    <clipPath id="box" clipPathUnits="objectBoundingBox">
      <use href="#silhouette" clip-rule="evenodd"
        transform="matrix(.01 0 0 .01 -.2 -.1)"/>
    </clipPath>
    <clipPath id="wide-fit" clipPathUnits="userSpaceOnUse">
      <use href="#silhouette" clip-rule="evenodd"
        transform="matrix(1.2 0 0 1.2 16 -12)"/>
    </clipPath>
    <clipPath id="tall-fit" clipPathUnits="userSpaceOnUse">
      <use href="#silhouette" clip-rule="evenodd"
        transform="matrix(1.2 0 0 1.2 -24 28)"/>
    </clipPath>
  </defs>
  <g fill="#107c86">
    <rect x="0" y="0" width="200" height="120"
      transform="translate(20 30)" clip-path="url(#fixed)"/>
    <rect x="0" y="0" width="200" height="120"
      transform="translate(260 30)" clip-path="url(#box)"/>
    <rect x="0" y="0" width="200" height="120"
      transform="translate(500 30)" clip-path="url(#wide-fit)"/>
    <rect x="0" y="0" width="120" height="200"
      transform="translate(60 230)" clip-path="url(#fixed)"/>
    <rect x="0" y="0" width="120" height="200"
      transform="translate(300 230)" clip-path="url(#box)"/>
    <rect x="0" y="0" width="120" height="200"
      transform="translate(540 230)" clip-path="url(#tall-fit)"/>
  </g>
</svg>

Бирюзовая заливка принадлежит прямоугольникам. Контур обрезки задаёт их видимое очертание. Скриншот добавляет подписи и шахматную сетку вокруг того же SVG; отдельный файл сам имеет прозрачный фон.

Нормализуйте исходные границы вместе с началом

Для точки (x, y) исходника с границами (minX, minY, width, height) вычислите:

normalizedX = (x - minX) / width
normalizedY = (y - minY) / height

Здесь это (x - 20) / 100 и (y - 10) / 100. Матрица в определении box выполняет обе операции без переписывания данных контура:

matrix(0.01 0 0 0.01 -0.2 -0.1)

Она отображает (20, 10) в (0, 0), а (120, 110) — в (1, 1). Деление на 100 без вычитания начала оставило бы фигуру смещённой внутри цели. Затем отображение по ограничивающей рамке независимо масштабирует нормализованный результат по ширине и высоте цели.

Используйте реальные границы геометрии, которую хотите нормализовать. viewBox может включать намеренное пустое пространство, поэтому его размеры не обязательно равны границам силуэта. Если хотите сохранить это пространство, осознанно используйте прямоугольник viewBox вместо случайного смешивания двух измерений.

Для импортированной графики с вложенными преобразованиями измеряйте и нормализуйте в одной согласованной системе координат. Если не можете уверенно учесть преобразования, примените их в редакторе перед копированием исходных данных контура. Процесс редактирования SVG разбирает проверку контуров и групп перед передачей.

Сохраните пропорции одним коэффициентом масштаба

Для прямоугольника цели в локальном (0, 0) с шириной W и высотой H используйте:

s  = min(W / width, H / height)
tx = (W - s * width) / 2 - s * minX
ty = (H - s * height) / 2 - s * minY
matrix(s 0 0 s tx ty)

Широкая цель даёт s=1.2, tx=16 и ty=-12. Её область обрезки занимает x=40..160 и y=0..120. Высокая цель даёт s=1.2, tx=-24 и ty=28, размещая обрезку в x=0..120 и y=40..160.

Это явные матрицы в userSpaceOnUse, поэтому пересчитывайте их при изменении локальных размеров цели. Простое отображение всего SVG при другом CSS-размере масштабирует композицию целиком. Изменение прямоугольника внутри с широкого на высокий — другая операция.

Расчёт предполагает ненулевую ширину и высоту исходника и отсутствие неучтённого поворота или скоса. Это вписывание внутрь: свободное пространство ожидаемо. Растягивание единицами ограничивающей рамки уместно, если заполнение цели важнее сохранения пропорций мотива.

Сохраните отверстие в геометрии обрезки

Пример задаёт clip-rule="evenodd" каждому use внутри его clipPath. Ссылочный контур содержит и внешнюю закладку, и ромбовидный подконтур. Правило определяет, какие области этой составной фигуры находятся внутри обрезки.

Задание clip-rule бирюзовому прямоугольнику не устанавливает правило фигуры обрезки. Аналогично, fill-rule для рисования исходника не заменяет правило обрезки. Справочник MDN по clip-rule объясняет его область действия внутри clipPath.

Не добавляйте отдельный белый ромб в ожидании вычитания из обрезки. Дочерние силуэты контура обрезки объединяются в видимую область; цвета их заливки не действуют как чёрно-белые значения маски. Для такого отверстия используйте составной контур и нужное правило обхода. Руководство по заполняющимся отверстиям SVG объясняет лежащую в основе структуру контуров.

Если дизайну нужны частично прозрачные края или видимость по яркости, сравните clipPath и SVG-маску на одном изображении. Обрезка полезна для геометрической границы; маска предлагает другую модель видимости. Для одноцветной иконки, рисуемой через CSS, см. руководство по CSS-маскам SVG.

Проверьте границы и экспортированный результат

Горизонтальная или вертикальная линия может иметь геометрическую ограничивающую рамку нулевой высоты или ширины, даже если обводка видна. Избегайте objectBoundingBox для таких целей и не делите на нулевой исходный размер при нормализации. Спецификация координат SVG исключает ширину обводки из этого расчёта рамки и предупреждает о вырожденных случаях.

Перед передачей:

  1. Убедитесь, что ID области обрезки, на которую ссылается элемент существует и уникален в документе.
  2. Сравните широкие и высокие цели, включая самое маленькое отверстие.
  3. Проверьте границы исходника и цели в нужных системах координат.
  4. Сохраните и заново откройте экспортированный SVG в приложении, которое его будет использовать.
  5. Сохраните исходную геометрию, если обрезка должна остаться редактируемой.

Спецификация CSS Masking говорит, что обрезка меняет отрисовку, а не собственную геометрию элемента. Поэтому плоттеру или приложению обработки геометрии может понадобиться реальное пересечение контуров или другая операция редактора. Подтвердите полученные контуры в этом приложении; одного правильного браузерного просмотра недостаточно для готовности файла к резке.

При необходимости восстановите растровый силуэт

PerfectVector подходит, если собственный мотив сохранился только в PNG или JPG и вам нужны редактируемые контуры для обрезки. Преобразуйте изображение в SVG, затем проверьте внешний край, внутренние отверстия и нежелательные фоновые фигуры перед извлечением силуэта. Выберите, какие контуры входят в обрезку; цвета исходника не определяют отдельные степени обрезки.

Если есть векторный оригинал, сохраните его. Простую геометрическую закладку можно нарисовать напрямую, как в этом примере. Векторизация не выбирает единицы обрезки, не нормализует границы и не выполняет постоянную булеву обрезку. Общие советы по выбору исходника приведены в обзоре векторизации изображений.

Частые вопросы

objectBoundingBox сохраняет пропорции фигуры? Нет. Он независимо отображает нормализованную область обрезки на ширину и высоту цели. Используйте равномерный масштаб в userSpaceOnUse, если силуэт должен сохранять пропорции.

Почему смена clipPathUnits скрывает мою фигуру? Координаты контура могут оставаться в исходных единицах. Нормализуйте их в систему координат относительно цели, включая начало исходника, или сохраните userSpaceOnUse и разместите их явно.

Удаляет ли обрезка скрытые части моего SVG? Нет. Обрезка меняет отображение, сохраняя исходную геометрию. Используйте подходящую операцию редактирования контуров, если передаваемому файлу нужны навсегда обрезанные очертания.

Источники

  1. MDN — clipPathUnits — Варианты координат и интерпретация в пользовательском пространстве по умолчанию.
  2. MDN — clip-rule — Размещение правила обхода внутри контуров обрезки.
  3. W3C — SVG coordinate systems — Отображение по ограничивающей рамке, исключение обводки и ограничения нулевых размеров.
  4. W3C — CSS Masking — Геометрия обрезки, объединённые силуэты и неизменность исходных контуров.

Если обрезка начинается с растрового мотива, подготовьте его SVG с PerfectVector, проверьте силуэт и отверстия, затем протестируйте обе пропорции цели перед выбором растягивания или равномерного вписывания.

Ещё из блога

Начните с более чистого SVG,
который проще редактировать