我目前正在研究由我的同事创建的工具,并希望提高性能。基本上,它是一个用于在屏幕上绘图的工具,并且在鼠标按钮关闭时每次移动鼠标时都使用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的技术,它会绘制到位图,但我不确定这会给我想要的性能提升,或者是否确实有任何方法可以橡皮擦功能。
有关更好方法的任何想法吗?绘图本身效果很好 - 这不是问题,它是后续“绘制”精灵的表现。
答案 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.x
和lastKnownPoint.y
是相同的值还是在某个距离内(或许是2或3个像素)来优化这一点。如果是,你只需返回而不做任何事情。试验并找出在线性能和平滑度之间取得良好平衡的距离。