SVG-更改比例后如何计算x和y坐标?

时间:2019-02-21 14:06:54

标签: javascript html svg

我有这样的SVG:

<svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  width="630"
  height="430"
>
  <rect
    rx="0"
    ry="0"
    width="100%"
    height="100%"
    fill="rgba(92, 95, 108, 1.0)"
  />
    <line x1="0" y1="176" x2="630" y2="176" style="stroke:rgb(255,0,0);stroke-width:2" />
      <g
        transform="scale(0.2) translate(1300.370746612549 818.9994964599609)"
        style="outline: black solid 2px;"
      >
        <path
          fill="rgba(198, 199, 205, 1.0)"
          d="M414.578,62.68L93.932,122.853c-22.91,4.448-33.326,15.876-33.326,35.457v221.359    c0,19.581,6.1,39.759,32.654,35.457l154.561-29.073l-9.639,63.268l110.875-82.335l65.695-12.019    c23.564-4.135,36.643-15.875,36.643-35.457V98.137C451.395,78.556,434.16,62.68,414.578,62.68z M354.711,235.385    c-5.002,53.956-55.426,97.697-112.623,97.697c-57.203,0-99.508-43.741-94.506-97.697c5.004-53.969,55.428-97.711,112.623-97.711    C317.408,137.674,359.721,181.416,354.711,235.385z M215.049,282.888c-3.109-20.511-6.363-56.128-9.063-76.632    c-1.416-10.769,4.857-14.876,15.098-12.905c28.838,5.537,82.398,16.59,82.398,16.59c11.623,1.416,17.576,11.9,6.578,20.643    c-19.873,15.793-56.912,48.904-78.846,61.547C224.207,296.168,216.229,290.638,215.049,282.888z"
        />
      </g>
</svg>

如您所见,有一个比例为0.2的组元素。同样,这个小组正在“触动”界线。这可以。但是,将比例尺更改为0.25后,组元素突然移动到其他位置。

<svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  width="630"
  height="430"
>
  <rect
    rx="0"
    ry="0"
    width="100%"
    height="100%"
    fill="rgba(92, 95, 108, 1.0)"
  />
    <line x1="0" y1="176" x2="630" y2="176" style="stroke:rgb(255,0,0);stroke-width:2" />
      <g
        transform="scale(0.25) translate(1300.370746612549 818.9994964599609)"
        style="outline: black solid 2px;"
      >
        <path
          fill="rgba(198, 199, 205, 1.0)"
          d="M414.578,62.68L93.932,122.853c-22.91,4.448-33.326,15.876-33.326,35.457v221.359    c0,19.581,6.1,39.759,32.654,35.457l154.561-29.073l-9.639,63.268l110.875-82.335l65.695-12.019    c23.564-4.135,36.643-15.875,36.643-35.457V98.137C451.395,78.556,434.16,62.68,414.578,62.68z M354.711,235.385    c-5.002,53.956-55.426,97.697-112.623,97.697c-57.203,0-99.508-43.741-94.506-97.697c5.004-53.969,55.428-97.711,112.623-97.711    C317.408,137.674,359.721,181.416,354.711,235.385z M215.049,282.888c-3.109-20.511-6.363-56.128-9.063-76.632    c-1.416-10.769,4.857-14.876,15.098-12.905c28.838,5.537,82.398,16.59,82.398,16.59c11.623,1.416,17.576,11.9,6.578,20.643    c-19.873,15.793-56.912,48.904-78.846,61.547C224.207,296.168,216.229,290.638,215.049,282.888z"
        />
      </g>
</svg>

我的问题是:如何更新x和y坐标,以便该组仍在接触线?

2 个答案:

答案 0 :(得分:2)

这是我的解决方案:我将路径放入g元素内,并缩放路径。我正在使用theg.getBBox()值来更改<use>元素的x和y。

let bb = testg.getBBox()
let x = 315 - bb.x - bb.width/2;
let y = 176 - bb.y;
theUse.setAttributeNS(null,"x", x);
theUse.setAttributeNS(null,"y", y);

