Flash Explained

Learn Flash easily.

Making an interactive drawing sketchpad

October 16th, 2008 | Author: Luka | Category: ActionScript Design


In this lesson, I will show you how to create a an interactive sketchpad on which you and your users can draw. The sketchpad features an interface which allows you to change the thickness and the color of the line.

With this tutorial, you will learn:

  • How to create simple buttons and tell them what to do via ActionScript,
  • How to easily duplicate them,
  • What are the drawing functions in ActionScript,
  • What are movie clip and button events and how to use them
  • and more.

Play around with the sketchpad below to see what you’ll learn to create!

Creating the interface background

1 Open a new Flash document. Call the first layer interface bkg. It is here that you'll draw the background that delineates the interface for your flash sketchpad.

Naming the first layer.

2 Select the Rectangle tool (R). Draw a rectangle on the stage that is 100 pixels wide. The rectangle's height isn't important, because you'll be adjusting it in a moment.

A rectangle on stage.

3 Select the rectangle by clicking on it with the Selection tool (V). Open the Align panel (Window > Align).

In the Align panel, turn on the "Align/Distribute to stage" button (see 1 on the image below). Next, click on the "Match height" button (2) to make the rectangle's height equal that of the stage.

Using the Align panel to position the rectangle.

To put the rectangle nicely on the right side of the stage, click the "Align right edge" (3) and "Align top edge" (4) buttons. Your final result should look like the one seen on the image below.

The rectangle in its final position on the stage.

Lock the interface bkg layer.

Top of page

Creating the buttons that will let the user choose the line thickness

4 Make a new layer and call it line thickness buttons.

Creating a second layer.

5 Again, select the Rectangle tool (R). In the Properties panel, select black as outline color and white as fill color. Select "hairline" as type of line.

Selecting the properties for the rectangle tool.

6 Draw a rectangle (about 60 pix wide and 25 pix high) in the upper portion of the interface background you just made awhile ago.

A white rectangle with a black border.

7 With the Selection tool (V), double-click on the rectangle's white fill to select both the fill and the outline.

The rectangle is selected.

8 Select Modify > Convert to Symbol. In the dialog window that appears, select Button as type, call it line thickness 0 and click OK.

Creating a new button symbol.

9 Now, don't click anywhere and don't touch anything! 🙂 If your button is still selected (and it should be, check that in the Properties panel - it should display a button icon on its left side), just press Ctrl+C (Cmd+C on a Mac) to copy it.

Next, select Edit > Paste in Place. You have just pasted a copy of the button exactly on top of the original.

Again, don't click anywhere. Hold Shift and press two or three times the down arrow key on your keyboard to move the new copy of the button below the original one.

Repeat this operation, making a third button. Your buttons should be perfectly vertically aligned, like the image below shows you.

Three buttons vertically aligned on stage.

10 Double-click on any of the three buttons on the stage. You'll enter inside the button symbol's timeline, which you can see by the change that appears above the scene: the button's timeline is different than that of the main stage and there is a sign telling you that, too. It bears the symbol's name: line thickness 0.

Inside the timeline of a button symbol.

11 Call the first layer background and lock it.

12 Create a second layer (still inside the button) and call it line.

Creating a second layer inside the button.

13 Select the Line tool (N). Make sure that the type of line is still set to hairline in the Properties panel. Hold Shift and draw a horizontal line that fits inside the rectangle below it.

Drawing inside the button symbol.

You'll certainly notice that the line has appeared in all of the three buttons situated on the stage. Dont be alarmed! 🙂 That's perfectly normal.

Since you entered inside this button symbol, once you make a change inside it, every single instance (copy) of it will be affected. That is because you made copies (multiple instances) of the same button symbol. You will make separate buttons for the other two types of line thickness in a moment.

As for now, don't lock the line layer.

Top of page

Duplicating the buttons and swapping them on the main scene

14 Return to the main scene by clicking on the "Scene 1" link above the timeline.

Returning to the main scene.

15 Open the Library (Window > Library). You will see your button symbol inside it.

16 Right-click on the line thickness 0 button and select Duplicate from the menu.

Duplicating a symbol inside the Library.

Call the new button line thickness 3.

17 Double-click on the newly created button inside the Library. You will enter inside it.

18 Using the Selection tool (V), click once on the thin line situated in the line layer to select it.

