定位 SVG 元素

发布于 2024-08-30 18:13:59 字数 936 浏览 6 评论 0原文

在第一次使用 SVG 的过程中(使用 Raphael 库),我运行了解决在画布上定位动态元素的问题,使其完全包含在画布中。我想做的是随机放置n 个单词/短语。

由于文本是可变的,它的位置也需要是可变的,所以我正在做的是:

  1. 最初在 0,0 点创建没有不透明度的文本。
  2. 使用 text.getBBox().width 检查绘制文本元素的宽度。
  3. 将新的 x 坐标设置为 Math.random() * (canvas_width - ( text_width/2 ) - pad)
  4. 将文本的 x 坐标更改为新设置的值 (text.attr( 'x', x ) )。
  5. 将文本的不透明度属性设置为 1。

我将是第一个承认我的数学敏锐度有限的人,但这看起来非常简单。不知何故,我仍然发现文本超出了画布的右边缘。为了简单起见,我通过将最小 x 值添加到 Math.random() 结果中删除了也设置最小 x 值的位。但它就在那里,我在画布的前缘看到了同样的问题。

我的理解(事实上是这样),Math.random() 位会生成一个 0 到 1 之间的数字,然后将其乘以某个数字(在我的例子中,画布宽度 -文本宽度的一半 - 一些任意填充)以获得外部边界。我将文本的宽度分成两半,因为它在网格上的位置设置在其中心。

我希望我只是盯着这个问题太久了,但是我的数学是否生锈了,或者我是否误解了 Math.random()、SVG 的行为、文本或该解决方案背后的其他任何内容?

In the course of toying with SVG for the first time (using the Raphael library), I've run into a problem positioning dynamic elements on the canvas in such a way that they're completely contained within the canvas. What I'm trying to do is randomly position n words/short phrases.

Since the text is variable, its position needs to be variable as well so what I'm doing is:

  1. Initially creating the text at point 0,0 with no opacity.
  2. Checking the width of the drawn text element using text.getBBox().width.
  3. Setting a new x coordinate as Math.random() * (canvas_width - ( text_width/2 ) - pad).
  4. Altering the x coordinate of the text to the newly set value (text.attr( 'x', x ) ).
  5. Setting the opacity attribute of the text to 1.

I'll be the first to admit that my math acumen is limited, but this seems pretty straightforward. Somehow, I still end up with text running off beyond the right edge of my canvas. For simplicity above, I removed the bit that also sets a minimum x value by adding it to the Math.random() result. It is there, though, and I see the same problem on the leading edge of the canvas.

My understanding (such as it is), is that the Math.random() bits would generate a number between 0 and 1 which could then be multiplied by some number (in my case, the canvas width - half of the text width - some arbitrary padding) to get the outer bound. I'm dividing the width of the text in half because its position on the grid is set at its center.

I hope I've just been staring at this for too long, but is my math that rusty or am I misunderstanding something about the behavior of Math.random(), SVG, text or anything else that's under the hood of this solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

故事灯 2024-09-06 18:13:59

答案就是我对 Math.random() 方程的思考。它并不像乘以最大值然后加上最小值那么简单(当然)。它实际上更像是在容器的右端建立一个双宽的排水沟,然后移动整个边界以吃掉该排水沟的一半:

var x  = Math.random() * ( canvas_w - 20 - ( text.getBBox().width ) ) + ( text.getBBox().width/2 + 10 );

用英语......

您必须将要考虑的每个元素的宽度加倍,以便您可以将整个范围向后移动该宽度,以保持良好且平等。就我而言,我想占文本宽度的一半加上 10 的填充。

例如...

给定画布宽度为 500,文本宽度为 50< /code> 和所需的“间距”10,我创建一个介于 0430 之间的随机数 (500 - 20 - 50)。通过添加回我需要考虑的宽度 - 文本宽度的一半 (25) + 填充 (10) - 我留下了一个随机数介于 35465 之间。如果我的文本位于该边界的外边缘,则它只能到达 10490

希望这足够清楚,有意义。虽然当我思考时这是有道理的,但这种事情对我来说并不是立即直观的,所以我确信我会经常回到这里。

The answer turned out to be how I was thinking about the Math.random() equation. It's not quite as simple as multiplying by the max and then adding the minimum value (of course). It's really more like establishing a double wide gutter on the right end of the container and then shifting the entire boundary to eat up half of that gutter:

var x  = Math.random() * ( canvas_w - 20 - ( text.getBBox().width ) ) + ( text.getBBox().width/2 + 10 );

In English...

You have to double the width of each element you want to account for so you can shift the entire range back by that width to keep things nice and equal. In my case, I want to account for half of the width of the text plus a padding of 10.

For example...

Given a canvas width of 500, a text width of 50 and a desired "gutter" of 10, I create a random number between 0 and 430 (500 - 20 - 50). By adding back the widths I need to account for--half of the text width (25) + the padding (10)--I'm left with a random number between 35 and 465. If my text sits at the outer edges of that boundary, it can only reach as far as the 10 or 490.

Hopefully that's clear enough to make sense. Although it makes sense when I think about it, this kind of thing isn't immediately intuitive to me, so I'm sure I'll be referring back here often.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文