Create a Paint in Flash CS3

As stated in Flash Actionscript contest: erase tool you can not "delete" a particular area in a Sprite, MovieClip, or shape of which have been traced lines or rectangles using the pointer graphics. There is, in fact, the only method clear() which, however, has no effect on the entire area of our object. The solution to the problem lies in the ability to use Bitmap and BitmapData objects. As we will see we can directly access and manipulate the Bitmap data in order to "erase" the traits with a real instrument "eraser".

Will present two different methods to realize the "eraser". per esempio. The first "draws" (delete) data directly into the BitmapData, using the method fillRect() - you can also use setPixel() for example. The second method, the one I prefer, uses the methods of mergers (blendMode).

First of all let's see what kind of organization is needed to achieve a minimal simple Painter in Flash. The scheme presented below applies to both the proposals of the "eraser"

schema-bitmap

I created three layers: the first, MovieClip or Sprite, background and acts as the event handler (MouseDown, MouseMove, and MouseUp). The second, the Bitmap is our top most layer, the one that will actually drawn graphics and which will be applied to the "eraser". , ecc…). The third and final layer, the Shape, addresses two issues: the first is that it allows to directly use the functions provided by the pointer graphics (as lineStyle , drawRect() , etc ...). It also increases the performance while tracking graph, as explained in detail below.

METHOD 1 - Direct access to bitmap data

) dalla Shape (layer 3) alla Bitmap (layer 2). This "sample" uses the method fillRect() directly on BitmapData (layer 2) after the design has been copied (using the method draw() ) from the Shape (Layer 3) to Bitmap (layer 2).

Loading ... Flash Player

To understand how it works here is the same movie with the layers apart and in pseudo 3D - drawn in colored Box - source :

Loading ... Flash Player

As you can see, you draw on layer 3, the Shape. When taking the MouseUp event the contents of the Shape is copied to the bitmap (and therefore the data are present in the BitmapData) and then the Shape is clean ( clear() ).

Note: this last point, the clear() on the Shape, it is not to be underestimated. Some examples of the painter in Flash (almost all lack a true "eraser") draw directly on a MovieClip or shape, keeping the latter on data drawn. After a while 'you draw the system slows down, because the area "vector" of the MovieClip increases. In the method I presented this problem is solved in that the data vector of the shape, as copied to the Bitmap, are tasformati in bits and the Shape is deleted, freeing up memory and restituiendo fluidity to the design!

While holding down the Ctrl (control) is "deleted" directly through the BitmapData fillRect() . This is possible because fillRect() , like the other methods that act on BitmapData, allow to set the "color" via 0xARGB, where A is the alpha value, transparency.