Selecting a line.

19 In the Properties panel, to the left of the line type drop-down menu, write 3 inside the small field and hit Enter to confirm. The type of line will automatically jump to "Solid".

Setting the line thickness.

Fine. you have just made the button for the second type of line thickness.

20 Repeat the steps 16 through 19:

  • Right-click on any of the two button symbols inside the Library. Call the new symbol line thickness 6.
  • Double-click on the new button.
  • Select the line inside it and make its thickness 6 in the Properties panel.

Return to the main scene. You shall now see how easy it is to put the newly made buttons on the scene, without having to pull them out of the Library and set their position manually.

21 Click once on the middle button on the stage with the Selection tool (V) to select it. Don't double-click on it, because you will enter inside it, and you don't want that.

22 Go to the Properties panel and click on the Swap button.

The button for swapping symbols on the scene.

In the dialog box that appears, select line thickness 3 and click OK. You just changed the button on the main scene the easiest way possible. Now ain't Flash cool? 🙂

23 Repeat this once again: select the third button on the scene, click on the Swap button, select line thickness 6 and click OK. You should now have three distinct buttons on the main scene, for different kinds of line thickness your users will draw with.

Three different line thickness buttons.

This part of your sketchpad's interface is in place, but there is still one more thing to do: giving them Instance names. You'll have to do this if you want to tell the buttons what to do via ActionScript from the main timeline. This is very practical, that's why I encourage you to do it in all your projects.

24 Select the first button by clicking on it once with the Selection tool (V). Go to the left side of the Properties panel and write line0 inside the Instance name field. Hit Enter to confirm.

The Instance name of a button.

That's a zero at the end of the Instance name (line0), not the letter O. It makes sense, because these buttons will serve for choosing a line thickness. You can give it an Instance name other than the one I suggested, but stick to the rules of assigning Instance names.

You can name your buttons any way you like, but there are some rules to be followed. For example, you can call it line0, but not 0line. Because an Instance name can contain numbers, but cannot begin with a number. Also, you cannot use special characters, like spaces, punctuation marks, hashes etc. Remember that ActionScript is a case-sensitive programming language. An Instance name called lineThicknessZero is not the same as linethicknesszero.

25 Assign Instance names to the remaining two buttons: call them line3 and line6, respectively.

Cool! Let's move on to the buttons which will serve for choosing the color with which a user will draw.

Lock this layer.

Top of page

Making the buttons for color selection

26 Make a new layer and call it color buttons.

All the layers on the scene made up until now.

