JSFL:检测元素何时被翻转
Posted
技术标签:
【中文标题】JSFL:检测元素何时被翻转【英文标题】:JSFL: Detecting when an Element has been flipped 【发布时间】:2011-11-29 21:33:23 【问题描述】:我正在用 JSFL 编写一个导出器,将 Flash 动画导出为可以在自定义播放器中回放的格式。导出器基本上遍历时间线和每个关键帧的所有元素,并写出元素的名称、位置、旋转、缩放和局部偏移。这些被读取到自定义播放器中,该播放器将数据馈送到精灵引擎以重新创建动画的每一帧。
我想要做的是检测给定元素是否已被翻转(即在 Flash 中选择元素(一个符号),然后修改->变换->水平翻转),以便导出器可以包含该元素信息,允许播放器中的精灵引擎翻转纹理的 UV 以复制 Flash 中发生的事情。这对于(比如说)使用一个符号作为角色的右手并将其翻转为左手很有用,而不必创建一个全新的符号。
很遗憾,我无法找到任何方法来找出这些信息。我所掌握的有关元素的任何信息似乎都没有暗示发生了任何类型的翻转。如何检测翻转?如果不能通过算法完成,我会接受动画师必须手动指示符号已被翻转(通过创建某种插件,为他们提供一个复选框,该复选框使用 setPersistentData( ),例如),但我也不知道如何制作那种插件。救命!
【问题讨论】:
如果在 JSFL api 中不可用,另一种方法是直接从 FLA 中提取元素设置。首先,确保您的 FLA 保存为 Flash CS5 (11.0) 格式,将文件扩展名从 .fla 重命名为 .zip,提取 XML,然后在 XML 中找到元素,看看是否有您需要的信息。跨度> 【参考方案1】:scaleX 或矩阵不起作用吗? http://help.adobe.com/en_US/flash/cs/extend/WS5b3ccc516d4fbf351e63e3d118a9024f3f-7f6c.html
【讨论】:
scaleX 不起作用,但 Matrix 在经过一些相当痛苦的提取后会起作用。如果您有兴趣,请参阅下文。【参考方案2】:scaleX 不起作用,它似乎总是给出一个正值。最后我不得不对矩阵做这个来得到答案。这是基于我们知道矩阵总是包含一个 2D 旋转的想法,并且我们知道角度,所以我们可以摆脱矩阵元素的旋转,只留下比例。这很可怕,但它似乎有效。
此外,旋转有时会显示为 NaN,尤其是当元素被翻转时。使用 skewX 的值似乎适用于您知道不倾斜的东西,但我希望我的导出器能够处理倾斜的元素,所以我认为这可能是这里另一个问题的基础。
var rotationRadians;
if(isNaN(someElement.rotation))
rotationRadians = someElement.skewX * Math.PI / 180;
else
rotationRadians = someElement.rotation * Math.PI / 180;
var sinRot = Math.sin(rotationRadians);
var cosRot = Math.cos(rotationRadians);
var SOME_EPSILON = 0.01;
var flipScaleX, flipScaleY;
if(Math.abs(cosRot) < SOME_EPSILON)
// Avoid divide by zero. We can use sine and the other two elements of the matrix instead.
flipScaleX = (someElement.matrix.b / sinRot);
flipScaleY = (someElement.matrix.c / -sinRot);
else
flipScaleX = someElement.matrix.a / cosRot;
flipScaleY = someElement.matrix.d / cosRot;
flipScaleX 如果水平翻转,则为 ~-1,否则为 ~1。如果垂直翻转,flipScaleY 为 ~-1,否则为 ~1。
【讨论】:
这很有帮助。当旋转为 NaN 时,我不会想到检查 Skew!不禁想到一定有更好的方法。【参考方案3】:这里是 Electrodruid 的解决方案,包含几个便利功能:
function isFlippedHorizontally (element)
return Math.round(getFlip(element)[0]) == -1;
function isFlippedVertically (element)
return Math.round(getFlip(element)[0]) == -1;
function getFlip (element)
var rotationRadians;
if(isNaN(element.rotation))
rotationRadians = element.skewX * Math.PI / 180;
else
rotationRadians = element.rotation * Math.PI / 180;
var sinRot = Math.sin(rotationRadians);
var cosRot = Math.cos(rotationRadians);
var SOME_EPSILON = 0.01;
var flipScaleX, flipScaleY;
if(Math.abs(cosRot) < SOME_EPSILON)
// Avoid divide by zero. We can use sine and the other two elements of the matrix instead.
flipScaleX = (element.matrix.b / sinRot);
flipScaleY = (element.matrix.c / -sinRot);
else
flipScaleX = element.matrix.a / cosRot;
flipScaleY = element.matrix.d / cosRot;
return [flipScaleX, flipScaleY];
用法示例:
var element = currentDoc.getTimeline().layers[0].frames[0].elements[0];
trace("Element is flipped:" + isFlippedHorizontally(element));
感谢代码electrodruid。
【讨论】:
以上是关于JSFL:检测元素何时被翻转的主要内容,如果未能解决你的问题,请参考以下文章
检测 iOS UICollectionCell 何时离开屏幕