OMA
OMA

Reputation: 3691

Drawing programatically using a complex brush with ActionScript 3

I'm trying to make a Flash app in which the user can draw using a brush such as a tire trail with the mouse, but I can't get anything decent. The test code I'm using right now is this:

var canvas:Sprite;
var canvasWidth:int = 1024;
var canvasHeight:int = 768;
var lastPoint:Array = [0, 0];

function init() {
  canvas = new Sprite();
  addChild(canvas);
  canvas.graphics.beginFill(0xCCCCCC);
  canvas.graphics.drawRect(0,0,canvasWidth,canvasHeight);
  canvas.graphics.endFill();
  canvas.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

}

function onMouseDown(e:Event):void
{
  canvas.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
  canvas.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
  canvas.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

function onMouseUp(e:Event):void
{
  canvas.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
  canvas.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
  canvas.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}

function onEnterFrame(e:Event):void
{
  var patternPiece:DisplayObject = new TireTrail();

  var newPoint = [mouseX, mouseY];
  var angle:Number = rad2deg(getAngle(lastPoint[0], lastPoint[1], newPoint[0], newPoint[1]));
  lastPoint = newPoint;

  patternPiece.rotation = angle;
  patternPiece.alpha = Math.random();
  patternPiece.x = mouseX;
  patternPiece.y = mouseY;
  canvas.addChild(patternPiece);
}

function getAngle(x1:Number, y1:Number, x2:Number, y2:Number):Number
{
    var dx:Number = x2 - x1;
    var dy:Number = y2 - y1;
    return Math.atan2(dy,dx);
}

function rad2deg(radians:Number)
{
    return radians * 180 / Math.PI;
}

init();

The TireTrail class is just a Sprite in the library containing a PNG image of a short car wheel trail. I'm temporarily testing with this image before I settle with a definitive one: http://www.clker.com/cliparts/s/R/3/U/W/V/tire-trail-md.png

Each time the mouse pointer is moved, using the getAngle function I can get the degrees between the previous position of the mouse pointer and the new one, which makes the brush rotate, but still the result looks nothing like a tire trail, because all I get is a lot of rotated square trails, not a continuous smooth trail, as if made by a car wheel.

Ideally, the user should be able to draw wavy trails like this using the mouse: http://previews.123rf.com/images/katyart/katyart1107/katyart110700007/11473326-dirty-tire-tracks-Stock-Vector-tire-tread-motocross.jpg

Any ideas on how to achieve this?

Upvotes: 0

Views: 175

Answers (1)

null
null

Reputation: 5255

  1. You need a seamless scrollable image as a brush. This means that attaching the top of an image to the bottom should be a smooth transition, without any visible gap or discontinuity.
  2. You have to work on the pixel level, instead of adding one DisplayObject as a whole. The movement of the mouse can be smaller than the brush is long, hence you need to be able to take arbitrary small portions of the brush and draw them. To retrieve pixels from the brush, you have to work with the BitmapData class.
  3. You have to distort the brush according to the movement of the mouse, i.e. its previous positions. DisplacementMapFilter can do this. drawTriangles() of the Graphics class can also do this.

This is possible, but quite a bit more advanced compared to what you do right now.

Upvotes: 2

Related Questions