[AS3]翻译国外文章AS3中修改mc的注册点常用于相册
这是我认为每个人都希望知道如何在ActionScript中实现的:在运行时动态改变一个影片剪辑或精灵的注册点。我 想知道这个很长时间了,也在网上看到了一些不太满意的解决方案。然而,它们为我开发自己的解决方案提供了有价值的线索,所以,我并不是在这里打击任何人。 你能找到的最主流的解决方案之一是链接库符号到一个类,然后,你获取诸如rotation2、x2、y2、scaleX2、scaleY2等属性,你知道 的。
然而,这不是我想要的……
我不想使用以2结尾的新属性,因为这看 起来不自然。相反,我需要一个函数,我可以调用它改变注册点,然后只需要使用正常的影片剪辑属性:rotation、x、y、scaleX和 scaleY。如果影片剪辑注册点可以在第一个地方永久的移动,后续的转换就可以从新的注册点开始了。我需要一些东西可以直接应用到已有的影片剪辑实例而 无需先链接该影片剪辑到一个自定义的类。
如果不是必须的,我也不想非使用Matrix类来处理。并不是说使用它不好,但是如果有更简单的解决方案,显然我会更喜欢它。
当 我在线查阅时,经常被很多人的断言所打击——影片剪辑的注册点不能移动(从技术上讲,确实如此)!然而,我也看到许多在线的示例,人们已经设法完成了它。 那么,你是如何移动一个注册点的?我必须知道!我看了许多论坛上的许多贴子,沮丧者即使死了都想知道答案。事实上,改变注册点是如此基本的东西,你可能想 ActionScript语言内建了解决方案,但没有。
这是一个技术性问题
像 我刚才说的,你确实不能移动一个注册点。对任何精灵或影片剪辑来说,注册点的位置永远是(0,0)。这是一个技术性问题,证明我们都在问一个错误的问题。 如果你不能移动一个注册点,问如何实现它就没有任何意义了。然而当你不能从技术上移动注册点的时候,你却可以参照它来移动其他所有的东西。这就是答案的关 键!你不能移动注册点,但你可以从效果上移动它!通过移动其他的一切!
这类似于你如何用Flash创作工具改变 注册点。你永远不会移动注册点自身,因为那是不可能的。相反,你相对该点移动所有的图形内容。假设你在舞台上有一个影片剪辑实例,其注册点在左上角,你想 让注册点在中间。你将编辑这个剪辑:进入剪辑内部,选择所有的图形并让他们在注册点上居中。然后回到场景1,你会发现舞台上的对象从先前的位置移动了,因 为你改变了它的内部,你会调整它的x和y位置来补偿刚才产生的变化。或许你已经这样做过。步骤就像这样:
1. 在剪辑内部,编辑模式下,向左向上移动剪辑内每一个图形内容
2. 回到场景,向右向下移动影片剪辑相同的数量
注意你并没有移动注册点本身,但你向左上方移动了影片剪辑的所有显示子对象,并且最后回到场景1,你向右下方移动了影片剪辑进行补偿。
所以如果我们想在程序中动态改变注册点,我们基本上要进行同样的处理,只使用代码。我不再让你有任何悬念。为此我花了一整天的大部分,完成后,我的函数只有11行(如果你不将注释计算在内)!但它起作用了,并且工作很棒!我很高兴与您共享!
噢, 我差点忘了。我也想要一个解决方案,它不管注册点最初设定在哪里,我也做到了!这个函数很容易使用。第一个参数是你要影响的对象,该对象必须是一个显示对 象容器(DisplayObjectContainer),所以它可以是Sprite、MovieClip,甚至Loader实例。第二个和第三个参数就 是你想要的新注册点的x和y值——相对于剪辑图形内容的左上角。而且,就像我所说的,代码工作时忽略注册点现在在哪里。下页是这个函数(未做处理,保留作 者原汁原味):
- function setRegPoint(obj:DisplayObjectContainer, newX:Number, newY:Number):void {
- //get the bounds of the object and the location
- //of the current registration point in relation
- //to the upper left corner of the graphical content
- //note: this is a PSEUDO currentRegX and currentRegY, as the
- //registration point of a display object is ALWAYS (0, 0):
- var bounds:Rectangle = obj.getBounds(obj.parent);
- var currentRegX:Number = obj.x - bounds.left;
- var currentRegY:Number = obj.y - bounds.top;
- var xOffset:Number = newX - currentRegX;
- var yOffset:Number = newY - currentRegY;
- //shift the object to its new location--
- //this will put it back in the same position
- //where it started (that is, VISUALLY anyway):
- obj.x += xOffset;
- obj.y += yOffset;
- //shift all the children the same amount,
- //but in the opposite direction
- for(var i:int = 0; i < obj.numChildren; i++) {
- obj.getChildAt(i).x -= xOffset;
- obj.getChildAt(i).y -= yOffset;
- }
- }
注释很好的解释了大部分是怎么回事,这是一个更充分的解释:
getBounds() 函数用来获取剪辑的边界框。剪辑的x和y属性给出了当前注册点的位置。暂时让我们只考虑x方向:bounds.left值是图形内容的最左边的位置,剪辑 的x属性给出了注册点的x位置。这两个值都来自父视图(坐标空间),这两个数之间的差异给出了注册点相对图形内容最左边的当前位置,然后从我们要使用的新 x值中扣除该(差)值,存储在变量xOffset中。剩下的部分是将所有的子对象向左移动这个数值,最后再讲剪辑自身向右移动这个数值。在y方向上保持同 样的处理。
在示例文件中,舞台上有一个称为book的影片剪辑实例。初始时特意使book影片剪辑的注册点不在左上角,也不在中心。然后setRegPoint()函数将注册点设定到中心,这仅需要一次简单的函数调用。当book被点击时,其scaleX属性被乘以-1,这是众所周知的进行水平翻转技术。因为函数调用已经设置注册点到中心,缩放使用了新的注册点来进行。book影片剪辑内部还有一对shape,用来演示所有的内容进行了移动。下页是完成任务的辅助代码(联合上面的函数代码):
- book.addEventListener(MouseEvent.CLICK, bookClicked);
- function bookClicked(event:MouseEvent):void {
- book.scaleX *= -1;
- }
- //set the registration point for the book object in the middle instead:
- setRegPoint(book, book.width / 2, book.height / 2);
下页是在线演示
http://theflashconnection.com/sites/default/files/Jody%20Hall/dynamic_registration_point.fla
注意:附件文件是CS4格式的。它演示了使用这面的函数是如何的容易。舞台上的影片剪辑动态修改了它的注册点。之后的所有变换都将使用新的点替代原来的那个。如果你在使用CS3,不能打开这个文件,但不用做太多,我在上面已经给出了全部的代码,只要复制、粘贴到你自己的文件,应用到你自己的影片剪辑实例。享用!
热门文章推荐
- [HLS]做自己的m3u8点播系统使用HTTP Live Streaming(HLS技术)
- [FMS]FMS流媒体服务器配置与使用相关的介绍
- [AS3]什么是M3U8,与HTML5的区别是什么
- AS2.0 让flash自适应全屏,并且不自动缩放
- [AS3]as3.0的sound类常用技巧整理
- [AS3]as3与ByteArray详解、ByteArray介绍、ByteArray用法
- 关于RTMP,RTMPT,RTMPS,RTMPE,RTMPTE协议的介绍
- [JS]分享浏览器弹出窗口不被拦截JS示例