SVG система координат углы наклона поворота - PullRequest
0 голосов
/ 07 декабря 2018

Мне показалось, что я достаточно хорошо понимаю SVG, включая область просмотра , viewBox и пользовательскую систему координат .

ВВ первом примере ниже мы используем viewBox с тем же соотношением сторон, что и viewport .Как и ожидалось, пользовательская система координат вращения не искажает никаких углов.

Во втором примере мы устанавливаем viewbox в другое соотношение сторон, по сравнению с * видовой экран 1020 *.Другими словами, при отображении viewBox в viewport пропорции форм не поддерживаются.Нижний правый угол не искажается от этого масштабирования, что имеет смысл, поскольку начало координат системы координат составляет (0,0).

Когда мы вращаем пользовательскую систему координат в примере дваОднако нижний правый угол искажен.Этого не происходит в первом примере.

Редактировать 1: Просто чтобы прояснить ситуацию, проблема касается нижнего правого угла в последнем примере.Перед вращением, но после растяжения с viewBox , угол составляет 90%.Однако после поворота он больше не равен 90%.

Почему треугольник с неравномерным масштабом теряет свои углы при вращении?

Пример первый (равномерная шкала)

body {
  height: 500px;
}

svg {
  width: 400px;
  height: 400px;
  border: 1px solid red;
}
<svg id="s1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 200 200" preserveAspectRatio="none">
    <style>
      polygon {
        transform: translate(100px, 0px);
        animation: 2s ease-in 1s 1 normal forwards rotate-down;
        fill: green;
      }
      
      @keyframes rotate-down {
        0% {
          transform: translate(100px, 0px) rotate(0deg);
        }
        100% {
          transform: translate(100px, 0px) rotate(45deg);
        }
      }
    </style>
    <polygon points="100,100 100,0 0,100" />
  </svg>

Пример два (неравномерная шкала)

body {
  height: 500px;
}

svg {
  width: 600px;
  height: 400px;
  border: 1px solid red;
}
<svg id="s1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 200 400" preserveAspectRatio="none">
    <style>
      polygon {
        transform: translate(100px, 0px);
        animation: 2s ease-in 1s 1 normal forwards rotate-down;
        fill: green;
      }
      
      @keyframes rotate-down {
        0% {
          transform: translate(100px, 0px) rotate(0deg);
        }
        100% {
          transform: translate(100px, 0px) rotate(45deg);
        }
      }
    </style>
    <polygon points="100,100 100,0 0,100" />
  </svg>

РЕДАКТИРОВАТЬ 2 (изображения для уточнения):

Ниже мы видим треугольник после viewBox был добавлен (таким образом масштабирован и переведен), но до вращения.Нижний правый угол составляет 90 градусов.

enter image description here

Ниже мы видим треугольник после добавления viewBox (таким образом масштабируется и переводится), и после вращения.Правый нижний угол больше не составляет 90 градусов.

enter image description here


РЕДАКТИРОВАТЬ 3:

Iв конце концов дошло до сути.

Ниже приведен ответ, объясняющий детали и ссылки на соответствующие ресурсы.

Ответы [ 3 ]

0 голосов
/ 07 декабря 2018

Кажется, вы думаете, что viewBox - это какой-то метод преобразования, применяемый, как и другие, при вычислении SVG-изображения, что не соответствует действительности.Здесь вы испытываете преобразование, примененное ко всему элементу SVG .Чтобы применить это преобразование, браузеру необходимо вычислить объект SVG, поэтому все преобразования в SVG уже применяются.

Это работает точно так же, как масштабирование растровых изображений:

polygon {
  fill: transparent;
  stroke-width: 4px;
  stroke: black;
}
Base raster image:<br>
<img src="https://i.stack.imgur.com/ZA16O.png">

<br>Stretched raster image:<br>
<img style="height: 150px; width: 300px" src="https://i.stack.imgur.com/ZA16O.png">

<br>Base SVG:<br>
<svg viewBox="0,0,160,160" style="height: 120px" preserveAspectRatio="none">
<polygon points="10,10 150,10 80,150"/>
</svg>

<br>Stretched SVG:<br>
<svg viewBox="0,0,160,160" preserveAspectRatio="none" style="height: 120px; width: 300px;">
<polygon points="10,10 150,10 80,150"/>
</svg>

После преобразования отрисовываются только SVG, следовательно, они не теряют качества.


На самом деле в спецификации SVG ( здесь ) что все преобразования, примененные к элементу SVG, работают таким образом.

0 голосов
/ 10 декабря 2018

Я наконец-то дошел до сути.

Следующий вопрос, который я опубликовал после того, как решил, в чем заключалась реальная проблема, объясняет, почему преобразования координат ведут себя так, как они:

В ответе на этот вопрос @TemaniAfif показывает, как вычисляется окончательная матрица преобразования и применяется к координатам графического элемента, вчтобы отобразить его из системы координат области просмотра в конечную пользовательскую систему координат.

Короче говоря, при применении преобразований мы фактически копируем текущую пользовательскую систему координат, а затем переводим ее относительно текущейпользовательская система координат, из которой мы скопировали.В SVG исходная пользовательская система координат (до viewBox или любых преобразований) идентична исходной системе координат видового экрана.

Цепные / вложенные преобразования применяются к системе координат слева направо / снаружи-в , чтобы достичь конечной системы координат, в которой могут отображаться графические элементы.Обратите внимание, что вложенные преобразования имеют тот же эффект, что и цепные преобразования для одного элемента.

Как это на самом деле работает?Что ж, каждое преобразование имеет предопределенную аффинную матрицу преобразования, не связанную с CSS / SVG.Есть несколько статей в Википедии, в которых показаны матрицы, например:

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

Обратите внимание, что, поскольку мы умножаемпреобразовать матрицы в том порядке, в каком они написаны в нашем исходном коде, и поскольку AxB отличается от BxA при умножении матриц, порядок, в котором преобразования записываются в нашем исходном коде, имеет значение.

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

Для таких склонных было бы проще не подумайте над вышесказанным и просто мысленно представьте, что цепочечные / вложенные преобразованияприменяется к самому элементу (не к пользовательским системам координат) справа налево / наизнанку (т.е. в обратном порядке того, как он был применен к системам координат).

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

Соответствующие характеристики

Примечание

Для этого вопроса не имеет значения, применяются ли преобразования к элементам SVG или элементам HTML.Применяется та же механика преобразования.

0 голосов
/ 07 декабря 2018

Надеюсь, этот пример покажет вам, что происходит.

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

body {
  height: 500px;
}

svg {
  width: 200px;
  height: 400px;
  border: 1px solid red;
  transition: 1s width;
}

svg:hover {
  width: 600px;
}
<svg id="s1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 200 400" preserveAspectRatio="none">
    <style>
      polygon {
        transform: translate(100px, 0px) rotate(45deg);
        fill: green;
      }
    </style>
    <polygon points="100,100 100,0 0,100" />
  </svg>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...