Actionscript 3 对';嵌套在其他displayObjects中,并将克隆添加到相同位置、旋转等的阶段层
我希望能够获取嵌套在其他变换的DisplayObject(旋转、缩放、拉伸对象)中的DisplayObject的副本,并能够将其标记回相同的视觉位置,但在舞台层上。从本质上讲,能够制作嵌套DisplayObject的克隆,但能够将克隆添加到舞台层,同时使其(视觉上)与原始对象完全对齐(相同的位置、比例、旋转) 我一直在从事以下工作:Actionscript 3 对';嵌套在其他displayObjects中,并将克隆添加到相同位置、旋转等的阶段层,actionscript-3,matrix,bitmap,transform,bitmapdata,Actionscript 3,Matrix,Bitmap,Transform,Bitmapdata,我希望能够获取嵌套在其他变换的DisplayObject(旋转、缩放、拉伸对象)中的DisplayObject的副本,并能够将其标记回相同的视觉位置,但在舞台层上。从本质上讲,能够制作嵌套DisplayObject的克隆,但能够将克隆添加到舞台层,同时使其(视觉上)与原始对象完全对齐(相同的位置、比例、旋转) 我一直在从事以下工作: // draw the pixels of a displayobject into a new bitmap object var bitmapData:Bitm
// draw the pixels of a displayobject into a new bitmap object
var bitmapData:BitmapData = new BitmapData(nestedSprite.width, nestedSprite.height, true, 0xFFFFFF);
var bitmap:Bitmap = new Bitmap(bitmapData);
bitmapData.draw(nestedSprite);
// put the copy on the top most layer
stage.addChild(bitmap);
// position the copy to perfectly overlay the original, but on the top stage layer
var point:Point = nestedSprite.localToGlobal(new Point(0, 0));
bitmap.x = point.x;
bitmap.y = point.y;
但这只适用于其父对象未被转换的displayObjects;以及直接位于(0,0)
原点的DisplayObjeTC。对于居中对齐的对象或缩放的父对象等,它会分开
我知道我可以将矩阵参数添加到
.draw()
方法,以及剪切矩形,然后缩放位图,或者设置一个对象到另一个对象的变换,或者使用.transform.concatenatedMatrix
,或者使用nestedObject.getBounds(null)
,或者nestedSprite.getBounds(nestedSprite)
,但不幸的是,我陷入了对这一问题进行试错编程的过程中,由于变量很多,这从来都不是解决编程问题的好方法。您是否尝试过将父级转换传递到绘图?将变换矩阵作为第二个参数
如果你有一个关于父对象的句柄,你可以使用这样的东西
bitmapData.draw(nestedSprite, parent.transform.matrix);
我相信这个函数应该可以工作,唯一的额外步骤是偏移连接的矩阵,这样目标将在位图上以左上角(0,0)绘制,即使其原点在其他地方。希望其余的都是不言自明的,但是如果有什么不合理的地方,我可以添加更多的注释
function createBitmapClone(target:DisplayObject):Bitmap {
var targetTransform:Matrix = target.transform.concatenatedMatrix;
var targetGlobalBounds:Rectangle = target.getBounds(target.stage);
var targetGlobalPos:Point = target.localToGlobal(new Point());
// Calculate difference between target origin and top left.
var targetOriginOffset:Point = new Point(targetGlobalPos.x - targetGlobalBounds.left, targetGlobalPos.y - targetGlobalBounds.top);
// Move transform matrix so that top left of target will be at (0, 0).
targetTransform.tx = targetOriginOffset.x;
targetTransform.ty = targetOriginOffset.y;
var cloneData:BitmapData = new BitmapData(targetGlobalBounds.width, targetGlobalBounds.height, true, 0x00000000);
cloneData.draw(target, targetTransform);
var clone:Bitmap = new Bitmap(cloneData);
// Move clone to target's global position, minus the origin offset.
clone.x = targetGlobalPos.x - targetOriginOffset.x;
clone.y = targetGlobalPos.y - targetOriginOffset.y;
return clone;
}
不幸的是,如果DisplayObjects上有任何过滤器,pixelBounds似乎会返回原点(0,0),这显然会破坏东西
编辑:将target.transform.pixelBounds
替换为target.getBounds(target.stage)
,这是一个轻微的改进。如果存在过滤器,这将保持位置正确,但是父显示对象上的过滤器仍然不包括在内,并且目标上的过滤器可能与位图的边缘重叠。我不确定是否有一个简单的方法来解决这个问题
更新:Jimmi Heiserman发现,如果swf被缩放,该功能将被破坏。无stage.scaleMode=StageScaleMode.NO_SCALE
但是,stageWidth
和stageHeight
参数似乎保持不变,因此我发现的唯一(相当棘手的)解决方法是添加一个“未缩放”测试精灵,并使用其连接矩阵来调整克隆的位置和比例:
function createScaledBitmapClone(target:DisplayObject):Bitmap {
var targetTransform:Matrix = target.transform.concatenatedMatrix;
var targetGlobalBounds:Rectangle = target.getBounds(target.stage);
var targetGlobalPos:Point = target.localToGlobal(new Point());
// Calculate difference between target origin and top left.
var targetOriginOffset:Point = new Point(targetGlobalPos.x - targetGlobalBounds.left, targetGlobalPos.y - targetGlobalBounds.top);
// Create a test Sprite to check if the stage is scaled.
var testSprite:Sprite = new Sprite();
target.stage.addChild(testSprite);
var testMatrix:Matrix = testSprite.transform.concatenatedMatrix;
target.stage.removeChild(testSprite);
// Move transform matrix so that top left of target will be at (0, 0).
targetTransform.tx = targetOriginOffset.x * testMatrix.a;
targetTransform.ty = targetOriginOffset.y * testMatrix.d;
var cloneData:BitmapData = new BitmapData(targetGlobalBounds.width * testMatrix.a, targetGlobalBounds.height * testMatrix.d, true, 0x00000000);
cloneData.draw(target, targetTransform);
var clone:Bitmap = new Bitmap(cloneData);
// Move clone to target's global position, minus the origin offset, and cancel out stage scaling.
clone.x = targetGlobalPos.x - targetOriginOffset.x;
clone.y = targetGlobalPos.y - targetOriginOffset.y;
clone.scaleX = 1 / testMatrix.a;
clone.scaleY = 1 / testMatrix.d;
return clone;
}
虽然我怀疑答案与将矩阵传递到draw命令有关,但我认为仅仅父矩阵是不够的。我还怀疑解决方案将包括.transfer.concatenatedMatrix
,因为这将考虑显示列表上的所有父级。但是仍然没有运气。非常感谢您编写了这段代码。它非常接近我所需要的,但我发现了一些奇怪的东西。刻度不太正确,但位置和旋转等都是正确的。然后我意识到我的浏览器窗口的大小决定了它离刻度有多远。这是因为我的swf通过我的html设置为缩放showAll
。因此,这对我来说并不完美,因为这一点。位图大小正确,但新位图中的内容缩放错误。稍后我将进一步讨论这个问题,但也许您也知道解决方法。再次感谢!啊,真奇怪。即使将stage设置为noScale,连接的矩阵和边界似乎也在缩放。我尝试了几件事,但在这里我也陷入了反复试验。如果我找到了修复,我会更新我的答案。我已经在我的答案中添加了一个可能的修复。虽然我找不到一个合适的方法来获得舞台的比例,所以它有点粗糙,但我希望这能有所帮助!这就成功了!这也是所有人在这个网站上为我做过的最彻底的研究问题,并且已经找到了一个真正有效的解决方案,这个解决方案本来应该很简单,但却变成了一个相当深的兔子洞。非常感谢您制定了每一个警告!很高兴我能帮忙,这是一个有趣的问题!不过,您删除测试精灵的想法绝对正确,这是内存泄漏。我会调整我的代码以防其他人使用它。