Как атрибуты maskUnits и maskContentUnits влияют на позиционирование маски? - PullRequest
0 голосов
/ 07 октября 2018

Я прочитал немного спецификации для элемента маски SVG , но разделы на maskUnits и maskContentUnits мне не понятны, а также то, как они влияют друг на друга, не так ли 'мне не понятно.

Из спецификации:

maskUnits = 'userSpaceOnUse' : x, y, ширина и высота представляют значения в текущей пользовательской координатесистема на месте, когда на нее ссылается элемент маски.

maskUnits = 'boundingBox' : x, y, ширина и высота представляют собой доли или проценты отограничивающий прямоугольник объекта элемента, к которому применяется маска.

maskContentUnits = 'userSpaceOnUse' : пользовательской системой координат для содержимого элемента маски являетсятекущая пользовательская система координат на месте в момент обращения к элементу маски.

maskContentUnits = 'boundingBox' : источник координат находится в верхнем левом углуугол ограничительной рамки элементаПрименительно к этому пути отсечения применяется одинаковая ширина и высота этой ограничительной рамки.

Я попытался отредактировать пример maskUnits и пример maskContentUnits в MDN, но всякий раз, когда я меняю что-либо, происходит что-то неожиданное, например, исчезает весь элемент или кажется, что маска не применяется.

Фрагмент ниже - это песочница с несколькими примерами запутанного поведения.Я ожидаю, что все квадраты будут выглядеть по-разному, но есть две пары, каждая из которых идентична, и одна из пар выглядит так, как будто маска вообще не применялась:

* {
  margin: 0;
  padding: 0;
}

body {
  padding: 20px 0 0 20px;
}

.hidden {
  width: 0;
  height: 0;
  margin: 0;
}

svg {
  width: 100px;
  height: 100px;
  margin: 0 20px 20px 0;
  display: block;
}

p {
  margin-bottom: 10px;
  font-family: monospace;
}
<!-- mask definitions -->
<svg viewBox="0 0 100 100" class="hidden">
  <mask
    id="usou-usou"
    maskUnits="userSpaceOnUse"
    maskContentUnits="userSpaceOnUse"
    x="0"
    y="0"
    width="100"
    height="100"
  >
    <rect x="0" y="0" width="100" height="100" fill="white" />
    <circle cx="50" cy="50" r="25" fill="black" />
  </mask>
  
  <mask
    id="usou-obb"
    maskUnits="userSpaceOnUse"
    maskContentUnits="objectBoundingBox"
    x="0"
    y="0"
    width="100"
    height="100"
  >
    <rect x="0" y="0" width="100" height="100" fill="white" />
    <circle cx="50" cy="50" r="25" fill="black" />
  </mask>
  
  <mask
    id="obb-usou"
    maskUnits="objectBoundingBox"
    maskContentUnits="userSpaceOnUse"
    x="0"
    y="0"
    width="100"
    height="100"
  >
    <rect x="0" y="0" width="100" height="100" fill="white" />
    <circle cx="50" cy="50" r="25" fill="black" />
  </mask>
  
  <mask
    id="obb-obb"
    maskUnits="objectBoundingBox"
    maskContentUnits="objectBoundingBox"
    x="0"
    y="0"
    width="100"
    height="100"
  >
    <rect x="0" y="0" width="100" height="100" fill="white" />
    <circle cx="50" cy="50" r="25" fill="black" />
  </mask>
</svg>

<p>maskUnits = userSpaceOnUse &<br> maskContentUnits = userSpaceOnUse</p>
<svg viewBox="0 0 100 100">
  <rect
    x="0"
    y="0"
    width="100"
    height="100"
    mask="url(#usou-usou)"
  />
</svg>

<p>maskUnits = userSpaceOnUse &<br> maskContentUnits = objectBoundingBox</p>
<svg viewBox="0 0 100 100">
  <rect
    x="0"
    y="0"
    width="100"
    height="100"
    mask="url(#usou-obb)"
  />
</svg>

<p>maskUnits = objectBoundingBox &<br> maskContentUnits = userSpaceOnUse</p>
<svg viewBox="0 0 100 100">
  <rect
    x="0"
    y="0"
    width="100"
    height="100"
    mask="url(#obb-usou)"
  />
</svg>

<p>maskUnits = objectBoundingBox &<br> maskContentUnits = objectBoundingBox</p>
<svg viewBox="0 0 100 100">
  <rect
    x="0"
    y="0"
    width="100"
    height="100"
    mask="url(#obb-obb)"
  />
</svg>

1 Ответ

0 голосов
/ 07 октября 2018

Мы знаем, что такое единицы в обычной жизни, есть дюймы, мили, километры и т. Д.

