svg - 通过翻转 X 轴更改坐标系(从右上角开始)

标签 svg graphics elm coordinate-systems coordinate-transformation

我正在寻找一种简单的方法来在给定的 svg 中创建坐标系元素从右上角开始,而不是从左上角开始。这意味着 X 轴被翻转,从而增加 x元素的属性将其进一步向左渲染,并增加 y属性将其像往常一样进一步呈现到底部。

我玩过scaleviewBox ,但是:

  • scale几乎解决了问题,但它并不真正适合我的用例,因为它还会翻转我渲染的文本
  • viewBox似乎不适用于 height="100%"width="100%" 。对于我的用例,我认为我无法对 height 进行硬编码和width SVG 的原因是我需要它可以在许多不同的分辨率和屏幕尺寸上使用。

这个question说它用 matrix 解决了 Y 轴的相同问题。转型。我环顾四周并尝试计算 X 轴的等效值,但没有成功。

这是我想要实现的目标的示例:

<svg style="border: 1px black solid;" height="100%" width="100%">
  <g>
    <g>
      <rect fill="#F0BC40" width="70" height="12" x="0" y="30"></rect>
      <text fill="black" font-size="10px" text-anchor="middle" x="35" y="29">7</text>
    </g>
    <g>
      <rect fill="orange" width="50" height="12" x="72" y="30"></rect>
      <text fill="black" font-size="10px" text-anchor="middle" x="97" y="29">5</text>
    </g>
    <g>
      <rect fill="orange" width="40" height="12" x="124" y="30"></rect>
      <text fill="black" font-size="10px" text-anchor="middle" x="144" y="29">4</text>
    </g>
    <g>
      <rect fill="red" width="50" height="12" x="166" y="30"></rect>
      <text fill="black" font-size="10px" text-anchor="middle" x="191" y="29">5</text>
    </g>
      <rect fill="#52575E" width="2" height="16" x="70" y="28"></rect>
      <rect fill="#52575E" width="2" height="16" x="122" y="28"></rect>
      <rect fill="#52575E" width="2" height="16" x="164" y="28"></rect>
    </g>
  </svg>

如您所见,我希望从右侧渲染此堆叠条,其中红色条位于最左侧(因此基本上堆叠条将被翻转)

此外,我是在 Elm 中执行此操作,因此我无法访问 DOM 来检查元素的宽度、高度或坐标(我正在以函数方式计算所有内容)。

如果有人能帮助我实现这一目标,我将非常感激。

最佳答案

我想到的方式是将条形图从 x="0"向左绘制,然后将 viewBox 设置为负 x 值和宽度,使其以 x="0"结束。

对于文本元素,向 x 值添加负号。对于矩形,将 x 值设置为 x -> -x - width .

定义 viewBox这样最低的 x 值仍然在内部,或者任何合适的值。

<svg style="border: 1px black solid;" height="100%" width="100%" viewBox="-500 0 500 100">
  <g>
    <g>
      <rect fill="#F0BC40" width="70" height="12" x="-70" y="30"></rect>
      <text fill="black" font-size="10px" text-anchor="middle" x="-35" y="29">7</text>
    </g>
    <g>
      <rect fill="orange" width="50" height="12" x="-122" y="30"></rect>
      <text fill="black" font-size="10px" text-anchor="middle" x="-97" y="29">5</text>
    </g>
    <g>
      <rect fill="orange" width="40" height="12" x="-164" y="30"></rect>
      <text fill="black" font-size="10px" text-anchor="middle" x="-144" y="29">4</text>
    </g>
    <g>
      <rect fill="red" width="50" height="12" x="-216" y="30"></rect>
      <text fill="black" font-size="10px" text-anchor="middle" x="-191" y="29">5</text>
    </g>
    <rect fill="#52575E" width="2" height="16" x="-72" y="28"></rect>
    <rect fill="#52575E" width="2" height="16" x="-124" y="28"></rect>
    <rect fill="#52575E" width="2" height="16" x="-166" y="28"></rect>
  </g>
</svg>

这将缩放文本和条形;如果你需要避免这种情况,有一个技巧。您可以用两个 <svg> 包围内容元素并使用内部元素将所有内容 100% 向右移动。 overflow="visible" (或 style="overflow:visible" )确保内容可见,尽管它正式位于内部 <svg> 的视口(viewport)之外.

<svg style="border: 1px black solid;" height="100%" width="100%">
  <svg x="100%" overflow="visible">
    <g>
      <g>
        <rect fill="#F0BC40" width="70" height="12" x="-70" y="30"></rect>
        <text fill="black" font-size="10px" text-anchor="middle" x="-35" y="29">7</text>
      </g>
      <g>
        <rect fill="orange" width="50" height="12" x="-122" y="30"></rect>
        <text fill="black" font-size="10px" text-anchor="middle" x="-97" y="29">5</text>
      </g>
      <g>
        <rect fill="orange" width="40" height="12" x="-164" y="30"></rect>
        <text fill="black" font-size="10px" text-anchor="middle" x="-144" y="29">4</text>
      </g>
      <g>
        <rect fill="red" width="50" height="12" x="-216" y="30"></rect>
        <text fill="black" font-size="10px" text-anchor="middle" x="-191" y="29">5</text>
      </g>
      <rect fill="#52575E" width="2" height="16" x="-72" y="28"></rect>
      <rect fill="#52575E" width="2" height="16" x="-124" y="28"></rect>
      <rect fill="#52575E" width="2" height="16" x="-166" y="28"></rect>
    </g>
  </svg>
</svg>

关于svg - 通过翻转 X 轴更改坐标系(从右上角开始),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52572765/

相关文章:

graphics - 2D 平台游戏 : why make the physics dependent on the framerate?

javascript - 单击 d3 中的 svg 文本在鼠标位置上打开 div

c - 用于演示矩阵的简单 C 图形库

css - "Background"忽略其他 <svg> 元素内的 <svg> 元素的样式属性

opengl - 顶点缓冲区的双缓冲与三重缓冲

comparison - 如何比较 Elm 中的多个字段?

javascript - 从榆树中的子组件发送信号

json - 递归解码嵌套列表(任意深度的列表的列表)

java - 使用 batik 在 JPanel 上加载 SVG 文件

graphics - 从色调 0 到 360 的 SVG 线性渐变