Saturday, November 27, 2010

Create a drawing application using AS3: Part 3

Today we will add the ability to draw lines, ellipses, as well as the ability to change between drawing modes and an erase button.

Take a look:


The code used to create this application includes all the features from the previous tutorials in the series, as well as 2 new drawing modes (lines and ellipses) and an erase button. It isn't too complicated, so if you followed through the previous tutorials you will understand the code without a problem.

Here it is:

var temporaryDrawing:Shape = new Shape();
addChild(temporaryDrawing);
temporaryDrawing.graphics.lineStyle(2, 0x666666, 1);

var myDrawing:Shape = new Shape();
addChild(myDrawing);
myDrawing.graphics.lineStyle(2, 0x000000, 1);

var mouseHolding:Boolean = false;
var clickedX:Number;
var clickedY:Number;
var drawMode:String = "pen";

stage.addEventListener(MouseEvent.MOUSE_DOWN, mDown);
stage.addEventListener(MouseEvent.MOUSE_UP, mUp);

function mDown(MouseEvent):void
{
mouseHolding = true;
clickedX = mouseX;
clickedY = mouseY;
myDrawing.graphics.moveTo(mouseX, mouseY);
temporaryDrawing.graphics.moveTo(mouseX, mouseY);
}

function mUp(MouseEvent):void
{
if (mouseY < 400)
{
switch (drawMode)
{
case "line" :
myDrawing.graphics.lineTo(mouseX, mouseY);
break;
case "rect" :
myDrawing.graphics.beginFill(0x222222, 0.5);
myDrawing.graphics.drawRect(clickedX, clickedY, mouseX-clickedX, mouseY-clickedY);
myDrawing.graphics.endFill();
break;
case "ellip" :
myDrawing.graphics.beginFill(0x222222, 0.5);
myDrawing.graphics.drawEllipse(clickedX, clickedY, mouseX-clickedX, mouseY-clickedY);
myDrawing.graphics.endFill();
break;
}
}
mouseHolding = false;
clearTemp();

}

stage.addEventListener(MouseEvent.MOUSE_MOVE, mMove);

function mMove(MouseEvent):void
{
if (mouseHolding && mouseY < 400)
{
clearTemp();
switch (drawMode)
{
case "line" :
temporaryDrawing.graphics.lineTo(mouseX, mouseY);
break;
case "pen" :
myDrawing.graphics.lineTo(mouseX, mouseY);
break;
case "rect" :
temporaryDrawing.graphics.drawRect(clickedX, clickedY, mouseX-clickedX, mouseY-clickedY);
break;
case "ellip" :
temporaryDrawing.graphics.drawEllipse(clickedX, clickedY, mouseX-clickedX, mouseY-clickedY);
break;
}
}
}

function clearTemp():void
{
temporaryDrawing.graphics.clear();
temporaryDrawing.graphics.lineStyle(2, 0x666666, 1);
temporaryDrawing.graphics.moveTo(clickedX, clickedY);
}

bt_pen.addEventListener(MouseEvent.CLICK, changeMode);
bt_line.addEventListener(MouseEvent.CLICK, changeMode);
bt_rect.addEventListener(MouseEvent.CLICK, changeMode);
bt_ellipse.addEventListener(MouseEvent.CLICK, changeMode);

function changeMode(evt:MouseEvent):void
{
drawMode = evt.target.value;
}

bt_erase.addEventListener(MouseEvent.CLICK, eraseAll);

function eraseAll(evt:MouseEvent):void
{
myDrawing.graphics.clear();
myDrawing.graphics.lineStyle(2, 0x000000, 1);
}

The mode is changed through 4 radio buttons placed on stage (bt_pen, bt_line, bt_rect, bt_ellipse), erase button is a button component placed on stage too (bt_erase). The drawing area is y<400, so everything below 400 pixels can't be drawn on. I used switch cases to check modes. Thanks for reading!

Related:

Create a drawing application using AS3: Part 1
Create a drawing application using AS3: Part 2
Create a drawing application using AS3: Part 4
Create a drawing application using AS3: Part 5

32 comments:

Anonymous said...

source file

Anonymous said...

this code is not working

Anonymous said...

dear sir

can you send me source file


zafar.qamar@yahoo.com

Kirill Poletaev said...

What exactly are you having problems with? I just tested the code from this post and it worked fine for me. Did you not put the radio buttons and the button on stage before testing the code?

I will email you the source file this time, but you should read tutorials more carefully from now on...

chetan's book said...

//change this in change mode function its work//


function changeMode(evt:MouseEvent):void
{
var radio:RadioButton = evt.target as RadioButton;
drawMode = evt.currentTarget.label;

}

頭上藍藍的天 said...

Hello Kirill,

I am learning Flash from your website. Could you kind help with one question?

I had applied drag and drop effects to an object, after that, I added the drawing codes provided by this site. Now I hope I can drag without drawing lines. Could you advise? Original files is at: https://www.sugarsync.com/pf/D9726155_61875891_73271

Kirill Poletaev said...

