Thursday 10 September 2009

Create a Basic Drawing Application in Flash

Step 1: Overview

This application will feature a series of tools such as pencil, eraser, text tool, and also the possibility to save your drawing in png format using the Adobe's PNG Encoder.

Step 2: Setting Up

Open Flash and create a new Flash File (ActionScript 3).

Set the stage size to 600x350px and the frame rate to 25fps.

””

Step 3: Board

Draw a 600x290px white rectangle and convert it to MovieClip. Set its instance name to "board" and align it to the top-left of the stage.

This will be the area on which we'll be able to draw.

Step 4: Tools Panel

Create a 600px wide 60px high gray (#DFDFDF) rectangle and align it to the bottom of the stage. This will be our background for the Tools Panel.

Step 5: Tool Icons

I'm not going to cover the creation of the tools icons since that isn't the intention of the turorial, still, you can see how they are made in the Fla file included in the Source.

As you can see in the image, we're going to use two icons, one in a gray tone and the other one in color.

Convert the gray pencil icon to a Button (F8) and name it "pencilTool", double click to edit it and add a KeyFrame (F6) in the "over" state. Here's where we're going to put the color version of the icon.

Lastly, add another KeyFrame in the "hit" state, and draw a 30x30px square to act as the button's hit area.

Repeat this process with all your tool icons, don't forget to give them the correct instance names (eraserTool, textTool, saveButton, clearTool).

In order to display the active tool icon, we're going to use the color version of the icon and place it in the same position of the button we created before. The instance names will be "pencil", "eraser" and "text".

We'll hide these icons later using ActionScript.

Step 5: Save Dialog

When we use the save option we're going to display a "save successful" message.

Create a 600x350px black rectangle with 50% alpha to use as a background.

Add a black rounded rectangle in the center with the save button icon and some text indicating that the save has been completed.

Create a close button and align it in the top-left of the rounded rectangle, name it "closeBtn". As you can imagine, this button will close the Save Dialog.

Convert all the elements to a single MovieClip and mark the "Export for ActionScript" checkbox. Set the Class textfield to "SaveDialog".

We'll instantiate this class when the user presses the SaveButton and the save is completed.

Step 6: Size Panel

The Size Panel is the area where you can change the size of the pencil, eraser and text tool. You can do that by clicking in the panel area or the oval inside it.

Select the Rectangle Primitive Tool, set the corner radius to 4 and create a #EFEFEF 80x50px rectangle. Convert it to a MovieClip and name it "sizePanel".

Open the Filters panel and add a Drop Shadow with the following values:

Now use the Oval Tool to create a 5x5px black circle and center it in the Size Panel, convert it to MovieClip and set its instance name to "shapeSize".

Step 7: Default Colors

We'll create a default color palette instead of using the Color Picker Component.

Create a 22x22px circle using the Oval Tool, set its color to #EEEEEE and convert it to MovieClip. Add the same Drop Shadow Filter we used in the Size Panel.

Draw a second circle of 16x16px and use black for the color this time. Center the circles and repeat this process changing the last circle color to the following:

Align them to end up with something like this:

Convert all the colors to a single MovieClip, name it "colors" and be sure to set the Registration Point to the Top-Left, since we're going to get pixel data using the Bitmap Class.

Step 8: Adobe PNG Encoder

In order to use the Save function we'll need the Adobe PNG Encoder wich is part of the as3corelib that you can find in Google Code.

To use this class outside of the package it comes with as default, we need to change one line. Open the PNGEncoder.as file and change the line "package com.adobe..." to just "package". This will let us call the class in the directory where the Fla file is.

Step 9: Main Class

A single Class will handle this application. Open the Properties Panel in the Fla file and set the Document Class as "Main".

Create a new ActionScript Document and save it as "Main.as" in the same directory where the Fla file is.

Step 10: Import Required Classes

These are the classes we're going to need in this app. Remember to check the Flash Help (F1) if you're unsure of a specific class.

  1. package
  2. {
  3. import PNGEncoder;
  4. import flash.display.MovieClip;
  5. import flash.display.Shape;
  6. import flash.display.DisplayObject;
  7. import flash.text.TextField;
  8. import flash.text.TextFormat;
  9. import flash.text.TextFieldType;
  10. import flash.text.TextFieldAutoSize;
  11. import flash.display.BitmapData;
  12. import flash.geom.ColorTransform;
  13. import flash.events.MouseEvent;
  14. import flash.events.Event;
  15. import flash.utils.ByteArray;
  16. import flash.net.FileReference;

Step 11: Extending the Class

We're extending the MovieClip class since we use this class' specific properties and methods.

  1. public class Main extends MovieClip
  2. {

Step 12: Variables

These are the variables we'll use. They're all explained in the code comments.

  1. /* Pencil Tool shape, everything drawn with this tool and the eraser tool is stored inside board.pencilDraw */
  2. var pencilDraw:Shape = new Shape();
  3. /* Text format */
  4. var textformat:TextFormat = new TextFormat();
  5. /* Colors */
  6. var colorsBmd:BitmapData; //We'll use this Bitmap Data to get the pixel RGB Value when clicked
  7. var pixelValue:uint;
  8. var activeColor:uint = 0x000000; //This is the current color in use, displayed by the shapeSize MC
  9. /* Save dialog instance */
  10. var saveDialog:SaveDialog;
  11. /* Active var, to check which tool is active */
  12. var active:String;
  13. /* Shape size color */
  14. var ct:ColorTransform = new ColorTransform();

Step 13: Main Function

The main function will take care of setting the Text Format of the Text Tool, converting the Colors MovieClip to Bitmap Data so we can extract the Pixels RGB Value, adding the listeners and hiding the active icons.

  1. public function Main():void
  2. {
  3. textformat.font = "Quicksand Bold Regular"; // You can use any font you like
  4. textformat.bold = true;
  5. textformat.size = 16;
  6. /* We create these functions later */
  7. convertToBMD();
  8. addListeners();
  9. /* Hide tools highlights */
  10. pencil.visible = false;
  11. hideTools(eraser, txt);
  12. }

Step 14: Tools Actions

The tools actions are each split into four functions.

The first one will set the tool to its Active state, the second and third ones will handle the Mouse Events (like Drawing or Erasing) and the fourth one will stop those Events.

Step 15: Pencil Tool

These functions handle the Pencil Tool, read the comments in the code for a better understanding.

The set to active function:

  1. private function PencilTool(e:MouseEvent):void
  2. {
  3. /* Quit active tool */
  4. quitActiveTool(); //This function will be created later
  5. /* Set to Active */
  6. active = "Pencil"; //Sets the active variable to "Pencil"
  7. /* Adds the listeners to the board MovieClip, to draw just in it */
  8. board.addEventListener(MouseEvent.MOUSE_DOWN, startPencilTool);
  9. board.addEventListener(MouseEvent.MOUSE_UP, stopPencilTool);
  10. /* Highlight, sets the Pencil Tool Icon to the color version, and hides any other tool */
  11. highlightTool(pencil);
  12. hideTools(eraser, txt);
  13. /* Sets the active color variable based on the Color Transform value and uses that color for the shapeSize MovieClip */
  14. ct.color = activeColor;
  15. shapeSize.transform.colorTransform = ct;
  16. }

The Start function; this function is called when the Board MovieClip is pressed.

  1. private function startPencilTool(e:MouseEvent):void
  2. {
  3. pencilDraw = new Shape(); //We add a new shape to draw always in top (in case of text, or eraser drawings)
  4. board.addChild(pencilDraw); //Add that shape to the board MovieClip
  5. pencilDraw.graphics.moveTo(mouseX, mouseY); //Moves the Drawing Position to the Mouse Position
  6. pencilDraw.graphics.lineStyle(shapeSize.width, activeColor);//Sets the line thickness to the ShapeSize MovieClip size and sets its color to the current active color
  7. board.addEventListener(MouseEvent.MOUSE_MOVE, drawPencilTool); //Adds a listener to the next function
  8. }

The Draw function; called when the user presses the Board MovieClip and moves the mouse.

  1. private function drawPencilTool(e:MouseEvent):void
  2. {
  3. pencilDraw.graphics.lineTo(mouseX, mouseY); //Draws a line from the current Mouse position to the moved Mouse position
  4. }

Stop function, executed when the user releases the mouse.

  1. private function stopPencilTool(e:MouseEvent):void
  2. {
  3. board.removeEventListener(MouseEvent.MOUSE_MOVE, drawPencilTool); //Stops the drawing
  4. }

Step 16: Eraser Tool

The Eraser Tool is pretty much the same as the Pencil Tool, except that we don't use any color other than White.

  1. private function EraserTool(e:MouseEvent):void
  2. {
  3. /* Quit active tool */
  4. quitActiveTool();
  5. /* Set to Active */
  6. active = "Eraser";
  7. /* Listeners */
  8. board.addEventListener(MouseEvent.MOUSE_DOWN, startEraserTool);
  9. board.addEventListener(MouseEvent.MOUSE_UP, stopEraserTool);
  10. /* Highlight */
  11. highlightTool(eraser);
  12. hideTools(pencil, txt);
  13. /* Use White Color */
  14. ct.color = 0x000000;
  15. shapeSize.transform.colorTransform = ct;
  16. }
  17. private function startEraserTool(e:MouseEvent):void
  18. {
  19. pencilDraw = new Shape();
  20. board.addChild(pencilDraw);
  21. pencilDraw.graphics.moveTo(mouseX, mouseY);
  22. pencilDraw.graphics.lineStyle(shapeSize.width, 0xFFFFFF); //White Color
  23. board.addEventListener(MouseEvent.MOUSE_MOVE, drawEraserTool);
  24. }
  25. private function drawEraserTool(e:MouseEvent):void
  26. {
  27. pencilDraw.graphics.lineTo(mouseX, mouseY);
  28. }
  29. function stopEraserTool(e:MouseEvent):void
  30. {
  31. board.removeEventListener(MouseEvent.MOUSE_MOVE, drawEraserTool);
  32. }

As you can see, the code is the same except for the White color changes.

Step 17: Text Tool

The Text Tool has only two functions; one in charge of setting it to active, and the other one for handling the text writing. Let's take a look:

  1. private function TextTool(e:MouseEvent):void
  2. {
  3. /* Quit active tool */
  4. quitActiveTool();
  5. /* Set to Active */
  6. active = "Text";
  7. /* Listener */
  8. board.addEventListener(MouseEvent.MOUSE_UP, writeText);
  9. /* Highlight */
  10. highlightTool(txt);
  11. hideTools(pencil, eraser);
  12. }
  13. private function writeText(e:MouseEvent):void
  14. {
  15. /* Create a new TextField Object, this way we won't replace older instances */
  16. var textfield = new TextField();
  17. /* Set Formats, position, and focus */
  18. textfield.type = TextFieldType.INPUT;
  19. textfield.autoSize = TextFieldAutoSize.LEFT;
  20. textfield.defaultTextFormat = textformat;
  21. textfield.textColor = activeColor;
  22. textfield.x = mouseX;
  23. textfield.y = mouseY;
  24. stage.focus = textfield;
  25. /* Add text to Board */
  26. board.addChild(textfield);
  27. }

This one was easy, remember that you can change the size and color using the shapeSize and the Colors MovieClips.

Step 18: Save Option

The save option handled by the saveButton will make use of the Adobe's PNGEnconder Class to save the artwork as a PNG file.

  1. private function export():void
  2. {
  3. var bmd:BitmapData = new BitmapData(600, 290);//Creates a new BitmapData with the board size
  4. bmd.draw(board);//Draws the board MovieClip into a BitmapImage in the BitmapData
  5. var ba:ByteArray = PNGEncoder.encode(bmd); //Creates a ByteArray of the BitmapData, encoded as PNG
  6. var file:FileReference = new FileReference(); // Instantiates a new File Reference Object to handle the save
  7. file.addEventListener(Event.COMPLETE, saveSuccessful); //Adds a new listener to listen when the save is complete
  8. file.save(ba, "MyDrawing.png"); //Saves the ByteArray as a PNG
  9. }
  10. private function saveSuccessful(e:Event):void
  11. {
  12. saveDialog = new SaveDialog();// Instantiates a new SaveDialog Class
  13. addChild(saveDialog); //Adds the SaveDialog MovieClip to the Stage
  14. saveDialog.closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeSaveDialog);//Adds a listener to the close button of the dialog
  15. }
  16. private function closeSaveDialog(e:MouseEvent):void
  17. {
  18. removeChild(saveDialog); //Removes the dialog of the Stage
  19. }
  20. private function save(e:MouseEvent):void
  21. {
  22. export(); //Calls the export function to begin the saving process
  23. }

Step 19: Clear Tool

The Clear Tool will add a white screen in front of all the elements in order to leave the board ready to draw again.

  1. private function clearBoard(e:MouseEvent):void
  2. {
  3. /* Create a white rectangle on top of everything */
  4. var blank:Shape = new Shape();
  5. blank.graphics.beginFill(0xFFFFFF);
  6. blank.graphics.drawRect(0, 0, board.width, board.height);
  7. blank.graphics.endFill();
  8. board.addChild(blank);
  9. }

Step 20: Get Colors Value

To get the value of the colors we're using in the Colors MovieClip, we convert it to a BitmapData Object and use the getPixel method to obtain the RGB value of the pixel clicked.

  1. private function convertToBMD():void
  2. {
  3. colorsBmd = new BitmapData(colors.width,colors.height);
  4. colorsBmd.draw(colors);
  5. }
  6. private function chooseColor(e:MouseEvent):void
  7. {
  8. pixelValue = colorsBmd.getPixel(colors.mouseX,colors.mouseY);//Gets the cliked pixel RGB value
  9. activeColor = pixelValue;
  10. /* Use a ColorTransform object to change the shapeSize MovieClip color */
  11. ct.color = activeColor;
  12. shapeSize.transform.colorTransform = ct;
  13. }

We'll add the chooseColor listener in the addListeners function later in the code.

Step 21: Active Tool

Earlier, we declared a variable to set the active or current tool in use, and we call this function to remove the corresponding listeners in order to have just one active tool.

Basically, the function checks the "active" variable in a switch loop, then depending on its value removes the listeners it has.

  1. private function quitActiveTool():void
  2. {
  3. switch (active)
  4. {
  5. case "Pencil" :
  6. board.removeEventListener(MouseEvent.MOUSE_DOWN, startPencilTool);
  7. board.removeEventListener(MouseEvent.MOUSE_UP, stopPencilTool);
  8. case "Eraser" :
  9. board.removeEventListener(MouseEvent.MOUSE_DOWN, startEraserTool);
  10. board.removeEventListener(MouseEvent.MOUSE_UP, stopEraserTool);
  11. case "Text" :
  12. board.removeEventListener(MouseEvent.MOUSE_UP, writeText);
  13. default :
  14. }
  15. }

We also need to highlight the active tool and hide the other ones:

  1. private function highlightTool(tool:DisplayObject):void
  2. {
  3. tool.visible=true; //Highlights tool in the parameter
  4. }
  5. /* Hides the tools in the parameters */
  6. private function hideTools(tool1:DisplayObject, tool2:DisplayObject):void
  7. {
  8. tool1.visible=false;
  9. tool2.visible=false;
  10. }

Step 22: Shape Size

We click the Size Panel or the ShapeSize MovieClip to change the size of the Pencil, Eraser and Text Tool. The size is changed in intervals of 5, and is reset when the size is bigger or equal to 50. Take a look at the code:

  1. private function changeShapeSize(e:MouseEvent):void
  2. {
  3. if (shapeSize.width >= 50)
  4. {
  5. shapeSize.width = 1;
  6. shapeSize.height = 1;
  7. /* TextFormat */
  8. textformat.size = 16;
  9. }
  10. else
  11. {
  12. shapeSize.width += 5;
  13. shapeSize.height=shapeSize.width;
  14. /* TextFormat */
  15. textformat.size+=5;
  16. }
  17. }

Step 23: Add Listeners

A function to add all the listeners.

  1. private function addListeners():void
  2. {
  3. pencilTool.addEventListener(MouseEvent.MOUSE_UP, PencilTool);
  4. eraserTool.addEventListener(MouseEvent.MOUSE_UP, EraserTool);
  5. textTool.addEventListener(MouseEvent.MOUSE_UP, TextTool);
  6. saveButton.addEventListener(MouseEvent.MOUSE_UP, save);
  7. clearTool.addEventListener(MouseEvent.MOUSE_UP, clearBoard);
  8. colors.addEventListener(MouseEvent.MOUSE_UP, chooseColor);
  9. sizePanel.addEventListener(MouseEvent.MOUSE_UP, changeShapeSize);
  10. shapeSize.addEventListener(MouseEvent.MOUSE_UP, changeShapeSize);
  11. }

Step 24: Test

Test your app by pressing cmd+return and check if everything is working as expected.

Use all the tools, colors and functions and start drawing your scene!

Conclusion

This Flash Movie can be easily adapted as a kids drawing application, it has a friendly user interface and basic tools that can teach how the mouse works whilst having some colorful fun in the process.

You can also explore the rest of the as3corelib and read its documentation to learn some new ActionScript features.

Thanks for reading!

source from: flash tuts+

0 nhận xét:

Post a Comment

 

Blogroll

Site Info

Text

Tut - Designer Copyright © 2009 WoodMag is Designed by Ipietoon for Free Blogger Template