root/as3/gunyarapaint/trunk/gunyarapaint/src/gunyarapaint.as

リビジョン 1096, 10.4 kB (コミッタ: tasuku, コミット時期: 5 年 前)

r47@poppop (orig r46): tasuku | 2008-04-06 05:47:55 +0900
ドットが描けるようになった。
マウス押下状態のままキャンバスから出て、マウス押下状態のままキャンバスに戻るとひと続きの描画とするようにした。ただし、キャンバス外でマウス押下状態が戻ったときに
描画をコミットする必要あり。

Line 
1 import flash.events.Event;
2
3 import gunyarapaint.Canvas;
4 import gunyarapaint.Com;
5
6 import mx.controls.Alert;
7 import mx.events.ColorPickerEvent;
8 import mx.events.FlexEvent;
9 import mx.events.ListEvent;
10 import mx.events.NumericStepperEvent;
11 import mx.events.SliderEvent;
12
13 private var gpCanvas:gunyarapaint.Canvas;
14 private var basex:uint, basey:uint, baseWidth:uint, baseHeight:uint;
15
16 private var comm:Com;
17 private var oekakiId:uint;
18 private var redirectUrl:String;
19 private var onPost:Boolean = false;
20
21 private var canvasWidth:uint;
22 private var canvasHeight:uint;
23 private var undoBufferSize:uint;
24
25 private const ALERT_TITLE:String = 'お絵カキコ';
26 private const DEBUG:Boolean = true;
27
28 public function init():void { 
29   // 通信系
30   this.enabled = false;
31   comm = new Com();
32   comm.addEventListener('completeGetData', commCompleteHandler);
33  
34   if (parameters['postUrl'] && parameters['cookie'] && parameters['magic'] && parameters['redirectUrl']) {
35     comm.setPostEnv(parameters['postUrl'], parameters['cookie'], parameters['magic']);
36     postOekakiButton.enabled = true;
37     redirectUrl = parameters['redirectUrl'];
38   }
39   if (parameters['undoBufferSize']) {
40     undoBufferSize = int(parameters['undoBufferSize']);
41     if (undoBufferSize < 0) {
42       Alert.show('最大アンドゥ回数が少なすぎます。', ALERT_TITLE);     
43     }
44     if (undoBufferSize > 32) {
45       Alert.show('最大アンドゥ回数が多すぎます。', ALERT_TITLE);     
46     }
47   } else {
48     if (DEBUG) {
49       undoBufferSize = 16;
50     } else {
51       return;
52     }
53   }
54   if (parameters['oekakiId'] && parameters['baseImgUrl']) {
55     oekakiId = uint(parameters['oekakiId']);
56     var url:String = parameters['baseImgUrl'];
57     comm.loadUrl(url);
58     this.enabled = false;
59   } else {
60     if (parameters['canvasWidth'] && parameters['canvasHeight']) {
61       canvasWidth = int(parameters['canvasWidth']);
62       canvasHeight = int(parameters['canvasHeight']);
63       if (canvasWidth < 16 || canvasHeight < 16) {
64         Alert.show('キャンバスサイズが小さすぎます。', ALERT_TITLE);
65         return;
66       }
67       if (canvasWidth > 600 || canvasHeight > 600) {
68         Alert.show('キャンバスサイズが大きすぎます。', ALERT_TITLE);
69         return;
70       }
71     } else {
72       if (DEBUG) {
73         canvasWidth = 300; canvasHeight = 400;
74       } else {
75         return;
76       }
77     }
78     gpCanvas = new gunyarapaint.Canvas(canvasWidth, canvasHeight, undoBufferSize, null, null);
79     initGunyaraPaintCanvas();
80   }
81  
82   // 太さ
83   thicknessStepper.addEventListener(NumericStepperEvent.CHANGE, thicknessStepperHandler);
84   // カラーピッカ
85   colorPicker.addEventListener(ColorPickerEvent.CHANGE, colorPickerHandler);
86   // スポイト
87   dropperButton.addEventListener(Event.CHANGE, dropperButtonHandler);
88   // 透明度
89   alphaSlider.addEventListener(SliderEvent.CHANGE, alphaSliderHandler);
90   // キャンバス回転
91   canvasRotate.addEventListener(SliderEvent.CHANGE, canvasRotateHandler);
92   canvasRotate.addEventListener(SliderEvent.THUMB_DRAG, canvasRotateHandler);
93   // 回転のときに勝手にApplicationの領域が拡大しないように
94   canvas.explicitWidth = 0;
95   canvas.explicitHeight = 0;
96  
97   // ブレンドモード
98   blendModeComboBox.dataProvider = [
99     {label: '通常', data: flash.display.BlendMode.NORMAL},
100     // {label: '消去', data: flash.display.BlendMode.ERASE},
101     {label: '比較(暗)', data: flash.display.BlendMode.DARKEN},
102     {label: '乗算', data: flash.display.BlendMode.MULTIPLY},
103     {label: '比較(明)', data: flash.display.BlendMode.LIGHTEN},
104     {label: 'スクリーン', data: flash.display.BlendMode.SCREEN},
105     {label: '覆い焼き', data: flash.display.BlendMode.ADD},
106     {label: 'オーバーレイ', data: flash.display.BlendMode.OVERLAY},
107     {label: 'ハードライト', data: flash.display.BlendMode.HARDLIGHT},
108     {label: '差の絶対値', data: flash.display.BlendMode.DIFFERENCE},
109     {label: '除外', data: flash.display.BlendMode.SUBTRACT},
110     {label: '反転', data: flash.display.BlendMode.INVERT}];
111   blendModeComboBox.addEventListener(ListEvent.CHANGE, blendModeComboBoxHandler);
112  
113   // アンドゥ・リドゥ
114   undoButton.addEventListener(FlexEvent.BUTTON_DOWN, undoButtonHandler);
115   redoButton.addEventListener(FlexEvent.BUTTON_DOWN, redoButtonHandler);
116    
117   // 補助線
118   additionalNumberStepper.addEventListener(NumericStepperEvent.CHANGE, additionalNumberStepperHandler);
119   additionalBoxCheckBox.addEventListener(Event.CHANGE, additionalBoxCheckBoxHandler);
120   additionalSkewCheckBox.addEventListener(Event.CHANGE, additionalSkewCheckBoxHandler);
121  
122   postOekakiButton.addEventListener(FlexEvent.BUTTON_DOWN, postOekakiButtonHandler);
123      
124   this.enabled = true;
125 }
126
127 private function initGunyaraPaintCanvas():void {
128   canvas.width = canvasWidth;
129   canvas.height = canvasHeight;
130   canvas.addChild(gpCanvas);
131   // スポイトで色取ったイベント
132   gpCanvas.addEventListener('changeColor', changeColorHandler);
133   // undo/redoの状態変化
134   gpCanvas.addEventListener('changeUndoRedo', changeUndoRedoHandler);
135   gpCanvas.rotation = 0;
136
137   this.width = canvasWidth + 20;
138   this.height = canvasHeight + canvas.y + 10;
139  
140   canvas.x = 10;
141   basex = canvas.x;
142   basey = canvas.y;
143   changeGunyaraPaintRect();
144
145   toolCanvas.x = (this.width - toolCanvas.width) / 2;
146 }
147
148 private function commCompleteHandler(evt:Event):void {
149   if (onPost) {
150     onPost = false;
151     if (comm.getHttpStatus() == 202 || comm.getError()) {
152       // error
153       Alert.show(comm.getStringData(), ALERT_TITLE);
154       this.enabled = true;
155     } else {
156       // redirect
157       Com.redirect(redirectUrl);
158     }
159   } else {
160     var baseImg:BitmapData = Bitmap(comm.getContent()).bitmapData;
161     canvasWidth = baseImg.width;
162     canvasHeight = baseImg.height;
163     gpCanvas = new gunyarapaint.Canvas(0, 0, undoBufferSize, null, baseImg);
164     initGunyaraPaintCanvas();
165     this.enabled = true;
166   }
167 }
168
169 private function thicknessStepperHandler(evt:NumericStepperEvent):void {
170   gpCanvas.setLineThickness(evt.value);
171 }
172
173 private function colorPickerHandler(evt:ColorPickerEvent):void {
174   gpCanvas.setLineColor(evt.target.selectedColor);
175 }
176
177 private function alphaSliderHandler(evt:SliderEvent):void {
178   gpCanvas.setLineAlpha(evt.value);
179 }
180
181 private function canvasRotateHandler(evt:SliderEvent):void {
182   gpCanvas.rotation = evt.value;
183  
184   var deg:int = gpCanvas.rotation;
185   var rad:Number = deg * Math.PI / 180;
186   // TODO: dasai
187   if (deg >= 0) {
188     if (deg <= 90) {
189       canvas.x = Math.sin(rad) * canvasHeight + 10;
190       canvas.y = basey;
191       this.width = canvasHeight * Math.sin(rad) +
192                     canvasWidth * Math.cos(rad) + 20;
193       this.height = canvasHeight * Math.cos(rad) +
194                      canvasWidth * Math.abs(Math.sin(rad)) + basey + 10;
195     } else {
196       canvas.x = canvasHeight * Math.sin(rad) - Math.cos(rad) * canvasWidth + 10;
197       canvas.y = basey - Math.cos(rad) * canvasHeight;
198       this.width = canvasHeight * Math.sin(rad) - Math.cos(rad) * canvasWidth + 20;
199       this.height = -canvasHeight * Math.cos(rad) +
200                      canvasWidth * Math.sin(rad) + basey + 10;
201     }
202   } else {
203     if (deg >= -90) {
204       canvas.x = basex;
205       canvas.y = basey - Math.sin(rad) * canvasWidth;
206       this.width = canvasHeight * Math.sin(Math.abs(rad)) +
207                     canvasWidth * Math.cos(rad) + 20;
208       this.height = canvasHeight * Math.cos(rad) +
209                      canvasWidth * Math.abs(Math.sin(rad)) + basey + 10;
210     } else {
211       canvas.x = basex - Math.cos(rad) * canvasWidth;
212       canvas.y = basey - Math.sin(rad) * canvasWidth - Math.cos(rad) * canvasHeight;
213       this.width = basex - Math.cos(rad) * canvasWidth - Math.sin(rad) * canvasHeight + 20;
214       this.height = basey - Math.sin(rad) * canvasWidth - Math.cos(rad) * canvasHeight + 10;
215     }
216   }
217   changeGunyaraPaintRect();
218 }
219 private function changeGunyaraPaintRect():void {
220   // 外部のスクリプト呼び出し。主に回転時のサイズ変更
221   if (this.width < (toolCanvas.width + 4)) {
222     this.width = toolCanvas.width + 4;
223   }
224   if (this.height < 312) { // for color picker
225     this.height = 312;
226   }
227   if (ExternalInterface.available) {
228     try {
229       ExternalInterface.call("changeGunyaraPaintRect", this.width, this.height);
230     } catch (e:SecurityError) {
231     } catch (e:Error) {
232     }
233   } 
234 }
235
236 private function blendModeComboBoxHandler(evt:ListEvent):void {
237   gpCanvas.setLineBlendMode(String(evt.currentTarget.value));
238 }
239 private function undoButtonHandler(evt:FlexEvent):void {
240   gpCanvas.undo();
241 }
242 private function redoButtonHandler(evt:FlexEvent):void {
243   gpCanvas.redo();
244 }
245 private function dropperButtonHandler(evt:Event):void {
246   if (evt.target.selected) {
247     gpCanvas.setPenMode(gpCanvas.MODE_DROPPER);   
248   } else {
249     gpCanvas.setPenMode(gpCanvas.MODE_PEN);
250   }
251 }
252 private function changeColorHandler(evt:Event):void {
253   colorPicker.selectedColor = gpCanvas.getLineColor();
254   alphaSlider.value = 1.0;
255 }
256 private function additionalNumberStepperHandler(evt:NumericStepperEvent):void {
257   gpCanvas.setAdditionalNumber(evt.value);
258 }
259 private function additionalBoxCheckBoxHandler(evt:Event):void {
260   gpCanvas.setAdditionalBox(evt.target.selected);
261 }
262 private function additionalSkewCheckBoxHandler(evt:Event):void {
263   gpCanvas.setAdditionalSkew(evt.target.selected);
264 }
265 private function changeUndoRedoHandler(evt:Event):void {
266   var undoCount:Number = gpCanvas.getUndoCount();
267   var redoCount:Number = gpCanvas.getRedoCount();
268   if (undoCount > 0) {
269     undoButton.label = 'アンドゥ (' + undoCount + ')';
270     undoButton.enabled = true;
271   } else {
272     undoButton.label = 'アンドゥ';
273     undoButton.enabled = false;
274   }
275   if (redoCount > 0) {
276     redoButton.label = 'リドゥ (' + redoCount + ')';
277     redoButton.enabled = true;
278   } else {
279     redoButton.label = 'リドゥ';
280     redoButton.enabled = false;
281   }
282 }
283
284 private function postOekakiButtonHandler(evt:Event):void {
285   if (messageTextArea.text == '') {
286     Alert.show('書き込みが空です。絵のタイトルなどの情報を書き込んでください。', ALERT_TITLE);
287     return;
288   }
289   this.enabled = false;
290   onPost = true;
291   comm.postOekaki(fromTextInput.text,
292                   messageTextArea.text,
293                   gpCanvas.getPNGImage(),
294                   gpCanvas.getCompressedLog(),
295                   oekakiId);
296 }
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。