需求:canvas
公司爲了使得和客戶領導簽字的時候記錄下來,簽字過程,能夠之後動態回放演示,最好是gif圖片,在網頁上也容易展現,文件也小。小程序
解決過程:數組
始咱們去尋找各類app,最終也沒有找到合適的,後來我在flash8上看到有個在線的手繪板,很適合咱們的需求,可是我嘗試了不少次服務器
繪畫完成後,導出的是swf文件,我想從這個swf文件中抽出圖片,最終發現這個導出的swf裏面根本不存在我繪畫的記錄過程。app
網上確實有手繪板的代碼,可是沒有動態回放的功能及處處gif圖片的功能,仍是不知足咱們需求,ide
索性本身寫了一個flash小程序實現手繪畫板及動態回放功能。我把具體的思路及詳細代碼都貼出來,網站
但願能給有用到的人帶來方便。ui
總體思路:url
截圖:spa
具體過程
1、實現手繪板功能,在網上能找到不少代碼,這塊也簡單。
2、在基礎上實現回放功能,我重點講下這裏的實現,起初我是這麼判斷的,當鼠標MOUSE_DOWN時候開始記錄畫筆當前位置信息存入一個數組中(包含X,Y座標值),
鼠標MOUSE_UP的時候,這個數組存儲結束,開啓一個新的數組用於點的信息。當回放的時候,將這些全部數組中的點的信息從新繪製一遍,包括flash8.net的實現都是這麼幹的
若是一筆繪製很長,當它回放的時候一會兒全顯示出來,沒有一個繪製的過程。後來領導說這樣不行,由於領導簽字的時候不少都是一筆走完,最後我想了一個解決的辦法,
就是在回放的時候設置一個閥值,好比50個點,夠50個點就回放一次,這樣一來,即便領導簽字是一筆,回放的時候效果也會很好。
下面是全部ActinScipt源碼
1 import flash.ui.Mouse; 2 import flash.display.BitmapData; 3 import com.adobe.images.JPGEncoder; 4 import flash.events.MouseEvent; 5 6 var linesize:uint = 2;//畫筆大小 7 var isDown:Boolean = false; 8 var oldX:Number; 9 var oldY:Number; 10 var arrayBig:Array=new Array();//存放筆畫的數組,外層數組 11 var num:uint = 0;//當前數組個數 12 var playNum:uint = 0;//當前回放的數字(表明當前回放到第幾個數組了) 13 var intervalDuration:Number = 500;// 回放延時時間間隔 14 var relaseDuration:Number = 1000;//發佈時時間間隔 15 var intervalId:uint;//回放循環的ID 16 var relaseId:uint;//發佈的ID 17 var url = "http://www.wispdawn.com/";//暫用個人網站作服務器 18 var serviceFile = "GetSignImg.ashx";//服務文件 19 20 mc_canvas.addEventListener(MouseEvent.MOUSE_DOWN ,onDown); 21 mc_canvas.addEventListener(MouseEvent.MOUSE_UP ,onUp); 22 mc_canvas.addEventListener(MouseEvent.MOUSE_MOVE ,onMove); 23 mc_canvas.addEventListener(MouseEvent.MOUSE_OVER,onMouseOver); 24 mc_canvas.addEventListener(MouseEvent.MOUSE_OUT,onMouseOut); 25 26 27 28 function onDown(event:MouseEvent):void 29 { 30 arrayBig[num]=new Array();//這裏設置爲數組 31 isDown = true; 32 oldX = mouseX; 33 oldY = mouseY; 34 } 35 function onMove(event:MouseEvent):void 36 { 37 if (isDown) 38 { 39 mc_canvas.graphics.lineStyle(linesize); 40 mc_canvas.graphics.moveTo(oldX,oldY); 41 mc_canvas.graphics.lineTo(mouseX,mouseY); 42 oldX = mouseX; 43 oldY = mouseY; 44 arrayBig[num].push([oldX,oldY]); 45 if (arrayBig[num].length > 80) 46 { 47 //isDown = false; 48 trace(num); 49 num++;//數組個數+1 50 arrayBig[num]=new Array(); 51 arrayBig[num].push([oldX,oldY]); 52 } 53 } 54 } 55 56 function onUp(event:MouseEvent):void 57 { 58 isDown = false; 59 trace(num); 60 num++;//數組個數+1 61 } 62 63 function onMouseOver(event:MouseEvent):void 64 { 65 mc_canvas.addEventListener(Event.ENTER_FRAME, onEnter); 66 } 67 68 69 function onMouseOut(event:MouseEvent):void 70 { 71 mc_canvas.removeEventListener(Event.ENTER_FRAME, onEnter); 72 Mouse.show(); 73 mc_pen.visible = false; 74 } 75 76 //畫布監聽事件 77 function onEnter(event:Event):void 78 { 79 Mouse.hide(); 80 mc_pen.visible = true; 81 mc_pen.x = mouseX + 22; 82 mc_pen.y = mouseY + 22; 83 } 84 85 86 87 //清空 88 btn_clear.addEventListener(MouseEvent.CLICK,onClear); 89 function onClear(event:MouseEvent):void 90 { 91 arrayBig = []; 92 playNum = 0; 93 num = 0; 94 mc_canvas.graphics.clear(); 95 } 96 //保存; 97 btn_save.addEventListener(MouseEvent.CLICK,onSave); 98 function onSave(event:MouseEvent):void 99 { 100 var imager:BitmapData = new BitmapData(mc_canvas.width,mc_canvas.height); 101 imager.draw(mc_canvas); 102 var jpg:JPGEncoder = new JPGEncoder(100); 103 var file:FileReference = new FileReference(); 104 file.save(jpg.encode(imager),"sign.jpg"); 105 106 } 107 108 //回放按鈕 109 btn_replay.addEventListener(MouseEvent.CLICK,onReplay); 110 function onReplay(event:MouseEvent):void 111 { 112 if (arrayBig.length > 0) 113 { 114 mc_canvas.graphics.clear(); 115 //清除畫面; 116 playNum = 0;//初始爲0 117 intervalId = setInterval(onReplayDelay,intervalDuration); 118 } 119 } 120 121 //用於設置循環的回放 122 function onReplayDelay():void 123 { 124 //當前筆畫 125 var arr:Array = arrayBig[playNum]; 126 //當前筆畫下面全部的點 127 for (var i:uint=0; i<arr.length-1; i++) 128 { 129 var curPoint = arr[i]; 130 var nexPoint = arr[i + 1]; 131 mc_canvas.graphics.lineStyle(linesize); 132 mc_canvas.graphics.moveTo(curPoint[0],curPoint[1]); 133 mc_canvas.graphics.lineTo(nexPoint[0],nexPoint[1]); 134 } 135 136 playNum++; 137 if (playNum==num) 138 { 139 clearInterval(intervalId); 140 } 141 } 142 143 //上傳圖片 144 function UpImg(seq:uint):void 145 { 146 var imager:BitmapData = new BitmapData(mc_canvas.width,mc_canvas.height); 147 imager.draw(mc_canvas); 148 var jpg:JPGEncoder = new JPGEncoder(100); 149 var bytes:ByteArray = jpg.encode(imager); 150 151 var signName:String = mc_mask.txt_name.text; 152 var req:URLRequest = new URLRequest(url+serviceFile+"?name="+signName+"&seq="+seq+"&total="+arrayBig.length); 153 req.data = bytes; 154 req.method = URLRequestMethod.POST; 155 req.contentType = "application/octet-stream"; 156 157 var loader:URLLoader = new URLLoader(); 158 loader.dataFormat = URLLoaderDataFormat.BINARY; 159 loader.load(req); 160 } 161 //loader.addEventListener(Event.COMPLETE, completeHandler); 162 163 //function completeHandler(evt:Event):void 164 //{ 165 //trace(evt.target.data); 166 //} 167 168 //發佈 169 btn_release.addEventListener(MouseEvent.CLICK,onReleas); 170 function onReleas(event:MouseEvent):void 171 { 172 if (arrayBig.length > 0) 173 { 174 mc_mask.x = mc_mask.y = 0; 175 mc_mask.mc_mask_bg.alpha = 0.8; 176 mc_mask.btn_complete.visible = false;//隱藏完成 177 mc_mask.btn_down.visible = false;//隱藏下載 178 } 179 } 180 //真正發佈事件執行 181 function Release():void 182 { 183 //當前筆畫 184 var arr:Array = arrayBig[playNum]; 185 //當前筆畫下面全部的點 186 for (var i:uint=0; i<arr.length-1; i++) 187 { 188 var curPoint = arr[i]; 189 var nexPoint = arr[i + 1]; 190 mc_canvas.graphics.lineStyle(linesize); 191 mc_canvas.graphics.moveTo(curPoint[0],curPoint[1]); 192 mc_canvas.graphics.lineTo(nexPoint[0],nexPoint[1]); 193 } 194 //上傳圖片;; 195 UpImg(playNum); 196 playNum++; 197 if (playNum==num) 198 { 199 clearInterval(relaseId); 200 AfterRelease(); 201 } 202 } 203 //取消發佈 204 mc_mask.btn_cancel.addEventListener(MouseEvent.CLICK,onCancel); 205 function onCancel(event:MouseEvent):void 206 { 207 mc_mask.x = 10000; 208 mc_mask.mc_mask_bg.alpha = 0; 209 } 210 //真正發佈按鈕 211 mc_mask.btn_release.addEventListener(MouseEvent.CLICK,onTrueRelease); 212 function onTrueRelease(event:MouseEvent):void 213 { 214 var name1 = mc_mask.txt_name.text; 215 if (name1!="") 216 { 217 BeginRelease(); 218 mc_canvas.graphics.clear(); 219 playNum = 0; 220 relaseId = setInterval(Release,relaseDuration); 221 } 222 else 223 { 224 mc_mask.txt_state.text = "請輸入姓名"; 225 } 226 } 227 //發佈前設置 228 function BeginRelease():void 229 { 230 mc_mask.btn_release.visible = false; 231 mc_mask.btn_cancel.visible = false; 232 mc_mask.txt_name.visible = false; 233 mc_mask.txt_nameTile.visible = false; 234 mc_mask.txt_state.text = "正在發佈..."; 235 } 236 //發佈後設置 237 function AfterRelease():void 238 { 239 mc_mask.btn_complete.visible = true; 240 mc_mask.btn_down.visible = true; 241 mc_mask.btn_complete.addEventListener(MouseEvent.CLICK,onComplete); 242 mc_mask.txt_state.text = "發佈完成"; 243 244 } 245 //發佈完成 246 function onComplete(event:MouseEvent):void 247 { 248 mc_mask.x = 10000; 249 mc_mask.mc_mask_bg.alpha = 0; 250 mc_mask.btn_down.visible = true; 251 mc_mask.btn_release.visible = true; 252 mc_mask.btn_cancel.visible = true; 253 mc_mask.txt_name.visible = true; 254 mc_mask.txt_nameTile.visible = true; 255 mc_mask.txt_state.text = ""; 256 mc_mask.txt_name.text = ""; 257 } 258 259 //下載gif 260 mc_mask.btn_down.addEventListener(MouseEvent.CLICK,onDownGif); 261 function onDownGif(event:MouseEvent):void 262 { 263 var today:Date =new Date(); 264 var todayStr = getDateFormat(today);//獲取當天日期例如 20131130 265 var signName:String = mc_mask.txt_name.text; 266 267 var gifUrl:URLRequest = new URLRequest(url+"/Img/"+signName+"_"+todayStr+"/"+signName+".gif"); 268 var fileRef:FileReference=new FileReference(); 269 //fileRef.addEventListener(ProgressEvent.PROGRESS,onProgress); 270 fileRef.download(gifUrl,"sign.gif"); 271 } 272 function onProgress(event:ProgressEvent):void 273 { 274 var loaded:uint = event.bytesLoaded; 275 var total:uint = event.bytesTotal; 276 } 277 278 //獲取當天日期 279 function getDateFormat( date:Date):String 280 { 281 var dYear:String = String(date.getFullYear()); 282 var dMonth:String = String((date.getMonth() + 1 < 10) ? "0" : "") + (date.getMonth() + 1); 283 var dDate:String = String(date.getDate() < 10 ? "0":"") + date.getDate(); 284 return dYear+dMonth+dDate; 285 }
3、建立一個asp.ne站點,寫個通常處理程序GetSignImg.ashx
這裏就是用於的獲取flash傳遞過來的圖片,獲取後導出jpg圖片序列,而後將這些序列圖片用程序生成一個gif圖片存放在目錄下,當flash點擊處處gif圖片時候,執行下載
源文件以下
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.IO; 6 using System.Drawing.Drawing2D; 7 using System.Drawing.Imaging; 8 using Gif.Components; 9 10 namespace Web 11 { 12 /// <summary> 13 /// GetSignImg1 的摘要說明 14 /// </summary> 15 public class GetSignImg1 : IHttpHandler 16 { 17 public void ProcessRequest(HttpContext context) 18 { 19 string name = context.Request["name"]; 20 int seq = Convert.ToInt32(context.Request["seq"]); 21 int total =Convert.ToInt32(context.Request["total"]); 22 int length = context.Request.TotalBytes; 23 byte[] buffer = context.Request.BinaryRead(length); 24 string newPath=HttpContext.Current.Server.MapPath("Img/" + name + "_"+DateTime.Now.ToString("yyyyMMdd")); 25 if (!Directory.Exists(newPath)) 26 { 27 Directory.CreateDirectory(newPath); 28 }; 29 string path = string.Format("{0}/{1}.jpg", newPath, seq); 30 FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write); 31 BinaryWriter bw = new BinaryWriter(fs); 32 bw.Write(buffer); 33 bw.Close(); 34 fs.Close(); 35 36 //下載gif 37 if (seq + 1 == total) 38 { 39 //生成gif圖片 40 List<string> fileList = new List<string>(); 41 for (int i = 0; i < total; i++) 42 { 43 fileList.Add(newPath + "/" + i + ".jpg"); 44 } 45 string[] imageFilePaths = fileList.ToArray(); 46 string outputFilePath = newPath + "/" + name + ".gif"; 47 AnimatedGifEncoder e = new AnimatedGifEncoder(); 48 e.Start(outputFilePath); 49 //圖片轉換時間 50 e.SetDelay(50); 51 //1表示只動一次,0:表示循環,n:表示循環n次 52 e.SetRepeat(1); 53 for (int i = 0, count = imageFilePaths.Length; i < count; i++) 54 { 55 e.AddFrame(System.Drawing.Image.FromFile(imageFilePaths[i])); 56 } 57 e.Finish(); 58 } 59 } 60 61 public bool IsReusable 62 { 63 get 64 { 65 return false; 66 } 67 } 68 } 69 }
4、全部程序打包下載 Download