Painting Flash CS3: real time erase tool

Partendo dai codici forniti in Creare un’applicazione Paint in Flash CS3, ed eseguendo piccole modifiche, si può migliorare notevolmente lo strumento di “erase”. Aggiungendo una Shape non visibile, è possibile usarla come “piano” per eseguire il draw() in modalità di fusione “erase”. Come mostrato nell’esempio qui sotto, dopo aver disegnato qualcosa, tenete premuto il tasto Ctrl e l’effetto di “cancellazione” appare ora in tempo reale.

Loading Flash Player...

Il codice è il seguente – sorgente:

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
69
70
71
72
73
74
75
76
import flash.events.MouseEvent;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.GradientType;
//
import flash.geom.Matrix;
//
var md:Boolean = false;
//
var event_spr:Sprite = new Sprite();
addChild (event_spr);
//
var area_width:Number = event_spr.stage.stageWidth;
var area_height:Number = event_spr.stage.stageHeight-32;
//
var fillType:String = GradientType.LINEAR;
var colors:Array = [0xFF0000, 0x00FF00, 0x0000ff];
var alphas:Array = [1, 1, 1];
var ratios:Array = [0, 128, 255];
var spreadMethod:String = SpreadMethod.PAD;
var matrix:Matrix = new Matrix();
matrix.createGradientBox (area_width, area_height, 1, 0, 0);
//
with (event_spr.graphics) {
    beginGradientFill (fillType,colors,alphas,ratios,matrix,spreadMethod);
    drawRect (0,0,area_width, area_height);
    endFill ();
}
// paint event
event_spr.addEventListener (MouseEvent.MOUSE_DOWN, _onMouseDown);
event_spr.addEventListener (MouseEvent.MOUSE_MOVE, _onMouseMove);
event_spr.addEventListener (MouseEvent.MOUSE_UP, _onMouseUp);
event_spr.addEventListener (MouseEvent.MOUSE_OUT, _onMouseUp);
//
var bmpd:BitmapData = new BitmapData(event_spr.width,event_spr.height,true,0);
var bmp:Bitmap = new Bitmap(bmpd);
addChild (bmp);
//
// shape temporanea
var draw_shape:Shape = new Shape();
addChild (draw_shape);
//
// shape, non visibile, usata per la "cancellazione"
var erase_shape:Shape = new Shape();

//
function _onMouseDown (e:MouseEvent):void {
    debug ("_onMouseDown");
    draw_shape.graphics.lineStyle (10, 0xffffff, 1);
    erase_shape.graphics.lineStyle (20, 0xffffff, 1);
    draw_shape.graphics.moveTo (e.localX,e.localY);
    erase_shape.graphics.moveTo (e.localX,e.localY);
    md = true;
}
//
function _onMouseUp (e:MouseEvent):void {
    md = false;
    bmp.bitmapData.draw (draw_shape);
    draw_shape.graphics.clear ();
    erase_shape.graphics.clear ();
}
//
function _onMouseMove (e:MouseEvent):void {
    debug ("_onMouseMove");
    if (md && !e.ctrlKey) {
        draw_shape.graphics.lineTo (e.localX,e.localY);
    } else if (md && e.ctrlKey) {
        erase_shape.graphics.lineTo (e.localX,e.localY);
        bmp.bitmapData.draw (erase_shape,null,null,"erase");
    }
}
//
function debug (v:String):void {
    var d:Date = new Date();
    trace (d.getMinutes()+":"+d.getSeconds()+":"+d.getMilliseconds()+": "+v);
}

È stata aggiunta una nuova Shape, erase_shape, non visibile (non è stato effettuato nessun addChild()):

1
2
3
...
// shape, non visibile, usata per la "cancellazione"
var erase_shape:Shape = new Shape();

Nella parte di codice che si preoccupa di disegnare è stato introdotto il controllo per il tasto Ctrl e, se premuto, viene interessata proprio la Shape erase_shape e copiata sulla Bitmap:

