Как центрировать svg <pattern>внутри более крупного адаптивного контейнера при любой возможной ширине? - PullRequest
1 голос
/ 28 мая 2020

У меня есть адаптивный контейнер SVG, и мне нужно, чтобы мой <pattern> отображался в центре каждой ситуации.

Я имею в виду:

  • Треугольник <pattern> должен быть с центром в все возможные ширины
  • И пространство слева / справа должно повторять треугольник <pattern>

Возможно ли это? Я знаю, что можно динамически пересчитать позицию шаблона с помощью JS. Но я бы хотел сделать это, используя только свойства svg.

.mySvg1 {
  width: 600px;
  height: 50px;
  border: 1px dotted red;
  margin-bottom: 16px;
}

.mySvg2 {
  width: 400px;
  height: 50px;
  border: 1px dotted red;
  margin-bottom: 16px;
}

.mySvg3 {
  width: 200px;
  height: 50px;
  border: 1px dotted red;
  margin-bottom: 16px;
}

span {
  font-weight: bold;
  color: red;
}

.myDiv1 {
  margin-bottom: 16px;
}
 <div class="myDiv1">
   SEE THAT THE TRIANGLE IS <span>NOT</span> CENTERED. I WOULD LIKE IT TO ALWAYS BE CENTERED
 </div>

<div>
  <svg class="mySvg1">
    <defs>
      <pattern 
        id="wave"
        width="150"
        height="50"
        patternUnits="userSpaceOnUse"
      >
        <path d="M 0 50 l 75 -50 l 75 50" stroke="black" stroke-width="2"/>
      </pattern>
    </defs>
    <rect x="0" y="0" width="100%" height="100%" fill="url(#wave)"/>
  </svg>
</div>

<div>
  <svg class="mySvg2">
    <rect x="0" y="0" width="100%" height="100%" fill="url(#wave)"/>
  </svg>
</div>

<div>
  <svg class="mySvg3">
    <rect x="0" y="0" width="100%" height="100%" fill="url(#wave)"/>
  </svg>
 </div>

EXTRA:

Это легко сделать с помощью background-image. Я хотел бы сделать то же самое, используя только <svg>. Возможно ли такое?

div {
  margin-bottom: 16px;
}

.myDiv1 {
  width: 600px;
  height: 50px;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 -2 150 52"><path d="M 0 50 l 75 -50 l 75 50" stroke="black" /></svg>');
  background-position: center;
}

.myDiv2 {
  width: 400px;
  height: 50px;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 -2 150 52"><path d="M 0 50 l 75 -50 l 75 50" stroke="black" /></svg>');
  background-position: center;
}

.myDiv3 {
  width: 200px;
  height: 50px;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 -2 150 52"><path d="M 0 50 l 75 -50 l 75 50" stroke="black" /></svg>');
  background-position: center;
}
<div>
  SEE THAT THE TRIANGLE IS ALWAYS CENTERED
</div>

<div class="myDiv1">
</div>

<div class="myDiv2">
</div>

<div class="myDiv3">
</div>

1 Ответ

2 голосов
/ 28 мая 2020

Вот идея, в которой вам нужно:

  1. установить большую ширину прямоугольника с учетом ширины пути (нечетный множитель ширины пути)
  2. вы задаете ширину узора в процентах (100/n, где n - множитель). Вы также удаляете patternUnits="userSpaceOnUse"
  3. . Вы помещаете rect в 50% и переводите его обратно с помощью 50%, чтобы он был посередине

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

.mySvg1 {
  width: 600px;
  height: 50px;
  border: 1px dotted red;
  margin-bottom: 16px;
}

.mySvg2 {
  width: 400px;
  height: 50px;
  border: 1px dotted red;
  margin-bottom: 16px;
}

.mySvg3 {
  width: 200px;
  height: 50px;
  border: 1px dotted red;
  margin-bottom: 16px;
}

span {
  font-weight: bold;
  color: red;
}

.myDiv1 {
  margin-bottom: 16px;
}

rect {
  transform:translate(-50%);
  transform-box:fill-box;
}
<div class="myDiv1">
   SEE THAT THE TRIANGLE IS <span>NOT</span> CENTERED. I WOULD LIKE IT TO ALWAYS BE CENTERED
 </div>

<div>
  <svg class="mySvg1">
    <defs>
      <pattern 
        id="wave"
        width="9.1%"
        height="50"
      >
        <path d="M 0 50 l 75 -50 l 75 50" stroke="black" stroke-width="2"/>
      </pattern>
    </defs>
    <rect x="50%" y="0" width="1672" height="100%" fill="url(#wave)" />
  </svg>
</div>

<div>
  <svg class="mySvg2">
    <rect x="50%" y="0" width="1672" height="100%" fill="url(#wave)"/>
  </svg>
</div>

<div>
  <svg class="mySvg3">
    <rect x="50%" y="0" width="1672" height="100%" fill="url(#wave)"/>
  </svg>
 </div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...