我计划为我的媒体播放器安排简单的进度条,绘制一个彩色矩形,然后根据需要更改其宽度属性。从视觉上看,它看起来不错——缩放得很好(我无法用零宽度绘制它,所以我指定了最小值 0.1)。
但真正的问题是不同的,而且看起来很奇怪,或者至少绝对不明显。由于我需要监视用户对该进度条的点击,以支持媒体流中的查找操作,我想 - 我会检测单击事件,将 x 坐标作为距父 DisplayObject 的偏移量,重新计算时间并进行查找。现在事实证明,event.localX 并没有真正与 Sprite 一起“缩放”。正如我所说,进度条最右边的 x 坐标最初是 0.1,并且无论实际进度条变得多宽 - 5、100、1000,它都会保持这种状态(!)。如果您单击进度条最右边的像素,它将是 - 0.1!
嗯?……
我显然做错了什么。也许有一个方法,比如 -refreshCooperatives() 之类的?是什么?..
I planned to arrange simple progress bar for my media player, drawing a colored rectangle and then changing it's width property as needed. Visually it looks ok - scales nicely (I could not draw it with zero width, so I assigned minimal value of 0.1).
Real problem is different though, and seems very weird, or at least absolutely non obvious. Since I need to monitor user clicks on that progress bar, to support seek operation in media stream, I thought - I would detect click event, take x coordinate as an offset from parent DisplayObject, recalculate into time and make a seek. Now it turns out, that event.localX doesn't really "scale" along with the Sprite. As I said the most right x coordinate for the progress bar initially is 0.1, and it stays that way (!) no matter how wide will the actual bar become - 5, 100, 1000. If you click the most right pixel of the bar, it will be - 0.1!
Huh?..
I obviously do something wrong. Maybe there is a method, like - refreshCoordinates() or something? What is it?..
发布评论
评论(3)
了解为什么会发生这种情况对于理解 Flash 的工作原理非常重要。关键是要认识到每个显示对象都有自己的坐标系,当您的范围位于该系统内时,对象本身是否旋转、缩放等并不重要。如果您生活在条形图形内,您就知道了是图形的宽度为 0.1 像素,并且单击发生在右边框上。您不知道您所在的显示对象是否已在层次结构中的某个位置被拉伸或变换。这就是您正在查看的事件属性称为
localX
的原因 - 它告诉您在该显示对象中本地发生点击的位置。这就是为什么在这种情况下,通常会将条形图形设置为 100 像素宽,然后在舞台上根据需要调整其大小。如果图形内部为 100 像素,并且您检测到该范围内的点击,则可以将
localX
视为百分比。如果您随后重新设计页面并更改栏的视觉宽度,则无需触摸代码。顺便说一句,如果您想将位置从一个坐标系转换到另一个坐标系,只需同时使用
localToGlobal
和globalToLocal
即可。也就是说:(或者解决问题的另一种方法是简单地捕获显示层次结构中更上方的单击事件,其中条形实际上是 100px 宽,而不是在图形内部,但不是。)
最后一个注意事项:不要不要养成将图形设为 0.1 像素宽的习惯。对于与渲染相关的值(例如
x
、rotation
等),Flash 有时会出于性能原因将某些值四舍五入到低于视觉上可区分的尺寸。只需将对象设置为 100px 或其他大小,然后将其缩小到您喜欢的大小即可。Understanding why this happens is very important to understanding how Flash works. The key is to realize that every display object has its own coordinate system, and when your scope is inside that system it doesn't matter if the object itself is rotated, scaled, etc. If you live inside the bar graphic, all you know is that the graphic is 0.1 pixel wide, and that a click occurred on the right border. You have no idea whether the display object you live in has been stretched or transformed somewhere up the hierarchy. That's why the event property you're looking at is called
localX
- it tells you where the click occurred locally, within that display object.This is why, in this situation, it's very common to make the bar graphic 100 pixels wide, and then resize it however you want on the stage. If the graphic is internally 100px, and you detect clicks within that scope, then you can treat
localX
like a percentage. And if you then redesign the page and change the visual width of the bar, you don't have to touch the code.Incidentally, if you want to transform a location from one coordinate system to another, just use
localToGlobal
andglobalToLocal
together. That is:(Or another way to fix your problem would be to simply capture the click events further up the display hierarchy, where the bar really is 100px wide, rather than inside the graphic where it isn't.)
One final note: don't get in the habit of making graphics 0.1 pixels wide. With values that are related to rendering, like
x
,rotation
, and so on, Flash sometimes rounds things off for performance reasons, below sizes that are visually distinguishable. Just make the object 100px or whatever, and transform it down to as small as you like.我猜这与全球坐标与本地坐标有关。为什么不尝试
LocalToGlobal
方法? 这里是一篇解释该功能的文章。I am guessing this has something to do with Global vs Local co-ordinates. Why don't you try
LocalToGlobal
method? Here is an article which explains the function.我以前从未遇到过这种情况,但看起来确实很奇怪。我能够通过
graphics
对象重现绘图问题,然后更改精灵宽度。无论如何,有一个简单的解决方法。预先绘制最大宽度的条形图,然后缩放它。像这样的事情:
我使用输入帧来模拟进度,但重点是您更新精灵的
scaleX
而不是width
来反映进度。I've never come across this before but it sure looks weird. I was able to reproduce the problem drawing through the
graphics
object and then changing the sprite width.Anyway, there's a simple workaround. Draw your bar with the max width upfront and then scale it. Something like this:
I'm using an enter frame to simulate progress, but the point is that you update the
scaleX
instead of thewidth
of the sprite to reflect the progress.