是否有可能改善这种绘图技术的性能?

时间:2010-10-22 12:56:36

标签: flash actionscript-3 optimization

我目前正在研究由我的同事创建的工具,并希望提高性能。基本上,它是一个用于在屏幕上绘图的工具,并且在鼠标按钮关闭时每次移动鼠标时都使用Sprites和Graphics类的组合来绘制线段。这是绘图位:

// on MouseMove
protected function drawLine(e:MouseEvent):void {
        if (currentTool.thickness > 0){
            //pen
            var line:Sprite = new Sprite();

            line.graphics.lineStyle(currentTool.thickness, currentColour);
            line.graphics.moveTo(lastKnownPoint.x, lastKnownPoint.y);
            line.graphics.lineTo(e.localX, e.localY);
            inkLayer.addChild(line);
            lastKnownPoint.x = e.localX;
            lastKnownPoint.y = e.localY;
            e.updateAfterEvent();
        } else {
            //eraser
            var inkChildren:int = inkLayer.numChildren;
            for (var i:uint = inkChildren; i > 0; i--){
                if (toolCursor.hitTestObject(inkLayer.getChildAt(i - 1))){
                    inkLayer.removeChildAt(i - 1);
                }
            }
        }
    }

正如您所看到的,它会检查行'thickness'属性是否属性,如果不是则绘制,如果不是则擦除。

我确实想过使用类似于blitting的技术,它会绘制到位图,但我不确定这会给我想要的性能提升,或者是否确实有任何方法可以橡皮擦功能。

有关更好方法的任何想法吗?绘图本身效果很好 - 这不是问题,它是后续“绘制”精灵的表现。

3 个答案:

答案 0 :(得分:2)

我最近解决了类似的问题,我想不出用向量实现橡皮擦的有效方法。所以我做了一个位图来擦除图纸。它以这种方式工作:当用户选择彩色笔时,他按住左键,画线到精灵。释放左按钮时,将sprite刷新到BitmapData,并使用此位图重新绘制板。当用户选择橡皮擦时,他会在精灵上绘制粗黑线(它们在alpha = 0时不可见)。在每次移动之后,精灵的受影响部分在擦除模式下被刷新到BitmapData,这在板上反映出来。为了支持缩放,我将位图设置得很大,并将BlurFilter挂钩。它并不完美,但工作得足够快。

编辑:一些代码,切割后未经过测试,但应该提出这个想法:

public class DrawingBoard extends Sprite {
    //...vars declaration
    public function DrawingBoard(width:int, height:int, bitmapWidth:int = 1000, bitmapHeight:int = 1000)
    {
        super();
        scrollRect = new Rectangle(0, 0, width, height);

        downMatrix = new Matrix();
        downMatrix.scale(bitmapWidth / width, bitmapHeight / height);

        upMatrix = new Matrix();
        upMatrix.scale(width / bitmapWidth, height / bitmapHeight);

        bitmap = new BitmapData(bitmapWidth, bitmapHeight, true, 0x00000000);

        //on canvas we draw vector pencils and eraser traces before flush
        canvas = new Sprite();
        addChild(canvas);

        filters = [new BlurFilter(3, 3)];
    }

        //external control api
    public function moveTo(point:Point):void {
        canvas.graphics.moveTo(point.x, point.y);
        var lineWidth:Number = 4 / parent.scaleX;
        canvas.graphics.lineStyle(lineWidth, currentColor, 0.8, false, LineScaleMode.NORMAL);
    }

    public function lineTo(point:Point):void {
        canvas.graphics.lineTo(point.x, point.y);
    }

    public function eraserLineTo(point:Point):void {
        canvas.graphics.lineStyle(eraserSize, 0, 1.0);
        canvas.graphics.lineTo(point.x, point.y);
        flush(BlendMode.ERASE);
        canvas.graphics.moveTo(point.x, point.y);
    }

    public function flush(blendMode:String = null):void {
                    //draw temporary vectors to bitmap
        bitmap.draw(canvas, downMatrix, null, blendMode, null, true);
                    //update board
        var bounds:Rectangle = canvas.getBounds(this);
        with (graphics) {
            beginBitmapFill(bitmap, upMatrix);
            drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
            endFill();
        }
                    //erase temporary vectors
        canvas.graphics.clear();
    }
}

答案 1 :(得分:0)

绘制时你会注意到曲线不再尖锐了......它们将由越来越大的线组成。解决方法不是创建数百万个小行并将它们添加为子行,而是使用copyBitmapData在同一个容器中写入。

答案 2 :(得分:0)

您可以通过检查方法的开头是lastKnownPoint.xlastKnownPoint.y是相同的值还是在某个距离内(或许是2或3个像素)来优化这一点。如果是,你只需返回而不做任何事情。试验并找出在线性能和平滑度之间取得良好平衡的距离。