Один дюйм не равен одному километру.Если вы нарисуете крошечную картинку шириной в один дюйм и поместите рамку вокруг нее в 2 дюйма, само изображение не изменится, если мы сделаем рамку шириной 2 километра.Точно так же, изменение размера изображения не меняет того, насколько оно видно внутри рамки изображения, если только рамка не слишком мала для изображения.

maskUnits влияет на единицы измерения кадра (маски), maskContentUnits влияет на единицы измерения.изображения (маска).

Единицы objectBoundingBox определены так, что 0 - левая сторона маскированной формы, а 1 - правая.

userSpaceOnUse используют ту же систему координаткак сама маска в форме.Если вы маскируете прямоугольник, который простирается от 50 до 100, тогда ваша маска должна также покрывать эту область, если вы хотите замаскировать весь прямоугольник.

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

Мы маскируем

<rect x="0" y="0" width="100" height="100"/>

Таким образом, x, y, ширина и высота нашей маски, т.е.

<mask maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100"/>

, должны покрывать одну и ту же область (или более), если мы хотим замаскировать эту форму, и они это делают.

Если бы у нас был maskUnits = "objectBoundingBox", нам понадобилось бы

<mask maskUnits="objectBoundingBox" x="0" y="0" width="1" height="1"/>

Использование 100 для ширины и высоты сделало бы маску в 100 раз больше необходимого ей размера, но не тратя много памяти,он не имеет видимого эффекта.

maskContentUnits работают одинаково для содержимого маски, т. е.

<rect x="0" y="0" width="100" height="100" fill="white" />
<circle cx="50" cy="50" r="25" fill="black" />

Либо они должны быть 0..1 для objectBoundingBox или 0..100 для фигуры.Поскольку они слишком велики для objectBoundingBox, все маски имеют один цвет, так как фигуры находятся за пределами области, которую вы можете видеть, т.е. области над формой.

<!-- mask definitions -->
<svg viewBox="0 0 100 100" class="hidden">
  <mask
    id="usou-usou"
    maskUnits="userSpaceOnUse"
    maskContentUnits="userSpaceOnUse"
    x="0"
    y="0"
    width="100"
    height="100"
  >
    <rect x="0" y="0" width="100" height="100" fill="white" />
    <circle cx="50" cy="50" r="25" fill="black" />
  </mask>
  
  <mask
    id="usou-obb"
    maskUnits="userSpaceOnUse"
    maskContentUnits="objectBoundingBox"
    x="0"
    y="0"
    width="100"
    height="100"
  >
    <rect x="0" y="0" width="1" height="1" fill="white" />
    <!-- if we wanted the same mask as above it would be r="0.25" -->
    <circle cx=".5" cy=".5" r=".1" fill="black" />
  </mask>
  
  <!-- have the mask cover only the top left quarter of the shape -->
  <mask
    id="obb-usou"
    maskUnits="objectBoundingBox"
    maskContentUnits="userSpaceOnUse"
    x="0"
    y="0"
    width="0.5"
    height="0.5"
  >
    <rect x="0" y="0" width="100" height="100" fill="white" />
    <circle cx="50" cy="50" r="25" fill="black" />
  </mask>
  
  <!-- have the mask cover only the top left quarter of the shape -->
  <mask
    id="obb-obb"
    maskUnits="objectBoundingBox"
    maskContentUnits="objectBoundingBox"
    x="0"
    y="0"
    width="0.5"
    height="0.5"
  >
    <rect x="0" y="0" width="1" height="1" fill="white" />
    <!-- if we wanted the same mask as above it would be r="0.25" -->
    <circle cx=".5" cy=".5" r=".1" fill="black" />
  </mask>
</svg>

<p>maskUnits = userSpaceOnUse &<br> maskContentUnits = userSpaceOnUse</p>
<svg viewBox="0 0 100 100">
  <rect
    x="0"
    y="0"
    width="100"
    height="100"
    mask="url(#usou-usou)"
  />
</svg>

<p>maskUnits = userSpaceOnUse &<br> maskContentUnits = objectBoundingBox</p>
<svg viewBox="0 0 100 100">
  <rect
    x="0"
    y="0"
    width="100"
    height="100"
    mask="url(#usou-obb)"
  />
</svg>

<p>maskUnits = objectBoundingBox &<br> maskContentUnits = userSpaceOnUse</p>
<svg viewBox="0 0 100 100">
  <rect
    x="0"
    y="0"
    width="100"
    height="100"
    mask="url(#obb-usou)"
  />
</svg>

<p>maskUnits = objectBoundingBox &<br> maskContentUnits = objectBoundingBox</p>
<svg viewBox="0 0 100 100">
  <rect
    x="0"
    y="0"
    width="100"
    height="100"
    mask="url(#obb-obb)"
  />
</svg>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...