Can't open the file, because it was created using Flash CS6 and I have Flash CS5.

頭上藍藍的天 said...

Dear Kirill,

Thank you very much for reply. Please see the cs5 files below:
https://www.sugarsync.com/pf/D9726155_61875891_86553

Kirill Poletaev said...

I opened the file, but I can't understand anything, including the problem :P What exactly is the problem?

頭上藍藍的天 said...

Hello Kirill,

Sorry for causing confusion. Please see the file below:
https://www.sugarsync.com/pf/D9726155_61875891_89554

I would like to drag and drop the word (i.e., Monkey) without drawing yellow lines. Please advise how to switch between pen and mouse cursor. Thanks a lot!

Kirill Poletaev said...

Ah, I see now.

Well, a simple way to do this is to declare a "dragging" boolean in the beginning of your code:

var dragging:Boolean = false;

Then you check if this value is false before drawing anything in the mMove() function:

if (!dragging && mouseHolding && mouseY < 1200)

Set it to true when the object is being dragged and to false when it's dropped:

monkey.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag_21);

function fl_ClickToDrag_21(event:MouseEvent):void
{
monkey.startDrag();
dragging = true;
}

stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop_21);

function fl_ReleaseToDrop_21(event:MouseEvent):void
{
monkey.stopDrag();
dragging = false;
}

頭上藍藍的天 said...

Hello Kirill,

Thanks a lot, that's what I want. I have uploaded your suggestion below:

https://www.sugarsync.com/pf/D9726155_61875891_84567

Have a good day!

頭上藍藍的天 said...
This comment has been removed by the author.
頭上藍藍的天 said...

Dear Kirill,

Could you take a look at my old question, please?

My question is how to switch between drawing and dragging function by clicking the radio buttons?

Please see below:
https://www.sugarsync.com/pf/D9726155_61875891_84311

Thank you very much for your help!
(I am willing to pay for your wisdom, I mean it!)

Kirill Poletaev said...

There are a few unneeded lines of code in your script and some things seemed confusing to me, for example, the radio buttons are called bt_rect and bt_ellipse even though their labels suggest that they won't be used for drawing rectangles or ellipses.

I'll show you how to achieve the functionality you need, and the program will work, but next time, when you're making more complex projects, it's advisable to keep only the important parts of the code in your script and name your elements approporiately.

Firstly, select your radio buttons (the bt_rect and bt_ellipse ones) and using the Component Parameters tab set their "value" values to "drag" and "draw".

This way, the drawMode value will be set to "drag" when the Drag/Drop radio button is selected, and to "draw" when the Draw radio button is selected.

Using this value, we can go to mMove function and add a new conditional in the if...statement that checks if drawMode is set to "draw" before drawing anything. I assume you will only be using the "pen" drawing mode, so a large portion of the code in this function will be unnecessary. The function becomes this:

function mMove(MouseEvent):void
{
if (drawMode=="draw" && !dragging && mouseHolding && mouseY < 1200){
clearTemp();
myDrawing.graphics.lineTo(mouseX, mouseY);
}
}

Now go to the fl_ClickToDrag_21 function to check if drawMode is set to "drag" before starting to drag the element.

function fl_ClickToDrag_21(event:MouseEvent):void
{
if(drawMode=="drag"){
monkey.startDrag();
dragging = true;
}
}

And there we go!

The code works, but the overall project structure could be cleaner. It's fine for small projects I guess, but if you make more complex stuff in the future it will be confusing for yourself if you keep your code clustered.

Hope this helps!

頭上藍藍的天 said...

Hello Kirill,

Your help is really appreciated. It works well.

I will try to make the codes look clean and tidy in the future.

Have a good day!!!

頭上藍藍的天 said...
This comment has been removed by the author.
頭上藍藍的天 said...

Aloha Kirill,

I am here to consult your advise again, hopefully this wouldn't cost you much time.

In my .exe file at:
https://www.sugarsync.com/pf/D9726155_61875891_16938

I can enable the dragging mode by clicking the cursor icon outside the scrollpane. However, now my question is:

1. How to drag and drop the word 'Monkey' inside the scrollpane? 'Monkey' belongs to movieclip "SS34".
2. Why can I not display the word 'Monkey' properly in the scrollpane?
3. How to change the background color of the scrollpane?


The original codes to drag 'Monkey'are listed below:

monkey.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag_22);

function fl_ClickToDrag_22(event:MouseEvent):void
{
if(drawMode=="drag"){
monkey.startDrag();
dragging = true;
}
}

stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop_22);

function fl_ReleaseToDrop_22(event:MouseEvent):void
{
monkey.stopDrag();
dragging = false;
}

With so many thanks,

Kirill Poletaev said...

1. Firstly go to your SS34 MovieClip and add an id for your Monkey movie clip. Set the id to "monkey".

Now go to main stage and select the scroll pane. Remove the "SS34" from the "source" property.

We are going to add the source using code. Add this to the script on main timeline:

var ss34:MovieClip = new SS34();
pane.source = ss34;

ss34.monkey.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag_22);

