【问题标题】:Alter coordinates system by flipping X axis (start at top right corner)通过翻转 X 轴来改变坐标系(从右上角开始)
【发布时间】:2018-09-29 21:36:51
【问题描述】:

我正在寻找一种简单的方法来使给定svg 元素中的坐标系从右上角开始,而不是从左上角开始。这意味着 X 轴被翻转,因此增加元素的 x 属性会将其渲染到更左侧,增加 y 属性会将其渲染到更底部。

我玩过scaleviewBox,但是:

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

这个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>

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

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

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

【问题讨论】:

    标签: svg graphics elm coordinate-systems coordinate-transformation


    【解决方案1】:

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

    对于文本元素,为 x 值添加一个负号。对于矩形,将 x 值设置为x -&gt; -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>

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

    <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>

    【讨论】:

      【解决方案2】:

      正如你所说,scale“几乎可以工作”。您可以再次使用scale 来取消翻转text。使用嵌套变换使翻转style 与水平text 放置正常工作。如果您想切换回未翻转的版本,只需将 scale 中的 -1 更改为 1(或去掉翻转 style 中的 transform)。

      <head>
        <style TYPE="text/css">
        <!--
        .flipped {
          transform: scale(-1,1);
        }
        -->
        </style> 
      </head>
      <svg class=flipped style="border: 1px black solid;" height="100%" width="100%">
        <g>
          <g>
            <rect fill="#F0BC40" width="70" height="12" x="0" y="30"></rect>
            <g transform="translate(35,29)">
              <g class=flipped >
                <text fill="black" font-size="10px" text-anchor="middle" >7</text>
              </g>
            </g>
          </g>
          <g>
            <rect fill="orange" width="50" height="12" x="72" y="30"></rect>
            <g transform="translate(97,29)">
              <g class=flipped >
                <text fill="black" font-size="10px" text-anchor="middle" >5</text>
              </g>
            </g>
          </g>
          <g>
            <rect fill="orange" width="40" height="12" x="124" y="30"></rect>
            <g transform="translate(144,29)">
              <g class=flipped >
                <text fill="black" font-size="10px" text-anchor="middle" >4</text>
              </g>
            </g>
          </g>
          <g>
            <rect fill="red" width="50" height="12" x="166" y="30"></rect>
            <g transform="translate(191,29)">
              <g class=flipped >
                <text fill="black" font-size="10px" text-anchor="middle" >5</text>
              </g>
            </g>
          </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>

      【讨论】:

      • 您的回答似乎不错,但我就是不明白为什么需要translate 以及您如何计算需要哪些值?有没有一种方法可以在我的代码中计算而不依赖于 DOM 检查?
      • 用于翻译的值与您最初用于文本定位的值相同。所以你可以用完全相同的方式计算它们——在这种情况下,在相应矩形的中间上方。发生的情况是,未翻译的文本首先在 x=0 处翻转(这导致镜像文本),然后翻译到位于相应矩形条上方。 :最后,整个事情再次翻转,将条形(和文本)放在 svg 图像的右侧(这是你首先想要的)。两次翻转的文字正常显示。
      • 效果很好的一个原因是文本是“中间”锚定的,这意味着文本翻转转换将围绕文本的中间翻转。左变右,右变左,中留中,整个翻转
      • 另请注意,用于文本放置的值不再在文本规范中。如果是这样,则文本将在在被镜像之前定位,并且翻转会将正 x 值变为负值,并且文本会从图像中翻转出来
      • 感谢您的意见,戴夫。我首先尝试了@ccprog 的答案,它奏效了,但你的看起来也有效!
      猜你喜欢
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 2012-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多