The code is as follows - source :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
. MouseEvent ; import flash.events. MouseEvent ;
. BitmapData ; import flash.display. BitmapData ;
. Bitmap ; import flash.display. Bitmap ;
. GradientType ; import flash.display. GradientType ;
/ /
. Matrix ; import flash.geom. Matrix ;
/ /
Boolean = false ; var md: Boolean = false;
/ /
Sprite = new Sprite ( ) ; var event_spr: Sprite = new Sprite ();
event_spr ) ; addChild (event_spr);
/ /
Number = event_spr . stage . stageWidth ; var area_width: Number = event_spr. internship. stageWidth;
Number = event_spr . stage . stageHeight - 32 ; var area_height: Number = event_spr. internship. stageHeight - 32;
/ /
String = GradientType . LINEAR ; fillType var: String = GradientType . LINEAR;
: Array = [ 0xFF0000 , 0x00FF00 , 0x0000ff ] ; var colors: Array = [0xFF0000, 0x00FF00, 0x0000FF];
: Array = [ 1 , 1 , 1 ] ; var alphas: Array = [1, 1, 1];
: Array = [ 0 , 128 , 255 ] ; var ratios: Array = [0, 128, 255];
String = SpreadMethod . PAD ; spreadMethod var: String = SpreadMethod . PAD;
: Matrix = new Matrix ( ) ; var matrix: Matrix = new Matrix ();
createGradientBox ( area_width , area_height , 1 , 0 , 0 ) ; matrix. createGradientBox (area_width, area_height, 1, 0, 0);
/ /
event_spr . graphics ) { with (event_spr. graphics) {
fillType , colors , alphas , ratios , matrix , spreadMethod ) ; beginGradientFill (fillType, colors, alphas, ratios, matrix, spreadMethod);
0 , 0 , area_width , area_height ) ; drawRect (0, 0, area_width, area_height);
; endFill ();
}
/ / Paint event
( MouseEvent . MOUSE_DOWN , _onMouseDown ) ; event_spr. addEventListener ( MouseEvent . MOUSE_DOWN, _onMouseDown);
( MouseEvent . MOUSE_MOVE , _onMouseMove ) ; event_spr. addEventListener ( MouseEvent . MOUSE_MOVE, _onMouseMove);
( MouseEvent . MOUSE_UP , _onMouseUp ) ; event_spr. addEventListener ( MouseEvent . MOUSE_UP, _onMouseUp);
( MouseEvent . MOUSE_OUT , _onMouseUp ) ; event_spr. addEventListener ( MouseEvent . MOUSE_OUT, _onMouseUp);
/ /
BitmapData = new BitmapData ( event_spr . width , event_spr . height , true , 0 ) ; var bmpd: BitmapData = new BitmapData (event_spr. width, event_spr. height, true, 0);
Bitmap = new Bitmap ( bmpd ) ; var bmp: Bitmap = new Bitmap (bmpd);
bmp ) ; addChild (bmp);
/ / Temporary shape
Shape = new Shape ( ) ; var draw_shape: Shape = new Shape ();
draw_shape ) ; addChild (draw_shape);
/ /
e : MouseEvent ) : void { _onMouseDown function (e: MouseEvent ): void {
) ; debug ("_onMouseDown");
: uint = 0xffffff ; var c: uint = 0xffffff;
. lineStyle ( 10 , c , 1 ) ; draw_shape. graphics. lineStyle (10, c, 1);
. moveTo ( e . localX , e . localY ) ; draw_shape. graphics. moveTo (e. localX, and. localY);
md = true;
}
/ /
e : MouseEvent ) : void { _onMouseUp function (e: MouseEvent ): void {
md = false;
. draw ( draw_shape ) ; bmp. bitmapData. draw (draw_shape);
. clear ( ) ; draw_shape. graphics. clear ();
}
/ /
e : MouseEvent ) : void { _onMouseMove function (e: MouseEvent ): void {
) ; debug ("_onMouseMove");
md && ! e . ctrlKey ) { if (md &&! e. ctrlKey) {
. lineTo ( e . localX , e . localY ) ; draw_shape. graphics. lineTo (e. localX, and. localY);
( md && e . ctrlKey ) { } Else if (md && e. CtrlKey) {
. fillRect ( new Rectangle ( e . target . mouseX - 10 , e . target . mouseY - 10 , 20 , 20 ) , 0 ) ; bmp. bitmapData. fillRect (new Rectangle (e. targets. mouseX - 10, and. targets. mouseY - 10, 20, 20), 0);
}
}
/ /
v : String ) : void { function debug (v: String ): void {
: Date = new Date ( ) ; var d: Date = new Date ();
d . getMinutes ( ) + ":" + d . getSeconds ( ) + ":" + d . getMilliseconds ( ) + ": " + v ) ; trace (d. getMinutes () + ":" + d. getSeconds () + ":" + d. getMilliseconds () + ":" + v);
}

The line 61, as shown in the code above, is esguita when the Ctrl key is pressed. As you can see this section of code draws directly into a BitmapData with color 0, or 0 × 0000!

METHOD 2 - Using blending modes

This is probably the best method when you can use any kind of "eraser". Unlike the previous method does not have direct access to the bitmap data present in BitmapData, but you take advantage of blending modes (blendMode) and the copy of the Bitmap using the method draw().

Loading ... Flash Player

3D version - source :

Loading ... Flash Player

. In exactly the same way that we copy the data from the Shape to Bitmap, the "eraser" is "simultato" copying the data from the Shape to Bitmap but, this time, setting the blendMode of the method draw() to erase .