function fl_ClickToDrag_22(event:MouseEvent):void
{
if(drawMode=="drag"){
ss34.monkey.startDrag();
dragging = true;
}
}

stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop_22);

function fl_ReleaseToDrop_22(event:MouseEvent):void
{
ss34.monkey.stopDrag();
dragging = false;
}

2. What do you mean by "properly"? I don't see a problem in the way its displayed.

3. Double click the scroll pane object, then double click the Normal Skin movie clip inside of it. Edit it in any way you want.

頭上藍藍的天 said...

Thank you very much Kirill, I have uploaded the revision to:
https://www.sugarsync.com/pf/D9726155_61875891_26084

Now I have one more question-could you please teach me how to drag 'Monkey' out of the scroll pane?

Because I'd like to see 'Monkey' appearing in the next page after click [next] button.

Thanks for your kindness as always.

Kirill Poletaev said...

Here's the code that should be in the frame on the Actions layout (basically remove monkey from the scoll pane and put it on the stage when its dragged for the first time):


var ss34:MovieClip = new SS34();
pane.source = ss34;

var monkey = ss34.monkey;

monkey.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag_22);

function fl_ClickToDrag_22(event:MouseEvent):void
{
if(drawMode=="drag"){
if(ss34.contains(monkey)){
ss34.removeChild(monkey);
this.addChild(monkey);
monkey.x += pane.x - pane.horizontalScrollPosition;
monkey.y += pane.y - pane.verticalScrollPosition;
}
monkey.startDrag();
dragging = true;
}
}

stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop_22);

function fl_ReleaseToDrop_22(event:MouseEvent):void
{
monkey.stopDrag();
dragging = false;
}

頭上藍藍的天 said...

Hello Kirill,

I cannot thank you enough. The codes works well. It's really appreciated!

Have a wonderful night.

頭上藍藍的天 said...
This comment has been removed by the author.
頭上藍藍的天 said...

Hello Kirill,

Could you help with another question, please?

I'd like to make sure both 'dog' and 'Monkey' to be dragged and dropped. That is, if 'Monkey' and 'dog' are not touched, the user cannot progress to the next page.

Thanks so much, I have put file below:
https://www.sugarsync.com/pf/D9726155_61875891_24948

Thanks again for your time.

頭上藍藍的天 said...

Hello Kirill,

After several hours, I still haven't figured out how to solve the problem.

I am able to go to the prevFrame or nextFrame after dragging and dropping 'Monkey'. The codes look like:
function fl_ClickToDrag_22(event:MouseEvent):void
{
if(drawMode=="drag"){
if(ss34.contains(monkey)){
ss34.removeChild(monkey);
this.addChild(monkey);
monkey.x += pane.x - pane.horizontalScrollPosition;
monkey.y += pane.y - pane.verticalScrollPosition;
}
monkey.startDrag();
dragging = true;
//Next or Previous page
button_11.addEventListener(MouseEvent.CLICK, fl_ClickToGoToPreviousFrame_3);

function fl_ClickToGoToPreviousFrame_3(event:MouseEvent):void
{

prevFrame();

}
button_12.addEventListener(MouseEvent.CLICK, fl_ClickToGoToNextFrame_3);

function fl_ClickToGoToNextFrame_3(event:MouseEvent):void
{

nextFrame();

}
}
}

However, I am still eager to know how to go to prevFrame or nextFrame after 'monkey' and 'dog' are both dragged and dropped.

Could you please advise?
With a lot of thanks.

頭上藍藍的天 said...
This comment has been removed by the author.
頭上藍藍的天 said...

button_11.addEventListener(MouseEvent.CLICK, fl_ClickToGoToPreviousFrame_3);

function fl_ClickToGoToPreviousFrame_3(event:MouseEvent):void
{
if(!ss34.contains(dog) && !ss34.contains(monkey))
{
prevFrame();
}
}
button_12.addEventListener(MouseEvent.CLICK, fl_ClickToGoToNextFrame_3);

function fl_ClickToGoToNextFrame_3(event:MouseEvent):void
{
if(!ss34.contains(dog) && !ss34.contains(monkey))
{
nextFrame();
}
}


This might not be the best codes, butI have made it work!!

頭上藍藍的天 said...

I have put the file below:

https://www.sugarsync.com/pf/D9726155_61875891_24948

Have good day!

Anonymous said...

Hello,

I am making a similar type of drawing tool for kids. In that they can select the shape onclick and that shape will appear on stage. Then, kids will draw over that shape using the brush.

At this stage I am facing problem:
1) I am not able to draw over the shape(with stoke and without fill. Even tried with fill). The brush is working inside shape but not over the stroke.
2) The lines are not coming while Drawing over Circular Shape.

Please help.

Kirill Poletaev said...

Hard to say what the problem is. Might be able to help if you post the source.

mrigank dembla said...
This comment has been removed by the author.
mrigank dembla said...

Hey Kirill, I understood your tutorials and pasted the code in my file, but when i run it, It doesn't draw anything?? Can you help me out. ?

Post a Comment