1
2
3
....
erase_shape.graphics.lineTo (e.localX,e.localY);
bmp.bitmapData.draw (erase_shape,null,null,"erase");
  • Greg

    Una mejora leve en la función y mí del drenaje le hizo una clase.

    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    package{
       
        import flash.display.Sprite;
        import flash.events.MouseEvent;
        import flash.display.BitmapData;
        import flash.display.Bitmap;
        import flash.display.GradientType;
        import flash.display.SpreadMethod;
        import flash.display.Shape;
        import flash.geom.Matrix;
        import flash.utils.setInterval;
        import flash.utils.clearInterval;
       
        public class BitmapErase extends Sprite {
           
            private var md:Boolean = false;
            private var event_spr:Sprite;
            private var area_width:Number;
            private var area_height:Number;
            private var fillType:String = GradientType.LINEAR;
            private var colors:Array = [0xFF0000, 0x00FF00, 0x0000ff];
            private var alphas:Array = [1, 1, 1];
            private var ratios:Array = [0, 128, 255];
            private var spreadMethod:String = SpreadMethod.PAD;
            private var matrix:Matrix = new Matrix();
            private var erase_shape:Shape;
            private var draw_shape:Shape;
            private var bmpd:BitmapData;
            private var bmp:Bitmap;
            private var interval:uint;
           
            public function BitmapErase(){
                draw_shape = new Shape();
                addChild (draw_shape);
                erase_shape = new Shape();
                event_spr = new Sprite();
                addChild (event_spr);
                area_width = event_spr.stage.stageWidth;
                area_height = event_spr.stage.stageHeight-32;
                matrix.createGradientBox (area_width, area_height, 1, 0, 0);
               
                event_spr.graphics.beginGradientFill (fillType,colors,alphas,ratios,matrix,spreadMethod);
                event_spr.graphics.drawRect (0,0,area_width, area_height);
                event_spr.graphics.endFill ();
           
                event_spr.addEventListener (MouseEvent.MOUSE_DOWN, _onMouseDown);
                event_spr.addEventListener (MouseEvent.MOUSE_MOVE, _onMouseMove);
                event_spr.addEventListener (MouseEvent.MOUSE_UP, _onMouseUp);
                event_spr.addEventListener (MouseEvent.MOUSE_OUT, _onMouseUp);
               
                bmpd = new BitmapData(event_spr.width,event_spr.height,true,0);
                bmp = new Bitmap(bmpd);
                addChild (bmp);
            }

            private function _onMouseDown (e:MouseEvent):void {
                //debug ("_onMouseDown");
                draw_shape.graphics.lineStyle (10, 0xffffff, 1);
                erase_shape.graphics.lineStyle (20, 0xffffff, 1);
                draw_shape.graphics.moveTo (e.localX,e.localY);
                erase_shape.graphics.moveTo (e.localX,e.localY);
                md = true;
            }
            private function _onMouseUp (e:MouseEvent):void {
                md = false;
                draw_shape.graphics.clear ();
                erase_shape.graphics.clear ();
                clearInterval(interval);
            }
            private function _onMouseMove (e:MouseEvent):void {
                //debug ("_onMouseMove");
                if (md && !e.ctrlKey) {
                    draw_shape.graphics.lineTo (e.localX,e.localY);
                    interval = setInterval(drawNow,1);
                } else if (md && e.ctrlKey) {
                    erase_shape.graphics.lineTo (e.localX,e.localY);
                    bmp.bitmapData.draw (erase_shape,null,null,"erase");
                }
            }
            private function debug (v:String):void {
                var d:Date = new Date();
                trace (d.getMinutes()+":"+d.getSeconds()+":"+d.getMilliseconds()+": "+v);
            }
            private function drawNow():void{
                bmp.bitmapData.draw (draw_shape);
            }
        }
    }
  • http://www.undolog.com Giovambattista Fazioli

    @Greg: good!! :D

  • Sarah-Jane

    This is totally awesome! Great job. Is it possible to have the same thing here except that it is erasing a movieclip exposing the background image underneath it?

    Ciò è completamente impressionante! Grande lavoro. È possibile avere la stessa cosa qui salvo che sta cancellando una clip di film gli che espone l’immagine di priorità bassa?