The code is as follows - source :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
. MouseEvent ; import flash.events. MouseEvent ;
. BitmapData ; import flash.display. BitmapData ;
. Bitmap ; import flash.display. Bitmap ;
. GradientType ; import flash.display. GradientType ;
/ /
. Matrix ; import flash.geom. Matrix ;
/ /
Boolean = false ; var md: Boolean = false;
/ /
Sprite = new Sprite ( ) ; var event_spr: Sprite = new Sprite ();
event_spr ) ; addChild (event_spr);
/ /
Number = event_spr . stage . stageWidth ; var area_width: Number = event_spr. internship. stageWidth;
Number = event_spr . stage . stageHeight - 32 ; var area_height: Number = event_spr. internship. stageHeight - 32;
/ /
String = GradientType . LINEAR ; fillType var: String = GradientType . LINEAR;
: Array = [ 0xFF0000 , 0x00FF00 , 0x0000ff ] ; var colors: Array = [0xFF0000, 0x00FF00, 0x0000FF];
: Array = [ 1 , 1 , 1 ] ; var alphas: Array = [1, 1, 1];
: Array = [ 0 , 128 , 255 ] ; var ratios: Array = [0, 128, 255];
String = SpreadMethod . PAD ; spreadMethod var: String = SpreadMethod . PAD;
: Matrix = new Matrix ( ) ; var matrix: Matrix = new Matrix ();
createGradientBox ( area_width , area_height , 1 , 0 , 0 ) ; matrix. createGradientBox (area_width, area_height, 1, 0, 0);
/ /
event_spr . graphics ) { with (event_spr. graphics) {
fillType , colors , alphas , ratios , matrix , spreadMethod ) ; beginGradientFill (fillType, colors, alphas, ratios, matrix, spreadMethod);
0 , 0 , area_width , area_height ) ; drawRect (0, 0, area_width, area_height);
; endFill ();
}
/ / Paint event
( MouseEvent . MOUSE_DOWN , _onMouseDown ) ; event_spr. addEventListener ( MouseEvent . MOUSE_DOWN, _onMouseDown);
( MouseEvent . MOUSE_MOVE , _onMouseMove ) ; event_spr. addEventListener ( MouseEvent . MOUSE_MOVE, _onMouseMove);
( MouseEvent . MOUSE_UP , _onMouseUp ) ; event_spr. addEventListener ( MouseEvent . MOUSE_UP, _onMouseUp);
( MouseEvent . MOUSE_OUT , _onMouseUp ) ; event_spr. addEventListener ( MouseEvent . MOUSE_OUT, _onMouseUp);
/ /
BitmapData = new BitmapData ( event_spr . width , event_spr . height , true , 0 ) ; var bmpd: BitmapData = new BitmapData (event_spr. width, event_spr. height, true, 0);
Bitmap = new Bitmap ( bmpd ) ; var bmp: Bitmap = new Bitmap (bmpd);
bmp ) ; addChild (bmp);
/ / Temporary shape
Shape = new Shape ( ) ; var draw_shape: Shape = new Shape ();
draw_shape ) ; addChild (draw_shape);
/ /
e : MouseEvent ) : void { _onMouseDown function (e: MouseEvent ): void {
) ; debug ("_onMouseDown");
: uint = ( ! e . ctrlKey ? 0xffffff : 0x000000 ) ; var c: uint = (! e. ctrlKey? 0xffffff: 0x000000);
. lineStyle ( 10 , c , 1 ) ; draw_shape. graphics. lineStyle (10, c, 1);
. moveTo ( e . localX , e . localY ) ; draw_shape. graphics. moveTo (e. localX, and. localY);
md = true;
}
/ /
e : MouseEvent ) : void { _onMouseUp function (e: MouseEvent ): void {
md = false;
. draw ( draw_shape , null , null , ( e . ctrlKey ? "erase" : "normal" ) ) ; bmp. bitmapData. draw (draw_shape, null, null, (e. ctrlKey? "erase": "normal"));
. clear ( ) ; draw_shape. graphics. clear ();
}
/ /
e : MouseEvent ) : void { _onMouseMove function (e: MouseEvent ): void {
) ; debug ("_onMouseMove");
md ) { if (md) {
. lineTo ( e . localX , e . localY ) ; draw_shape. graphics. lineTo (e. localX, and. localY);
}
}
/ /
v : String ) : void { function debug (v: String ): void {
: Date = new Date ( ) ; var d: Date = new Date ();
d . getMinutes ( ) + ":" + d . getSeconds ( ) + ":" + d . getMilliseconds ( ) + ": " + v ) ; trace (d. getMinutes () + ":" + d. getSeconds () + ":" + d. getMilliseconds () + ":" + v);
}

This code is not very different from the previous one. The real difference is in row 52! This determines the "blending mode" when copying from Shape to Bitmap, and when the Control key is pressed is used the blending mode to erase .
That's all! We will return to the Bitmap as soon as possible and the differences between MovieClip, Sprite, Shape and Bitmap ... all visual objects!

4 comments to: " "

  1. March 31, 2008 Undolog.com »Blog Archive» How to save images in Flash CS3 :

    [...] How to save images in Flash CS3 Tags: ActionScript 3.0, Bitmap, BitmapData, Flash CS3, GD, GD Library, Internet, PHP, Save Flash Image, Development, Flash CS3 TutorialsCon the use of Bitmap is so improved that is immediately want to create a small Paint. We have already seen how to make a small Paint (see Creating a € ™ Paint application in Flash CS3 and Painter: simple application for drawing in Flash CS3 Pro) can support a true "eraser" - erase function, thanks to the use particular layer Shape and Bitmap. Let's say that Flash (unlike Flex) it does not allow encoding (such as JPG or PNG) will automatically save Bitmap images. However you can get around it by using server-side scripting and Flash's ability to send data in POST. [...]

  2. October 8, 2008 Guide ActionScript 3 in Flash CS3: mouse events | Marcello Surdi:

    [...] Create an application in Flash CS3 Paint [...]

  3. October 30, 2008 Gianni:

    Excellent solution, suitable for innnumerevoli solutions related to web application also graphic.

Leave a comment

TAG XHTML PERMITS: CODE ENTRY:
 <pre></pre> // blocco generico <code></code> // blocco generico [cc_actionscript][/cc_actionscript] // Actionscript [cc_actionscript3][/cc_actionscript3] // Actionscript 3 [cc_css][/cc_css] // CSS Style Sheet [cc_html][/cc_html] // HTML [cc_js][/cc_js] // Javascript [cc_objc][/cc_objc] // Objective-C [cc_php][/cc_objc] // PHP [cc_sql][/cc_sql] // SQL