我的想法(如here所示)是使用beginBitmapFill
()和drawRect
()绘制位图副本(使用BitmapData.draw
()制作)一个MovieClip到另一个MovieClip的。graphics
属性,但事实证明这比我想象的要困难,主要是出于以下原因:
不保留透明度:源MovieClip是透明的,目标图形变为白色。我尝试过使用问题似乎是BlendMode
,但没有用。看起来白色像素实际上被复制到BitmapData中。我必须遗漏一些东西,但我不知道是什么。BitmapData
构造函数的文档是错误的:透明度不会默认为 true ,但 false 。因此,如果您创建了new BitmapData(x, y, true)
透明度,则保留,否则不会。
定位即可。如果源MovieClip居中(中心位于(0,0),则在将其复制到BitmapData时必须应用Matrix移动它,或者位图仅包含源MovieClip的右下角。移动它很棘手,我认为它涉及以某种方式获取边界。(如果源对象在其画布中完全居中,当然可以简单地将其偏移一半的宽度和高度。)
< / LI> beginBitmapFill
平铺。看来如果你不在(0,0)处启动drawRect
(),位图填充也不会从位图中的(0,0)开始。这意味着您必须根据要开始绘制的位置再次移动源位图。
(然后还有其他东西,比如必须使用lineStyle(0,0,0),所以drawRect()不会绘制边框等。)
所有这些棘手的麻烦让我相信我会以错误的方式解决这个问题。有更简单的方法吗?在某个地方有可以帮助我的图书馆吗?有没有人成功完成这个?也许我的绘图画布不应该是精灵而是位图?但后来我不知道如何使用lineTo
()等来绘制它。
这是情况:我有一个Sprite,我使用它的.graphics绘制,使用lineTo()等。现在我想在绘图时使用MovieClip作为画笔(或者只是放置一个绘图表面上另一个MovieClip的副本),使另一个MovieClip成为第一个图形的一部分。我不能addChild
(),因为矢量图形不会与绘制的图形交互。
编辑:Theo提供了一个完美的除之外的工作解决方案,因为它不会应用旋转和缩放应用于正在绘制到Graphics表面上的DisplayObject。这是Theo's solution:
private function drawOntoGraphics(source : IBitmapDrawable, target : Graphics, position : Point = null) : void
{
position = position == null ? new Point() : position;
var bounds : Rectangle = DisplayObject(source).getBounds(DisplayObject(source));
var bitmapData : BitmapData = new BitmapData(bounds.width, bounds.height, true, 0x00000000);
bitmapData.draw(source, new Matrix(1, 0, 0, 1, -bounds.x, -bounds.y), null, null, null, true);
target.beginBitmapFill(bitmapData, new Matrix(1, 0, 0, 1, bounds.x + position.x, bounds.y + position.y));
target.drawRect(bounds.x + position.x, bounds.y + position.y, bounds.width, bounds.height);
}
为了支持旋转和缩放,我假设必须修改以下内容:
Matrix
中使用的draw()
应该复制源DisplayObject
的缩放和轮换?Matrix
中使用的beginBitmapFill()
也应该复制此缩放和旋转吗?或者这可能会产生“双倍”缩放和旋转?drawRect()
坐标以匹配缩放和旋转DisplayObject
的大小?这意味着getBounds()
不准确?编辑:这是一个支持缩放和旋转的工作实现,由所有反馈构成:
static function DrawOntoGraphics(source:MovieClip, target:Graphics,
position:Point = null):void {
var sourceClass:Class = getDefinitionByName(getQualifiedClassName(source))
as Class;
var sourceCopy:MovieClip = new sourceClass();
sourceCopy.rotation = source.rotation;
sourceCopy.scaleX = source.scaleX;
sourceCopy.scaleY = source.scaleY;
sourceCopy.graphics.clear();
var placeholder:MovieClip = new MovieClip();
placeholder.addChild(sourceCopy);
if (!position)
position = new Point();
var bounds:Rectangle = placeholder.getBounds(placeholder);
var bitmapData:BitmapData = new BitmapData(bounds.width, bounds.height,
true, 0x00000000);
var drawMatrix:Matrix = new Matrix(1, 0, 0, 1, -bounds.x, -bounds.y);
bitmapData.draw(placeholder, drawMatrix);
placeholder.removeChild(sourceCopy);
var fillMatrix:Matrix = new Matrix(1, 0, 0, 1, bounds.x + position.x,
bounds.y + position.y);
target.beginBitmapFill(bitmapData, fillMatrix);
target.lineStyle(0, 0x00000000, 0);
target.drawRect(bounds.x + position.x, bounds.y + position.y,
bounds.width, bounds.height);
target.endFill();
}
有些相关但不那么热门的问题:How to put an image (say, PNG) on a graphics in Flex 3?
答案 0 :(得分:2)
我认为你有几种方法可以解决这个问题:
使用“画布”形状的图形属性
优点:简单明了
缺点:非常有限,特别是如果你需要删除东西,因为你必须重绘整个画布。
使用位图和.draw()方法
优点:也很简单,你可以更轻松地复制事物
缺点:基本上与先前的方法有相同的问题,删除任何东西都需要完整的重绘。它也是不可扩展的,因为它是位图。
使用精灵并添加原语作为孩子
优点:非常灵活。
缺点:这允许您单独移动,缩放和删除对象。但是,它会比前两个选项稍微复杂一些。
使用最后一种方法(我建议如果你要做的事情比你用的东西还要小),你可以通过使用添加到“绘图”中的位图解决问题,这些方法支持透明度(如你已经发现了)并且比使用bitmapFill更简单(这有点难以实现)。
我的博客上有using a bitmap to clone and draw other DisplayObjects的示例。它不是你想要的,但代码可能有一些用处,至少是draw方法的矩阵部分。
答案 1 :(得分:1)
使用显示对象getBounds函数是绘制时转换坐标的可靠解决方案:
private function drawOntoGraphics(source : IBitmapDrawable, target : Graphics, position : Point = null) : void
{
position = position == null ? new Point() : position;
var bounds : Rectangle = DisplayObject(source).getBounds(DisplayObject(source));
var bitmapData : BitmapData = new BitmapData(bounds.width, bounds.height, true, 0x00000000);
bitmapData.draw(source, new Matrix(1, 0, 0, 1, -bounds.x, -bounds.y), null, null, null, true);
target.beginBitmapFill(bitmapData, new Matrix(1, 0, 0, 1, bounds.x + position.x, bounds.y + position.y));
target.drawRect(bounds.x + position.x, bounds.y + position.y, bounds.width, bounds.height);
}
除了你的评论...使用 BitmapData 而不是Graphics对象作为画布使用相同的方法:
private function drawOntoBitmapData(source : IBitmapDrawable, target : BitmapData, position : Point = null) : void
{
position = position == null ? new Point() : position;
var bounds : Rectangle = DisplayObject(source).getBounds(DisplayObject(source));
var bitmapData : BitmapData = new BitmapData(bounds.width, bounds.height, true, 0x00000000);
bitmapData.draw(source, new Matrix(1, 0, 0, 1, -bounds.x, -bounds.y), null, null, null, true);
target.draw(bitmapData, new Matrix(1, 0, 0, 1, bounds.x + position.x, bounds.y + position.y));
}
答案 2 :(得分:1)
bzlm - 您总是可以将起始X位置设为常量,并将drawRect与Matrix平移结合起来。
var xPos:Number = 750;
var matrix:Matrix = new Matrix();
matrix.translate(xPos,0);
mySprite.graphics.beginBitmapFill(myBitmap,matrix);
mySprite.graphics.drawRect(xPos,yPos,imgWidth,imgHeight);