SVG坐标系旋转倾斜角度

Mag*_*nus 5 html css svg

我以为我对 SVG 有相当不错的理解,包括viewportviewBox用户坐标系

在下面的第一个示例中,我们使用与viewport具有相同纵横比的viewBox。正如预期的那样,用户坐标系旋转不会扭曲任何角度。

在示例二中,与viewport相比,我们将viewbox设置为不同的纵横比。换句话说,当将viewBox映射到viewport 时,不会保持形状的纵横比。右下角不会因这种缩放而变形,这是有道理的,因为坐标系原点位于 (0,0)。

然而,当我们在示例二中旋转用户坐标系时,右下角发生了扭曲。这在示例一中不会发生。

编辑 1:需要说明的是,问题在于最后一个示例中的右下角。旋转前,但使用viewBox拉伸后,角度为 90%。然而,旋转后,它不再是 90%。

为什么不均匀缩放的三角形在旋转时会失去角度?

示例一(统一比例尺)

body {
  height: 500px;
}

svg {
  width: 400px;
  height: 400px;
  border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

示例二(非均匀比例)

body {
  height: 500px;
}

svg {
  width: 600px;
  height: 400px;
  border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


编辑2(图像澄清):

下面我们看到了添加 viewBox之后的三角形(因此缩放和平移),但旋转之前。右下角为 90 度。

在此处输入图片说明

下面我们看到的三角形已加入视框(因而缩放和翻译), 转动。右下角不再是 90 度。

在此处输入图片说明


编辑 3:

我终于明白了这一点。

以下是解释详细信息并链接到相关资源的答案。

Mag*_*nus 2

我终于弄清楚了这件事的真相。

以下问题是我在得出实际问题的结论后发布的,它解释了为什么坐标变换的行为如下:

在该问题的回答中,@TemaniAfif 展示了如何计算最终变换矩阵并将其应用于图形元素的坐标,以便将其从视口坐标系映射到最终用户坐标系。

长话短说,在应用转换时,我们实际做的是复制当前用户坐标系,然后相对于我们复制的当前用户坐标系进行平移。在 SVG 中,初始用户坐标系(在 viewBox 或任何变换之前)与初始视口坐标系相同。

链式/嵌套变换应用于从左到右/从外到内的坐标系,以达到可以在其中映射图形元素的最终坐标系。请注意,嵌套变换与一个元素上的链接变换具有相同的效果。

这实际上是如何运作的?嗯,每个变换都有一个预定义的仿射变换矩阵,与 CSS/SVG 无关。有几篇维基百科文章显示了这些矩阵,例如:

为了将元素的坐标映射到最终的用户坐标系,我们从左到右(按照源代码中编写的顺序)将矩阵相互相乘,以获得最终的转换矩阵。

请注意,由于我们按照变换矩阵在源代码中写入的顺序来相乘,并且由于矩阵相乘时 AxB 与 BxA 不同,因此在源代码中写入变换的顺序很重要。

最后,我们将元素的 x 和 y 坐标与最终的变换矩阵相乘,以查看每个坐标如何从视口坐标系映射到最终的用户坐标系。

对于那些如此倾向于的人,可能更容易不考虑上述内容,而只是在心里想象链式/嵌套变换从右到左/从内到外应用于元素本身(而不是用户坐标系)(即其应用于坐标系的顺序相反)。

无论您在心里想象从左到右变换坐标系然后映射到图形元素,还是通过从右到左应用变换来变换元素本身,最终结果都是相同的。

相关规格

笔记

对于这个问题,变换是应用于 SVG 元素还是 HTML 元素并不重要。适用相同的转换机制。