topical media & game development
actionscript-scribble-ScribbleAS3_VectorV2.ax
actionscript-scribble-ScribbleAS3_VectorV2.ax
[swf]
flex
package {
import flash.display.*;
import flash.events.*;
import flash.ui.*;
import flash.geom.*;
// A basic drawing application. This version draws a vector off screen
// and then copies that vector to a bitmap surface, thus avoiding
// the performance degradation associated with drawing too many vectors.
public class @ax-actionscript-scribble-ScribbleAS3_VectorV2 extends Sprite {
private var canvas:Bitmap;; // The on-screen bitmap canvas
private var virtualCanvas:Shape; // The off-screen vector canvas
private var canvasContainer:Sprite; // Contains the bitmap,
// providing interactivity
private var isDrawing:Boolean = false; // Indicates whether the mouse
// is currently depressed
private var border:Shape; // Line around the bitmap
private var lastX:int; // Most recently clicked x-position
private var lastY:int; // Most recently clicked y-position
// Constructor
public function @ax-actionscript-scribble-ScribbleAS3_VectorV2 () {
createCanvas();
registerForInputEvents();
// Prevent the app from resizing.
stage.scaleMode = StageScaleMode.NO_SCALE;
}
// Creates the on-screen bitmap canvas and off-screen vector canvas
private function createCanvas (width:int = 200, height:int = 200):void {
// Create a new off-screen object into which individual
// vector lines are drawn before being copied to canvasData
virtualCanvas = new Shape();
// Define the data object that will store the actual pixel
// data for the user's drawing. Lines are copied from virtualCanvas
// to this object.
var canvasData:BitmapData = new BitmapData(width,
height, false, 0xFFFFFFFF);
// Create a new displayable Bitmap, used to render the
// canvasData object
canvas = new Bitmap(canvasData);
// Create a Sprite to contain the Bitmap. The Bitmap class
// doesn't broadcast input events, so put it in a Sprite so the
// user can interact with it.
canvasContainer = new Sprite();
canvasContainer.addChild(canvas);
// Add the canvasContainer Sprite (and the Bitmap it contains) to
// this object's display hierarchy
addChild(canvasContainer);
// Put a border around the drawing surface.
border = new Shape();
border.graphics.lineStyle(1);
border.graphics.drawRect(0, 0, width, height);
addChild(border);
}
// Registers for the required mouse and keyboard events
private function registerForInputEvents ():void {
// Register for mouse down and movement events from canvasContainer
canvasContainer.addEventListener(MouseEvent.MOUSE_DOWN,
mouseDownListener);
canvasContainer.addEventListener(MouseEvent.MOUSE_MOVE,
mouseMoveListener);
// Register for mouse up and key events from the Stage (i.e.,
// globally). Use the Stage because a mouse up event should always
// exit drawing mode, even if it occurs while the mouse pointer is
// not over the drawing. Likewise, the spacebar should always clear
// the drawing, even when canvasContainer isn't focused.
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
}
// Sets the color of a specified pixel. Use this for drawing a single
// pixel because Graphics.lineTo() won't draw a single pixel
public function drawPoint (x:int, y:int, color:uint = 0xFF000000):void {
// Set the color of the specified pixel
canvas.bitmapData.setPixel(x, y, color);
}
// Draws a vector line in virtualCanvas, then copies that line's bitmap
// representation to canvasData (which is accessed via
// canvas.bitmapData)
public function drawLine (x1:int, y1:int, x2:int, y2:int,
color:uint = 0xFF000000):void {
// Draw line in virtualCanvas
virtualCanvas.graphics.clear();
virtualCanvas.graphics.lineStyle(1, 0x000000, 1, true,
LineScaleMode.NORMAL, CapsStyle.NONE);
virtualCanvas.graphics.moveTo(x1, y1);
virtualCanvas.graphics.lineTo(x2, y2);
// Copy line to canvasData
canvas.bitmapData.draw(virtualCanvas);
}
// Responds to MouseEvent.MOUSE_DOWN events
private function mouseDownListener (e:MouseEvent):void {
// Set a flag indicating that the primary
// mouse button is currently down
isDrawing = true;
// Remember the point clicked so we can draw a line to it if
// the mouse moves
lastX = e.localX;
lastY = e.localY;
// Draw a dot where the mouse was clicked
drawPoint(e.localX, e.localY);
}
// Responds to MouseEvent.MOUSE_MOVE events
private function mouseMoveListener (e:MouseEvent):void {
// Draw a line when the mouse moves over the drawing
// while the primary mouse button is depressed
if (isDrawing) {
// Use localX and localY to obtain pointer position relative to
// the canvasContainer.
var thisX:int = e.localX;
var thisY:int = e.localY;
// Draw a line to the new mouse location
drawLine(lastX, lastY, thisX, thisY);
// Remember the last mouse position for next time
lastX = thisX;
lastY = thisY;
// Update the screen immediately following the execution of
// this event listener function
e.updateAfterEvent();
}
}
// Responds to MouseEvent.MOUSE_UP events
private function mouseUpListener (e:MouseEvent):void {
// Set a flag indicating that the primary mouse button is currently up
isDrawing = false;
}
// Responds to KeyboardEvent.KEY_DOWN events
private function keyDownListener (e:KeyboardEvent):void {
// Clear the drawing when the spacebar is pressed. To clear the
// drawing, we set all pixels to the color white.
if (e.charCode == Keyboard.SPACE) {
canvas.bitmapData.fillRect(new Rectangle(0, 0,
canvas.width, canvas.height),
0xFFFFFFFF);
}
}
}
}
(C) Æliens
27/08/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.