我正在编写一个JSFL导出器,以导出Flash动画为一种格式,可以在自定义播放器中重放。导出器基本上迭代通过时间线和每个关键帧处的所有元素,并写出元素的名称、位置、旋转、缩放和局部偏移。这些数据被读取到自定义播放器中,该播放器将数据提供给sprite引擎以重新创建动画的每一帧。
我想要做的是检测给定的元素是否已经翻转(即在Flash中选择元素(一个符号),然后修改->变换->水平翻转),以便导出器也可以包括该信息,允许播放器中的精灵引擎翻转纹理的UV以复制Flash中发生的事情。这对于(比方说)使用一个符号作为角色的右手,并只是将其翻转为他们的左手,而不是必须创建一个全新的符号,这将是有用的。
不幸的是,我看不到任何方法来找出这个信息。我所拥有的元素信息似乎都不意味着发生了任何类型的翻转。如何检测翻转?如果不能在算法上完成,我会满足于动画制作人手动指示符号已经翻转(例如,通过创建某种插件,给他们一个用setPersistentData()向元素写入值的勾选框),但我也不知道如何制作这种插件。帮助!
发布于 2011-10-07 19:05:31
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。
发布于 2011-10-03 20:31:43
scaleX或矩阵不能工作吗?http://help.adobe.com/en_US/flash/cs/extend/WS5b3ccc516d4fbf351e63e3d118a9024f3f-7f6c.html
发布于 2017-02-03 04:08:31
以下是电德鲁伊的解决方案,包含了几个方便的功能:
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));谢谢你的密码电德鲁伊。
https://stackoverflow.com/questions/7634901
复制相似问题