-1

位置や透明度などを考慮して、ActionScript で別のベクトル オブジェクトの特定の位置に適切に描画するにはどうすればよいですか?

私のアイデア (たとえばここで提案されているようにbeginBitmapFill) を () と() を使用して、1 つのムービークリップdrawRectのビットマップ コピー (() を使用して作成) を に描画することでした。他の MovieClip のプロパティですが、主に次の理由から、これは思ったより難しいことがわかりました。BitmapData.drawgraphics

  1. 透明度は保持されません: ソース MovieClip が透明な場合、ターゲット Graphics は白になります。を使用してみましたBlendModeが、役に立ちません。白いピクセルが実際に BitmapData にコピーされているようです。何かが欠けているに違いないのですが、何がわかりません。問題は、BitmapDataコンストラクターのドキュメントが間違っていることだったようです: 透明度のデフォルトはtrueではなく、 falseです。したがって、new BitmapData(x, y, true)透明度を作成すると保持されますが、そうでない場合は保持されません。

  2. ポジショニング。ソース MovieClip が中央に配置されている場合 (中心が (0, 0) の場合、BitmapData にコピーするときに Matrix を適用して移動する必要があります。そうしないと、ビットマップにはソース MovieClip の右下のみが含まれます。方法を理解する移動するのは非常に難しく、どうにかして境界を取得する必要があると思います (ソース オブジェクトがキャンバス内で完全に中央に配置されている場合は、もちろん、幅と高さの半分だけオフセットすることができます)。

  3. beginBitmapFillタイリングdrawRect() を (0, 0) から開始しないと、ビットマップの塗りつぶしもビットマップ内の (0, 0) から開始されないようです。これは、描画を開始する場所に基づいて、ソース ビットマップをもう一度シフトする必要があることを意味します。

(次に、lineStyle(0,0,0) にする必要があるような他のものがあるため、drawRect() は境界線などを描画しません。)

このトリッキーな問題はすべて、私がこれを間違った方法で行っていると信じさせてくれます。これを行う簡単な方法はありますか?私を助けることができる図書館はどこかにありますか?誰もこれを成功させましたか?おそらく、私の描画キャンバスはスプライトではなくビットマップであるべきですか? lineToしかし、 () などを使用して描画する方法がわかりません。

状況は次のとおりです。.graphics を使用して、lineTo() などを使用して描画するスプライトがあります。描画時に MovieClip をブラシとして使用したい (または描画面に別の MovieClip のコピーを配置するだけ)。他のムービークリップを最初のグラフィックの一部にします。addChildベクトル グラフィックスが描画されたグラフィックスと相互作用しないため、()はできません。


EDIT : Theoは、Graphics サーフェスに描画される DisplayObject に適用される回転とスケーリングを適用しないという事実を除いて、完全に機能する実用的なソリューションを提供しました。これはテオの解決策です:

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);
}

回転とスケーリングをサポートするには、以下を変更する必要があると思います。

  1. で使用Matrixされるdraw()は、ソースからスケーリングと回転をコピーする必要がありますDisplayObjectか?
  2. で使用Matrixされる は、beginBitmapFill()このスケーリングと回転もコピーする必要がありますか? それとも、「二重」のスケーリングと回転が作成されるのでしょうか?
  3. 座標は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();
}

やや関連しているがそれほどホットではない質問: Flex 3 のグラフィックスに画像 (PNG など) を配置する方法は?

4

3 に答える 3

2

私の見方では、これにアプローチするにはいくつかの方法があります。

  • 「キャンバス」シェイプのグラフィックス プロパティを使用します。
    長所: 素晴らしく単純
    です。 短所: キャンバス全体を再描画する必要があるため、特に何かを削除する必要がある場合は非常に制限されます。

  • Bitmap と .draw() メソッドを使用する
    長所: これも素晴らしくシンプルで、複製をより簡単に行うことができます。
    短所: 基本的には以前のアプローチと同じ問題があり、何かを削除するには完全な再描画が必要になります。また、ビットマップであるため、スケーラブルではありません。

  • スプライトを使用し、プリミティブを子として追加し
    ます。長所: 非常に柔軟です。
    短所: これにより、オブジェクトを個別に移動、スケーリング、および削除できます。ただし、前の 2 つのオプションよりも少し複雑になります。

最後のアプローチを使用すると(これで非常に小さなこと以上のことをする場合はお勧めします)、「図面」に追加するビットマップを使用して問題を解決できます。これらは透過性をサポートします(あなたが持っているようにbitmapFill を使用するよりも少し簡単です (これを正しく行うには少し注意が必要です)。

私のブログには、ビットマップを使用して他の DisplayObject を複製および描画する例があります。それはまさにあなたが望むものではありませんが、少なくとも描画メソッドの行列部分では、コードが役立つかもしれません。

于 2009-02-17T09:30:12.207 に答える
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);
}

コメントに加えて... Graphics オブジェクトの代わりにBitmapDataをキャンバスとして使用する同じメソッドの下:

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));
}
于 2009-02-16T22:46:23.940 に答える
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);
于 2009-05-16T16:18:22.963 に答える