27 One more time, select the Rectangle tool (R). In the Properties panel, select hairline as line type. Choose black as outline color and pure red (#FF0000) as fill colour.

Hold Shift, click and start dragging to draw a square. Make a small square just below the existing buttons.

A small red square beneath the buttons.

28 Select the square (both the outline and the fill). Hit F8 (or select Modify > Convert to Symbol) to convert it to a symbol. Select Button as type, call it red button and click OK.

You will now duplicate this button, the same way you duplicated the line thickness buttons in the previous section.

29 Go to the Library (Ctrl+L), right-click on the red button symbol and select Duplicate. Call the new button green button (or blue, yellow, whichever color you prefer).

30 Double-click the green button in the Library to enter inside it. The graphics (the square) inside it will already be selected.

31 Just go to the Tools or Properties panel, click on the small fill colour selecting case, and choose the green colour.

Selecting a fill colour.

32 Return to the main scene by clicking on the "Scene 1" link above the timeline.

33 Click once on the small red button on the main scene to select it. Again, like you did before,

  • copy it (Ctrl+C)
  • paste it in place (Ctrl+Shift+V)
  • move the copy by holding Shift and using the arrow keys
  • click the Swap button and select green button, click OK

Two buttons for changing color added to the interface.

34 Select the red button, go to the Properties panel and give it the Instance name colorRed.

Instance name for the red button.

Repeat the same thing with the green button - give it the Instance name, like colorGreen for example.

You can make additional color buttons - as many as you like. For the sake of not repeating the same thing, I'll proceed with the tutorial with just two color buttons. You understand the principle, so it won't be a problem for you to add more buttons and write additional code for them.

Lock the color buttons layer.

Top of page

Inserting the ActionScript code that powers the drawing pad

35 Make a new layer and call it actions. Select this layer's first keyframe by clicking on it.

Selecting the keyframe for entering ActionScript.

36 Select Window > Actions (or press F9) to open the Actions panel. Enter the following code inside it:

lineThickness = 0;
selectedColor = "0x000000";
_root.onMouseDown = startDrawing;
_root.onMouseUp = stopDrawing;
function startDrawing() {
if (_xmouse<455) {
_root.lineStyle(lineThickness, selectedColor);
_root.moveTo(_root._xmouse, _root._ymouse);
_root.onMouseMove = drawLine;
}
}
function drawLine() {
_root.lineTo(this._xmouse, this._ymouse);
}
function stopDrawing() {
delete this.onMouseMove;
}
line0.onPress = function() {
lineThickness = 0;
};
line3.onPress = function() {
lineThickness = 3;
};
line6.onPress = function() {
lineThickness = 6;
};
colorRed.onPress = function() {
selectedColor = "0xFF0000";
};
colorGreen.onPress = function() {
selectedColor = "0x00FF00";
};

Test your movie (Control > Test Movie). Draw something. Be creative! Draw a masterpiece and send it over to the Louvre museum. 🙂

Now, if something doesn't function as intended, check out if you gave Instance names to all of the interface buttons, and also that you wrote those names exactly the same in your ActionScript code.

Everything should function smoothly. But! You may have noticed that the lines that you are drawing are lagging behind the cursor. That is especially true if you have made quick movements with your mouse. To correct that, go back to your document.

37 Select Modify > Document.

Change the speed of your movie, by entering 30 in the Frame Rate field. Click OK.

Test your movie again (Ctrl+Enter on a PC, Cmd+Enter on a Mac). You should see the change immediately when you start drawing in your flash movie.

Top of page

Explaining the ActionScript behind the interactive sketchpad

Let me explain you now what each line of ActionScript exactly does.

The first two lines define two variables and their respective values.

lineThickness = 0;
selectedColor = "0x000000";

The lineThickness variable is set up at the beginning to be used later to define the starting thickness of the line a user will draw with. This is a numerical value, which can range from 0 (the finest possible line) to 100 (enormous line). The next variable, selectedColor, defines the starting drawing color, which is black in this case. This is a hexadecimal value and has to be written between quotation marks.

Next, two movie clip events are defined, onMouseDown and onMouseUp.

_root.onMouseDown = startDrawing;
_root.onMouseUp = stopDrawing;

And just what are events? Events are things that happen while your SWF is running and/or a user interacts with it. An event can be, for example, when a user has clicked a button, moved his mouse, when a sound has finished playing, a file has been loaded, etc.

In ActionScript, there are button events and movie clip events. Button events are concerned mostly with the user interaction with them. Movie clip events are far more powerful and include not only user interaction, but a plethora of many other very useful things.

The onMouseDown movie clip event happens when the user presses the mouse button, anywhere on stage. So, when a user clicks, this particular event occurs. You can tell Flash what to do when this happens, which is exactly what is going on in the line

_root.onMouseDown = startDrawing;

Let's go over each element and see what it does. The first ActionScript keyword, _root, points to the main timeline, or the root level, level 0, the flash movie itself. You cannot write an event like this:

onMouseDown = ...etc

A movie clip event has to be tied to a movie clip to function properly. So, you could write

myMovieClipName.onMouseDown = ...etc

But, there is no need for you to create a separate movie clip that will be associated with the onMouseDown event, because the _root timeline is treated as a movie clip.

On the right side of the equals sign there is the word startDrawing, followed by a semicolon. This is a name of a function that comes later in the code. To sum it up, every time the user clicks her mouse, this function (startDrawing) will be executed.

The next line is similar to the previous one:

_root.onMouseUp = stopDrawing;

Whenever a user releases the mouse button, a function will be executed - the stopDrawing function in this case. Note that the startDrawing and stopDrawing functions aren't built-in ActionScript functions, I wrote them myself. I could have called them beginDrawing, startToTrace, or any way I liked, I just chose the names in this example as most intuitive and easy to remember.

Now comes the first function:

function startDrawing() {
if (_xmouse<455) {
_root.lineStyle(lineThickness, selectedColor);
_root.moveTo(_root._xmouse, _root._ymouse);
_root.onMouseMove = drawLine;
}
}

Inside the function, there is an if conditional statement. It says that if the current position of the user's mouse (_xmouse) is less than 455, the code lines between its curly braces can be executed. If it is not (i.e. if the mouse x position is equal to or greater than 455), nothing will happen.

Why this? Simply to make the functionality of the movie better. The x coordinate at point 455 is where the interface (the background rectangle) begins. So, even if a user could click on a button with no problems, I prefer to tell Flash not to draw if the mouse has been pressed over the interface.

The arrow marks the left edge of the interface.

If you start drawing in the white area and continue moving your mouse inside the interface area and come back inside the white zone, you will see that your line isn't interrupted. I merely told Flash not to start drawing inside the interface area - not to react to a click inside this zone, so that the clicks will react only to the buttons.

Even if you ommited this conditional statement, you wouldn't draw over the interface because the code has been set up to draw on the _root level, or level zero, which is below all the other layers inside Flash.

Ok, let's see what happens when you start drawing inside the appropriate area then.

The lines that get executed once the condition is true (_xmouse is less than 455) are the following three:

_root.lineStyle(lineThickness, selectedColor);
_root.moveTo(_root._xmouse, _root._ymouse);
_root.onMouseMove = drawLine;

The first one contains the obligatory method (command) that must be written if you want to draw with ActionScript in Flash: the lineStyle method. Before you can draw programmatically, you must define the characteristics of the line.

So the parameters inside the lineStyle method, inside the parentheses are the thickness of the line and its color. You can also define its degree of transparency (its alpha property) if you want. If you omit it like I did, Flash will consider the line as fully opaque - its alpha set to 100%. I won't go into much detail here, if you want to know more on this method, read my tutorial on basic drawing with ActionScript.

Inside the parentheses, I have put two variables: lineThickness and selectedColor. If you remember, these two are defined at the outset of your ActionScript code. So, if the user hasn't clicked on any buttons to change them, the thickness will be 0 and the color will be black.

The next line,

_root.moveTo(_root._xmouse, _root._ymouse);

uses the moveTo method to move the starting point for drawing. If you don't specify a starting point, Flash will take the default value where x and y both equal zero (starting point 0, 0), which is the top left corner of the stage.

And the starting point for drawing is the current position of the user's mouse, the coordinates of which are read from the _xmouse and _ymouse variables. These two are ActionScript keywords which are used to detect the current position of the mouse inside the stage or a movie clip.

What this basically does is, when a user clicks to start drawing, she will start drawing from the point where the click occured.

Then comes another event:

_root.onMouseMove = drawLine;

The onMouseMove event happens anytime the mouse is moved. So, every time this happens, you tell Flash to execute a function - the drawLine function.

function drawLine() {
_root.lineTo(this._xmouse, this._ymouse);
}

This function has a method inside it, the lineTo method. This method draws a line from the previous point (the starting one, defined with the moveTo method awhile ago) to the point defined between the parentheses. Again, this point is equal to the current position of the mouse, found through the _xmouse and _ymouse properties.

The keyword this is used instead of _root, to show you that they mean the same. The this keyword points to the timeline it is situated on. Since the ActionScript code is situated on the keyframe on the main timeline, it equals _root.

The last function,

function stopDrawing() {
delete this.onMouseMove;
}

defines what happens when the user has released her mouse. Remember the line

_root.onMouseUp = stopDrawing;

from the start of your code? This event, onMouseUp, happens when the user has released the mouse button anywhere on stage. So, the function deletes the onMouseMove event and stops it from happening. And the drawn line ends.

To resume:

  • The user clicks with her mouse inside the drawing area.
  • The onMouseDown event is fired, which in turn calls the startDrawing function.
  • The startDrawing function sets the style (thickness and color) for the line, moves the starting drawing point to the current position of the mouse and defines the onMouseMove event.
  • The onMouseMove event calls the drawLine function. Since this event is happening every fraction of a second the mouse is moved, this function gets executed repeatedly, over and over again.
  • The drawLine function draws a line from the last point registered, to the current position of the mouse.
  • The user releases her mouse button.
  • The onMouseUp event is fired, which in turn calls the stopDrawing function.
  • The stopDrawing function deletes the onMouseMove event and therefore stops the drawing process.

What this in fact does is that there aren't any curved lines being drawn here. If you draw a nice curve with this small application, you really drew dozens of small straight lines which are connected and so closely placed near each other that they seem like a curve.

Whew! That was nice and cool, now wasn't it? All that remains to be explained is the functionality of the buttons. These are simpler then the previous code. But wait, before you continue, I just want to give you a small piece of advice.

Everything IS easy once you learn how to do it. Even surgery and rocket science, yes. In my vocabulary, the words "problem" and "difficult" DO NOT EXIST. There are only solutions and easy things you learned how to do.

On to the little interface buttons!

I'll explain just a single button from each group, because the logic is exactly the same for the remaining ones.

Let's take the button that sets the line thickness to 3, for example.

line3.onPress = function() {
lineThickness = 3;
};

The first thing you bump into in the code above is the Instance name of the button - line3. So, when you say to Flash

line3.onPress = function() {

you tell it that when the button called line3 is pressed, a function will be executed. Here you encounter the onPress button event. Unlike the onMouseDown movie clip event, which happens at the moment the mouse button is clicked anywhere on stage, this button event happens only and exclusively when that particular button has been pressed.

Then the function is being run. The code inside the function consists of a single line of code, which sets the value of the lineThickness variable to 3. And it will stay this way until some other button defining the line thickness has been pressed.

The same goes for color buttons:

colorGreen.onPress = function() {
selectedColor = "0x00FF00";
};

A button is pressed, a function which sets the value of the selectedColor variable is executed and the color of the next line that will be drawn is changed.

Ta-daaaa! That's it! You just learned what all the code does and a lot more. Apply and use this knowledge in your Flash projects and keep on learning!

Oh yes... just one more little thing. The resulting SWF from this tutorial has a file size of just 635 bytes!!! That's less than 1 KB!

You can download the source files for this project below. The second link is for downloading the example seen on top of this page, with all the seven colors.

Download the zipped source FLA file for this lesson.

Download the source for the expanded example.

Be Sociable, Share!

Comments

Submit a comment

  • Charlotte Oct 27, 2010 at 2:11 am

    Hey,
    just wondering how to get the colours to change, ive created more buttons, however when i test the movie, it only goes between the red and green..
    thank you
    This tutorial was very helpful..
    Charlotte

  • eko Nov 11, 2010 at 2:19 am

    how if we want to insert text in canvasby pressing additional button

  • admec multimedia Dec 2, 2010 at 11:56 am

    easy, simple, nice tutorial. but how can i add erase option. plz explain it next tutorial or if u have already posted then send me the url of that in it’s reply.

    Thanks
    admec multimedia staff

  • Jasmin Dec 6, 2010 at 6:28 pm

    heloo, can somebody help me please!

    Im wondering if its possible, if i embedd a drawing app into web site, to preserve it’s contents!? for instance if i draw something and then the some other person comes later and he continues onto content generated by me!?

    thanks!

  • Rob G Dec 10, 2010 at 11:57 am

    Hi, Im an architecture student and am designing something that incorporates an interactive wall. I have made a website to be projected and want to have this drawing page as one of the features of it. I have copied (i hope) what you have done and copied the script but it still doesnt seem to work. This is the first thing i have done in flash, so iv probably made a stupid mistake. Is there any differences with CS4 Flash to this one (if it created in a different version)

    Cheers, Rob

  • crystal Dec 11, 2010 at 8:11 pm

    Hi, great tutorial!

    New to Flash, having trouble debugging an issue I’m getting. I’m running into an 1120 error: Access to undefined property. I’m not sure what’s going on. I’ve stripped the code down to just declaring lineThickness and selectedColor and still receive the error.

    I also downloaded your example code and was able to run it… I pasted in the example code into my code and still got the error.

    Any help greatly appreciated!

  • Rob G Dec 15, 2010 at 2:12 am

    Had the smae problem as someone before, was using actionscript 3.0, not 2.0. Works perfectly now. AMAZIN!!!!!
    Cheers

  • pio_pio Dec 16, 2010 at 1:09 am

    Can someone please tell me how to change this code to work in AS 3.0?? I am just starting to learn AS and need help!

  • pio_pio Dec 16, 2010 at 7:20 am

    Okay I figured out how to tackle my question above but now I have another question: How in AS3 do you set it up to draw on top of symbols? I noticed some people figured it out in AS2 so please advise of any tips!

  • linda Jan 13, 2011 at 2:31 am

    To create this sketchpad within a movie clip, put the code onto the keyframe within that movie clip. But in the top part, use this instead of the code entered above:

    lineThickness = 0;
    selectedColor = “0x000000”;
    onMouseDown = startDrawing;
    onMouseUp = stopDrawing;
    function startDrawing() {
    if (_xmouse<455) {
    lineStyle(lineThickness, selectedColor);
    moveTo(_xmouse, _ymouse);
    onMouseMove = drawLine;
    }
    }
    function drawLine() {
    lineTo(this._xmouse, this._ymouse);
    }
    function stopDrawing() {
    delete this.onMouseMove;
    }

    then add all parameters for line thickness and line color. The difference between this code and the one used above is that it deletes the parts where it says "_root." which defines where the line is drawn, changing that will allow the line to be drawn within the movie clip on the same layer as the movie clip is in. The same adjustment can be used if there is a background that you wish to use in your code, just put the background on a lower layer than the one where the actionscript is entered.

  • matt Feb 7, 2011 at 9:11 pm

    This is awesome! does anyone know how I could limit the drawing to one pixel per visit and have the image update an existing image each time someone adds to the pic??

  • joe nursey Feb 23, 2011 at 4:23 pm

    Hi – trying to do this with a banner ad and wanting to limit the space for drawing so can have “clickable” area underneath but not having any luck!

    Any help would do

  • Nihat Mar 30, 2011 at 12:27 pm

    Is it possible to develop something similar to Geometer’s Skecthpad software using flash?

  • Ravi Bhadauria Mar 31, 2011 at 5:55 am

    hello,

    I also noticed a problem, when i want to draw within a particular area,

    It doesn’t work fine.

    Is any of u have solution for that, i am in urgent requirement.

    Thanks,
    ADMEC Multimedia Institute

  • Herbert Humlebi May 1, 2011 at 9:50 am

    Beautiful sketchpad – perfect for use on eg. a smartboard.

    In the actionscript of your example the linethickness is set to “0” as default, giving the user the choice of changing to a thicker line “3” or “6”.

    “0” is a little too thin for a smartboard. “3” is the better thickness. No big deal for the user to press the “3” line when he wants to draw something.

    However, every time you reload the webpage containing the sketchpad, you must press “3” to get the desired trhickness.

    Is there a way to get access to the actionscript in your example and change default thickness to “3”?

    Or must I build a new one based on your instructions, changing the linethickness to “3”?

    I only have access to the rather obsolete Flash 5. Will it work with this version?

    Thank you for your work!

  • Dimitris May 6, 2011 at 9:31 am

    Iinstead of blank board I would like to draw on a jpg image background.
    How can we do this?

  • Richard May 23, 2011 at 1:34 pm

    Hi there! I’m making an English learning software and have modified this tutorial to let students circle pictures on a smart board. I have a question tho: how can I make an On/Off button for this? I made a clear button and was able to only allow a line to be drawn after a pencil tool was pressed. However, I don’t know how to turn this off. Also, how can I have the lines appear on the top most layer (over the background and other pictures). I would reaaaaaaally appreciate some help on this!

  • Angie Nov 6, 2011 at 7:12 pm

    Hi, great tutorial, im a student at uni doing a project about Art and works brill and fits in nice with my project area. Thank you.

  • Zach Nov 9, 2011 at 2:44 am

    Awesome tutorial! Just one question: is there any way to make the lines sketch out a radial background or an image, instead of just a solid color?
    Any help would be greatly appreciated!
    – Astonishing Pie

  • Ryan Feb 14, 2012 at 6:18 pm

    How could i allow users to insert text with the drawing?

  • […] http://flashexplained.com//actionscript/making-an-interactive-drawing-sketchpad/ Share this:MoreLike this:LikeBe the first to like this post. […]

  • Mazza Mar 1, 2013 at 3:40 am

    Am I the only one who couldn’t get this to work?

    I don’t understand what I did wrong. The actionscript is a straight copy & paste from this website onto the Actions layer of Frame 1. All my instance names are correct. But every time I press Ctrl + Enter I get a huge list of “Access to undefined property” compile errors.

    I’ve tried this in Actionscript 2 and 3 and it’s made no difference.

    Waaah! What am I doing wrong?

You must log in to post a comment.