在SVG组中将多个路径对齐到中心。

huangapple go评论60阅读模式
英文:

Align multiple Paths inside SVG Group to center

问题

为我正在进行的项目,我必须动态生成多个由路径组成的圆。这些圆的大小在两个设定的数字之间随机(例如750 <-> 850)。我试图将这些圆垂直和水平居中到SVG组的中间,但我不太确定如何实现这一点。

这是负责生成路径的代码片段:

const svgViewportWidth = 900;
const svgViewportHeight = 1000;
const randomSize = generateRandomNumberInRange(750, 850);

return (
   <path key={`path-${aIndex}`} 
      d={`M ${(svgViewportWidth - randomSize) / 2}, ${svgViewportHeight - (randomSize - 320)}
            a 1,1 0 1,1 ${randomSize},0
            a 1,1 0 1,1 -${randomSize},0z`} id={`path-${aIndex}`}></path>
       )

上述片段的“完整输出”可能如下所示:
https://jsfiddle.net/c6phn8ue/

从jsfiddle中可以看到,圆在左下角相交。最终我想要实现的是使每个圆都在中心对齐,这意味着这些圆永远不会相交。

我假设我需要以某种方式获取SVG和圆之间的差距,然后使用它来对齐圆,但我对如何做到这一点感到有些困惑。

英文:

For a project i'm working on, i have to dynamically generate multiple circles, composed of paths.
These circles have random sizes between two set numbers (eg. 750 <-> 850).
I'm trying to vertically and horizontally center these circles to the middle of the SVG Group, but i'm not quite sure how i would achieve this.

Here is the code snippet responsible for generating the paths:

    const svgViewportWidth = 900;
    const svgViewportHeight = 1000;
    const randomSize = generateRandomNumberInRange(750, 850);

    return (
       &lt;path key={`path-${aIndex}`} 
          d={`M ${(svgViewportWidth - randomSize) / 2}, ${svgViewportHeight - (randomSize - 320)}
                a 1,1 0 1,1 ${randomSize},0
                a 1,1 0 1,1 -${randomSize},0z`} id={`path-${aIndex}`}&gt;&lt;/path&gt;
           )

"Complete output" of above snippet could look like this:
https://jsfiddle.net/c6phn8ue/

As can be seen in the fiddle, the circles cross each other on the bottom left corner. Ultimately what i'm trying to achieve is to have each circle aligned in the center, meaning that the circles would never cross each other.

I am assuming i'll somehow need to get the delta between the SVG and the circle and then align the circle using that, but i'm somewhat at a loss as to how to do that.

答案1

得分: 0

更自解释的变量名有助于理解代码。

随机数将变为直径 d

let d = generateRandomNumberInRange(750, 850);

因此半径将为 let r=d/2

第一个 M x 坐标将始终位于 cx

let [cx, cy] = [svgViewportWidth/2, svgViewportHeight/2];

现在我们有了新 <path> 元素的所有必要坐标。

let newPath = `<path  d="
M ${ cx } ${ cy-r }
a 1 1 0 1 1  0 ${d}
a 1 1 0 1 1  0 -${d} z "/>`;
英文:

It's easier to understand when you assign more self-explanatory variable names.

The random number will become the diameter d

  let d = generateRandomNumberInRange(750, 850);  

and consequently the radius let r=d/2

Th first M x coordinate will always be at cx

let [cx, cy] = [svgViewportWidth/2, svgViewportHeight/2];  

Now we have all necessary coordinates for the new &lt;path&gt;element:

let newPath = `&lt;path  d=&quot;
M ${ cx } ${ cy-r }
a 1 1 0 1 1  0 ${d}
a 1 1 0 1 1  0 -${d} z &quot;/&gt;`;

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-js -->

const svgViewportWidth = 900;
const svgViewportHeight = 1000;

for (let i = 0; i &lt; 5; i++) {
  let [cx, cy] = [svgViewportWidth/2, svgViewportHeight/2];
  let d = generateRandomNumberInRange(750, 850);
  let r = d/2;
  let newPath = `
 &lt;path  d=&quot;
M ${ cx } ${ cy-r }
a 1 1 0 1 1  0 ${d}
a 1 1 0 1 1  0 -${d}
&quot;/&gt;`;
  
  svgGroup.insertAdjacentHTML(&#39;beforeend&#39;, newPath); 

}

function generateRandomNumberInRange(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}

<!-- language: lang-html -->

&lt;svg viewBox=&quot;0 0 900 1000&quot; fill=&quot;none&quot; stroke=&quot;black&quot; class=&quot;svg&quot;&gt;
  &lt;g class=&quot;svgGroup&quot; id=&quot;svgGroup&quot;&gt;
  &lt;/g&gt;
&lt;/svg&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年4月6日 21:09:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75949911.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定