theRange.addEventListener("input", ()=>{
  thePath.setAttributeNS(null, "transform", `scale(${parseInt(theRange.value)/100})`)
  let bb = testg.getBBox()
  let x = 315 - bb.x - bb.width/2;
  let y = 176 - bb.y;
  theUse.setAttributeNS(null,"x", x);
  theUse.setAttributeNS(null,"y", y);
})
<input id="theRange" type="range" value ="25" /><svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  width="630"
  height="430"
>
  
  <defs>   
    <g id="testg">
    <path id="thePath" transform="scale(.45)"
          fill="rgba(198, 199, 205, 1.0)"
          d="M414.578,62.68L93.932,122.853c-22.91,4.448-33.326,15.876-33.326,35.457v221.359    c0,19.581,6.1,39.759,32.654,35.457l154.561-29.073l-9.639,63.268l110.875-82.335l65.695-12.019    c23.564-4.135,36.643-15.875,36.643-35.457V98.137C451.395,78.556,434.16,62.68,414.578,62.68z M354.711,235.385    c-5.002,53.956-55.426,97.697-112.623,97.697c-57.203,0-99.508-43.741-94.506-97.697c5.004-53.969,55.428-97.711,112.623-97.711    C317.408,137.674,359.721,181.416,354.711,235.385z M215.049,282.888c-3.109-20.511-6.363-56.128-9.063-76.632    c-1.416-10.769,4.857-14.876,15.098-12.905c28.838,5.537,82.398,16.59,82.398,16.59c11.623,1.416,17.576,11.9,6.578,20.643    c-19.873,15.793-56.912,48.904-78.846,61.547C224.207,296.168,216.229,290.638,215.049,282.888z"
          /></g>
  </defs>
  <rect
    rx="0"
    ry="0"
    width="100%"
    height="100%"
    fill="rgba(92, 95, 108, 1.0)"
  />
    <line x1="0" y1="176" x2="630" y2="176" style="stroke:rgb(255,0,0);stroke-width:2" />
<line x1="315" y1="0" x2="315" y2="100%" style="stroke:rgb(255,0,0);stroke-width:2" />
       <use id="theUse" xlink:href="#testg"  y="161" />

</svg>

答案 1 :(得分:1)

  1. 暂时完全删除transform属性
  2. 找出路径元素的左上角
  3. 移动路径,使其左上角位于(0,0)
  4. 定义一个将组翻译的变换属性到您希望左上角永久放置的位置
  5. 在transform属性的右侧
  6. 中,定义您选择的 scale

<svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  width="630"
  height="430"
>
  <rect
    rx="0"
    ry="0"
    width="100%"
    height="100%"
    fill="rgba(92, 95, 108, 1.0)"
  />
    <line x1="0" y1="176" x2="630" y2="176" style="stroke:rgb(255,0,0);stroke-width:2" />
      <g
        transform="translate(260 176) scale(0.25)"
        style="outline: black solid 2px;"
      >
        <path transform="translate(-60.6, -62.7)"
          fill="rgba(198, 199, 205, 1.0)"
          d="M414.578,62.68L93.932,122.853c-22.91,4.448-33.326,15.876-33.326,35.457v221.359    c0,19.581,6.1,39.759,32.654,35.457l154.561-29.073l-9.639,63.268l110.875-82.335l65.695-12.019    c23.564-4.135,36.643-15.875,36.643-35.457V98.137C451.395,78.556,434.16,62.68,414.578,62.68z M354.711,235.385    c-5.002,53.956-55.426,97.697-112.623,97.697c-57.203,0-99.508-43.741-94.506-97.697c5.004-53.969,55.428-97.711,112.623-97.711    C317.408,137.674,359.721,181.416,354.711,235.385z M215.049,282.888c-3.109-20.511-6.363-56.128-9.063-76.632    c-1.416-10.769,4.857-14.876,15.098-12.905c28.838,5.537,82.398,16.59,82.398,16.59c11.623,1.416,17.576,11.9,6.578,20.643    c-19.873,15.793-56.912,48.904-78.846,61.547C224.207,296.168,216.229,290.638,215.049,282.888z"
        />
      </g>
</svg>

那么,如何找到path元素的左上角?将其加载到浏览器中,然后在Javascript命令行上执行

document.querySelector('path').getBBox()