Search code examples
actionscript-3drawbitmapdata

AS3 Creating a drawing app using bitmapdata


I'm trying to create a drawing application that renders vector lines into bitmap. I've read the documentation about bitmapdata and I have a basic understanding of how it should work. But I'm having some trouble. As of right now my goal is simple, allow the user to draw lines with their mouse, that's all I want. The problem is somewhere with the matrix i'm using, could someone help me out?

import flash.display.Sprite;              //imports needed
import flash.events.Event;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.events.MouseEvent;
import flash.geom.Matrix;



var draw:Boolean = false;     //Boolean to determine when the mouse is down since bitmapdata doesnt receieve mouse events.

var brush:Sprite =new Sprite();    // Creating the "brush", determining the stroke it will make.
brush.graphics.lineStyle(0x000000);
brush.graphics.lineTo(mouseX,mouseY);

var data:BitmapData = new BitmapData(600,400, false); // Creating bitmapdata to allow the work with pixels.

var canvas:Bitmap = new Bitmap(data);
addChild(canvas);


stage.addEventListener(MouseEvent.MOUSE_DOWN, drawStart);  // Event listeners to determine when the mouse is up or down.
stage.addEventListener(MouseEvent.MOUSE_UP, drawStop);
stage.addEventListener(Event.ENTER_FRAME, render);

function drawStart(e:MouseEvent):void  // When the mouse is down we are drawing
{


draw= true;
}

function drawStop(e:MouseEvent):void // When the mouse is up we are not drawing
{
draw= false;
}

function render(e:Event):void  //Rendering the vector into bitmap
{
if(!draw) return;
var mat:Matrix=new Matrix();   // We need a matrix to get the correct mouse coordinates
mat.translate(mouseX,mouseY)


    data.draw(brush,mat);   // Then we draw the bitmap into vector.
} 

I have listed comments to show what I understand is happening. If I have gotten something wrong i'd like it if someone could explain it better to me.

When tested, the program draws lines, but all it does is draw a line to the mouse position from some other seemingly random position. So I figure the problem has something to do with the matrix.

I appreciate any help I can get, i've been looking at this for a while and it's just not clicking. Thanks.


Solution

  • The main problem with your code is that you draw the line into your bush.graphics only once (when your app starts), before any user input and then draw that same line into your bitmap data every frame as long as the mouse is down.

    One way to do things correctly would be to redraw that line every frame while the user keeps the mouse key down. The drawing should happen in your brush.graphics (which now serves more like a canvas) and finally, once the user releases the mouse the line he has drawn should be rendered into the bitmap data so you can reuse your brush.graphics for drawing new lines.

    var draw:Boolean = false;     //Boolean to determine when the mouse is down since bitmapdata doesnt receieve mouse events.
    var brush:Sprite;
    var canvas:Bitmap;
    var data:BitmapData;
    var start:Point = new Point();
    
    brush = new Sprite(); // This will serve as a canvas
    data = new BitmapData(600,400, false); // Creating bitmapdata to allow the work with pixels.
    
    canvas = new Bitmap(data);
    addChild(canvas);
    addChild(brush); // Add to display list so we can see what we are drawing visually
    
    stage.addEventListener(MouseEvent.MOUSE_DOWN, drawStart);  // Event listeners to determine when the mouse is up or down.
    stage.addEventListener(MouseEvent.MOUSE_UP, drawStop);
    stage.addEventListener(Event.ENTER_FRAME, render);
    
    private function drawStart(e:MouseEvent):void  // When the mouse is down we are drawing
    {
        draw = true;
        start.setTo(e.localX, e.localY); // Save mouse position at interaction start
    }
    
    private function drawStop(e:MouseEvent):void // When the mouse is up we are not drawing
    {
        draw = false;
        data.draw(brush, null);   // User released the mouse and we can draw the result into bitmap
    }
    
    private function render(e:Event):void  //Rendering the vector into bitmap
    {
        if(!draw) return;   
    
        // Redraw the line each frame as long as the mouse is down
        brush.graphics.clear();
        brush.graphics.lineStyle(0x000000);
        brush.graphics.moveTo(start.x, start.y);
        brush.graphics.lineTo(mouseX, mouseY);
    
    }