forked from: Paint Tool
// forked from whirlpower's Paint Tool
package
{
import flash.display.Sprite;
import flash.events.Event;
/**
* TwitPaintが納得いかないので自分で作ってみる。
* マウスの座標が整数でしかとれないので、線がガタガタになる。
* 高級なツールはどうやってるでしょうね。
*/
public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
addChild( new PaintTool() );
}
}
}
import com.bit101.components.Label;
import com.bit101.components.PushButton;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.ui.Mouse;
/**
* ペイントツール本体
*/
internal class PaintTool extends Sprite
{
private var _data : ToolData;
private var _canvas : Canvas;
private var _backCanvas : Sprite;
private var _backgroud : Shape;
private var _cursor : Cursor;
private var _colorButtons : Array;
private var _brashButtons : Array;
private var _canvasX : int = 32;
private var _canvasY : int = 32;
private var _canvasW : int = 400;
private var _canvasH : int = 300;
public function PaintTool()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// ツールデータの作成
_data = new ToolData();
// 背景の作成
_backgroud = new Shape();
_backgroud.graphics.beginFill( 0xEEEEEE, 1 );
_backgroud.graphics.drawRect( 0, 0, stage.stageWidth, stage.stageHeight );
_backgroud.graphics.endFill();
addChild( _backgroud );
// キャンバス有効面の作成
_backCanvas = new Sprite();
_backCanvas.graphics.beginFill( 0xDDDDDD, 1 );
_backCanvas.graphics.drawRect( 0, 0, stage.stageWidth, _canvasH + _canvasY*2 );
_backCanvas.graphics.endFill();
addChild( _backCanvas );
// キャンバスの作成
_canvas = new Canvas( _data, _canvasW, _canvasH );
_canvas.x = _canvasX;
_canvas.y = _canvasY;
addChild( _canvas );
_backCanvas.addEventListener( MouseEvent.MOUSE_MOVE, mouseMoveHandler );
_backCanvas.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
_backCanvas.addEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
_backCanvas.addEventListener( MouseEvent.MOUSE_OVER, mouseOverHandler );
_backCanvas.addEventListener( MouseEvent.MOUSE_OUT, mouseOutHandler );
// カラーボタンの作成
var posY : int = _canvasH + _canvasY*2 + 15;
var posX : int = 115;
var colorLabel : Label = new Label( this, _canvasX, posY-8, "COLOR" );
_colorButtons = new Array();
var colors : Array = [
0xA40000, 0xE95505, 0xFFF100, 0x8FC31F,
0x007130, 0x00A0E9, 0x00479B, 0xEB6877,
0x601986, 0x6A3906, 0xF8B551, 0x1B1B1B,
0x898989, 0xB5B5B5, 0xFFFFFF
];
for each( var c:uint in colors )
{
var colorButton : ColorButton = new ColorButton( c );
colorButton.addEventListener( MouseEvent.CLICK, changeColor );
colorButton.x = posX;
colorButton.y = posY;
posX += 22;
_colorButtons.push( colorButton );
addChild( colorButton );
}
// ブラシサイズ変更ボタンの作成
posY = _canvasH + _canvasY * 2 + 45;
posX = 115;
var radiusLabel : Label = new Label( this, _canvasX, posY-8, "BRUSH SIZE" );
_brashButtons = new Array();
var brashs : Array = [ 1, 2, 3, 5, 7, 9, 12, 15 ];
for each( var b:uint in brashs )
{
var brashButton : RadiusButton = new RadiusButton( b );
brashButton.addEventListener( MouseEvent.CLICK, changeRadius );
brashButton.x = posX;
brashButton.y = posY;
posX += 22;
_brashButtons.push( brashButton );
addChild( brashButton );
}
posY = _canvasH + _canvasY * 2 + 70;
posX = 105;
// すべて消去ボタン
new PushButton( this, posX, posY, "Ando", ando );
// アンドゥ
new PushButton( this, posX + 110, posY, "Fill Clear", fillAll );
// カーソルの作成
_cursor = new Cursor( _data );
addChild( _cursor );
}
private var _mouseDown : Boolean = false;
private function mouseDownHandler(e:MouseEvent):void
{
_mouseDown = true;
_canvas.startStroke( mouseX - _canvasX , mouseY - _canvasY );
_canvas.draw( mouseX - _canvasX , mouseY - _canvasY );
}
private function mouseUpHandler(e:MouseEvent):void
{
_mouseDown = false;
_canvas.endStroke();
}
private function mouseOverHandler(e:MouseEvent):void
{
_cursor.visible = true;
Mouse.hide();
}
private function mouseOutHandler(e:MouseEvent):void
{
_cursor.visible = false;
Mouse.show();
if ( _mouseDown )
{
_mouseDown = false;
_canvas.endStroke();
}
}
private function mouseMoveHandler(e:MouseEvent):void
{
_cursor.x = this.mouseX;
_cursor.y = this.mouseY;
if( _mouseDown )
{
_canvas.draw( mouseX-_canvasX , mouseY-_canvasY );
}
}
/**
* ペンの太さを変更する。
* @param e
*/
private function changeRadius( e:Event ):void
{
_data.radius = e.target.radius;
_cursor.upDate();
}
/**
* 色を変更する。
* @param e
*/
private function changeColor( e:Event ):void
{
_data.color = e.target.color;
_cursor.upDate();
}
/**
* 全部消す
* @param e
*/
private function fillAll( e:Event ):void
{
_canvas.fillAll( 0xFFFFFF );
_data.lines = new Vector.<Stroke>();
}
/**
* 一筆もどる
* @param e
*/
private function ando( e:Event ):void
{
_data.lines.pop();
_canvas.reDraw();
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Shape;
/**
* 描画領域
*/
internal class Canvas extends Bitmap
{
private var _data : ToolData;
private var _posX : int = 0;
private var _posY : int = 0;
private var _stroke : Stroke;
public function Canvas( data:ToolData, width:int = 400, height:int = 300 ):void
{
_data = data;
bitmapData = new BitmapData( width, height, true, 0xFFFFFFFF );
}
/**
* 描き始めのポイントをセットする。
* @param posX
* @param posY
*/
public function startStroke( posX:Number, posY:Number ):void
{
_posX = posX;
_posY = posY;
_stroke = new Stroke( _data.color, _data.radius );
}
/**
* 描きおわり
*/
public function endStroke():void
{
if ( _stroke )
{
_data.lines.push( _stroke );
}
}
/**
* キャンバスに書き込む
* @param posX
* @param posY
*/
public function draw( posX:int, posY:int ):void
{
var line : Shape = new Shape();
var g : Graphics = line.graphics;
g.lineStyle( _data.radius, _data.color, 1 );
g.moveTo( _posX, _posY );
g.lineTo( posX, posY );
_stroke.stroke.push( posX, posY );
_posX = posX;
_posY = posY;
bitmapData.lock();
bitmapData.draw( line );
bitmapData.unlock();
}
/**
* 描画記録から描画をしなおす。
*/
public function reDraw():void
{
fillAll( 0xFFFFFF );
if ( _data.lines.length == 0 ) return;
var lines : Vector.<Stroke> = _data.lines;
var l : int = lines.length;
for ( var j:int = 0; j < l; j++ )
{
var stroke : Stroke = lines[j];
var __stroke : Vector.<int> = stroke.stroke;
_posX = __stroke[0];
_posY = __stroke[1];
var posX : int;
var posY : int;
var color : uint = stroke.color;
var radius : int = stroke.radius;
var ll : int = __stroke.length;
for (var i:int = 0; i < ll; i +=2 )
{
posX = __stroke[i+0];
posY = __stroke[i+1];
var line : Shape = new Shape();
var g : Graphics = line.graphics;
g.lineStyle( radius, color, 1 );
g.moveTo( _posX, _posY );
g.lineTo( posX, posY );
_posX = posX;
_posY = posY;
bitmapData.lock();
bitmapData.draw( line );
bitmapData.unlock();
}
}
}
/**
* すべてを消す
*/
public function fillAll( color:uint ):void
{
bitmapData.fillRect( bitmapData.rect, color + 0xFF000000 );
}
}
/**
* キャンバス上で扱うデータ
*/
internal class ToolData
{
// position, color, radius
public var lines : Vector.<Stroke> = new Vector.<Stroke>();
public var color : uint = 0x00479B;
public var radius : Number = 4;
}
/**
* 一筆のデータ
*/
internal class Stroke
{
public var stroke : Vector.<int> = new Vector.<int>;
public var color : uint;
public var radius : int;
public function Stroke( color:uint, radius:int ):void
{
this.radius = radius;
this.color = color;
stroke = new Vector.<int>;
}
}
/**
* カーソル
*/
internal class Cursor extends Sprite
{
private var _toolData : ToolData;
public function Cursor( data:ToolData ):void
{
this._toolData = data;
upDate();
mouseEnabled = false;
mouseChildren = false;
}
public function upDate():void
{
graphics.clear();
graphics.beginFill( _toolData.color, 1 );
graphics.drawCircle( 0, 0, _toolData.radius/2 );
graphics.endFill();
}
}
/**
* ペンの太さ変更ボタン
*/
internal class RadiusButton extends Sprite
{
public var radius :uint = 1;
private var _size : int = 20;
public function RadiusButton( radius:uint ):void
{
this.radius = radius;
graphics.beginFill( 0xFFFFFF, 1 );
graphics.drawRect( -_size/2, -_size/2, _size, _size );
graphics.endFill();
graphics.beginFill( 0x000000, 1 );
graphics.drawCircle( 0, 0, radius/2 );
graphics.endFill();
graphics.lineStyle( 0.5, 0x888888, 1 );
graphics.drawRect( -_size/2, -_size/2, _size, _size );
buttonMode = true;
}
}
/**
* カラー変更ボタン
*/
internal class ColorButton extends Sprite
{
public var color :uint;
private var _size : int = 20;
public function ColorButton( color:uint ):void
{
this.color = color;
graphics.beginFill( color, 1 );
graphics.drawRect( -_size/2, -_size/2, _size, _size );
graphics.endFill();
graphics.lineStyle( 0.5, 0x888888, 1 );
graphics.drawRect( -_size/2, -_size/2, _size, _size );
buttonMode = true;
}
}