自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用HTML 5和Javascript設(shè)計繪圖程序

開發(fā) 前端
在本文中,將會介紹如何使用HTML5和Javascript去設(shè)計一個簡單的繪圖程序。HTML5的一個新的特性是canvas畫布功能,通過canvas畫布的強(qiáng)大功能可以實(shí)現(xiàn)繪畫不少圖形和其他絢麗的功能。

在本文中,將會介紹如何使用HTML5和Javascript去設(shè)計一個簡單的繪圖程序。HTML5的一個新的特性是canvas畫布功能,通過canvas畫布的強(qiáng)大功能可以實(shí)現(xiàn)繪畫不少圖形和其他絢麗的功能。在本文中,讀者將學(xué)習(xí)到如下幾個知識點(diǎn):

1) 如何動態(tài)在canvas畫布上繪畫圖形

2) HTML 5 canvas的前景特性探討

3) 目前瀏覽器對HTML5的兼容情況

本文的讀者對象為,對HTML 5 Canvas有初步認(rèn)識及熟悉Javascript的讀者。

設(shè)計目標(biāo)

首先,我們來設(shè)計下這個繪圖程序?qū)碛惺裁垂δ?。在這個簡單的繪圖程序中,首先要有的是一塊能給用戶涂鴉的畫布區(qū)域,上面有一只可愛的小鴨,然后我們準(zhǔn)備了4種不同顏色的蠟筆,可以給用戶給這只小鴨上色,同時也要提供橡皮擦的功能,以方便隨時擦除這個小鴨。而除了蠟筆外,也提供了普通的油畫筆的效果,當(dāng)然也指定了每次繪畫時筆觸范圍的大小,這里設(shè)定了4個選擇。設(shè)計好后的繪圖應(yīng)用,效果如下圖:

在這個應(yīng)用中,用戶點(diǎn)左邊的四種顏色筆,就可以在指定的矩形框中隨便涂鴉,也可而已點(diǎn)右面兩種不同的筆觸效果(crayon蠟筆)和普通筆,也可以使用橡皮擦,也可以使用右下角四種不同的筆觸大小。

開始使用Canvas畫布

首先,要聲明一個canvas畫布,使用如下代碼聲明:

目前,對canvas支持的最好的瀏覽器依然是FireFox,Chrome等非IE的瀏覽器,在本文的這個例子中,也兼顧了對IE瀏覽器的支持,使用的是一個開源的JS文件,其中提供了一些對canvas的基本支持腳本(在附件下載中包含了該腳本,名稱為excanvas.js)。因此,我們可以同時也為了兼顧IE,所以這里改用了

的方式,如下代碼:

接下來,為了要使用canvas畫布的功能,必須如下調(diào)用:

  1. context = document.getElementById('canvasInAPerfectWorld').getContext("2d"); 

然而,同樣為了兼顧在IE下的使用,我們改用以下的代碼段實(shí)現(xiàn):

  1. var canvasDiv = document.getElementById('canvasDiv');  
  2.   canvas = document.createElement('canvas');  
  3.   canvas.setAttribute('width', canvasWidth);  
  4.   canvas.setAttribute('height', canvasHeight);  
  5.   canvas.setAttribute('id''canvas');  
  6.   canvasDiv.appendChild(canvas);  
  7.   if(typeof G_vmlCanvasManager != 'undefined') {  
  8.   canvas = G_vmlCanvasManager.initElement(canvas);  
  9.   }  
  10. context = canvas.getContext("2d"); 

可以看到,在上面的代碼中,通過document.createElement創(chuàng)建了一個標(biāo)簽元素canvas,然后再用setAttribute方法設(shè)置了畫布的高度和寬度等屬性(這些都可以通過設(shè)置常量屬性值進(jìn)行設(shè)置)。然后通過

  1. canvasDiv.appendChild(canvas); 

為canvasDiv增加了一個子元素canvas。然后利用excanvas.js這個專門為IE擴(kuò)展的canvas元素包中提供的處理方法initElement進(jìn)行相應(yīng)的判斷處理,即:

  1. if(typeof G_vmlCanvasManager != 'undefined') {  
  2.   canvas = G_vmlCanvasManager.initElement(canvas);  
  3.   } 

最后,要使用canvas的繪圖功能的話,必須調(diào)用canvas的上下文,這里使用的語句是:

  1. context = canvas.getContext("2d"); 

在畫布上繪畫圖形

接下來,我們開始在canvas上繪制圖形。這里我們要對4個鼠標(biāo)的相關(guān)事件進(jìn)行編碼,并且要編寫兩個相關(guān)的方法addClick和redraw。addClick方法記錄鼠標(biāo)移動的點(diǎn),而redraw方法則將已記錄的數(shù)據(jù)點(diǎn)在canvas畫布中繪畫出來。

先來看下鼠標(biāo)按下時的mouse down事件,代碼如下:

  1. $('#canvas').mousedown(function(e){  
  2.   var mouseX = e.pageX - this.offsetLeft;  
  3.   var mouseY = e.pageY - this.offsetTop;  
  4.   paint = true;  
  5.   addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);  
  6.   redraw();  
  7.   }); 

其中設(shè)置的變量paint為true時,表明當(dāng)前正在繪制圖形,patint為false時,表示鼠標(biāo)已經(jīng)松開。

再看下鼠標(biāo)移動時的事件,代碼如下:

  1. $('#canvas').mousemove(function(e){  
  2.   if(paint){//是不是按下了鼠標(biāo)  
  3.   addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);  
  4.   redraw();  
  5.   }  
  6.  }); 

鼠標(biāo)松開時的事件代碼為:

  1. $('#canvas').mouseup(function(e){  
  2.   paint = false;  
  3.   }); 

鼠標(biāo)移開的事件代碼為:

  1. $('#canvas').mouseleave(function(e){  
  2.   paint = false;  
  3.   }); 

下面是addClick方法的代碼如下:

  1. var clickX = new Array();  
  2.   var clickY = new Array();  
  3.   var clickDrag = new Array();  
  4.   var paint;  
  5.   function addClick(x, y, dragging)  
  6.   {  
  7.   clickX.push(x);  
  8.   clickY.push(y);  
  9.   clickDrag.push(dragging);  
  10.   } 

可以看到,這里分別用三個數(shù)組clickX,clickY及clickDrag記錄了鼠標(biāo)移動的點(diǎn)的X,Y坐標(biāo),以及判斷是否鼠標(biāo)松開的標(biāo)志。

再來看下redraw這個方法,其作用為每次都清空畫板,然后重新把所有的點(diǎn)都畫過,效率不高,但作為本例子來說還是可以接受,代碼如下:

  1. function redraw(){  
  2.   canvas.width = canvas.width; // Clears the canvas  
  3.   context.strokeStyle = "#df4b26";  
  4.   context.lineJoin = "round";  
  5.   context.lineWidth = 5;  
  6.   for(var i=0; i < clickX.length; i++)  
  7.   {  
  8.   context.beginPath();  
  9.   if(clickDrag[i] && i){//當(dāng)是拖動而且i!=0時,從上一個點(diǎn)開始畫線。  
  10.   context.moveTo(clickX[i-1], clickY[i-1]);  
  11.   }else{  
  12.   context.moveTo(clickX[i]-1, clickY[i]);  
  13.   }  
  14.   context.lineTo(clickX[i], clickY[i]);  
  15.   context.closePath();  
  16.   context.stroke();  
  17.  }  
  18.   }  

接下來,再定義四種不同的顏色:紫色,綠色,棕色和黃色,分別用四個不同的變量表示,并且用變量curColor保存當(dāng)前正在使用的顏色,并且也用一個數(shù)組clickColor來記錄用戶每次選擇的顏色。代碼如下:

  1. var colorPurple = "#cb3594";  
  2.   var colorGreen = "#659b41";  
  3.   var colorYellow = "#ffcf33";  
  4.   var colorBrown = "#986928";  
  5.   var curColor = colorPurple;  
  6.   var clickColor = new Array();  

同樣,在addClick方法中,也必須加入對用戶每次選擇顏色的記錄,所以更新后的addclick代碼如下:

  1. function addClick(x, y, dragging)  
  2.   {  
  3.   clickX.push(x);  
  4.   clickY.push(y);  
  5.   clickDrag.push(dragging);  
  6.   clickColor.push(curColor);  
  7.   } 

而在redraw的方法中,我們?nèi)サ鬰ontext.strokeStyle一句,將繪畫筆的顏色設(shè)置到for循環(huán)中去設(shè)置,更新后的redraw代碼如下:

  1. function redraw(){  
  2.   /* context.strokeStyle = "#df4b26"; */ 
  3.   context.lineJoin = "round";  
  4.   context.lineWidth = 5;  
  5.   for(var i=0; i < clickX.length; i++)  
  6.   {  
  7.   context.beginPath();  
  8.   if(clickDrag[i] && i){  
  9.   contex.moveTo(clickX[i-1], clickY[i-1]);  
  10.   }else{  
  11.   context.moveTo(clickX[i]-1, clickY[i]);  
  12.   }  
  13.   context.lineTo(clickX[i], clickY[i]);  
  14.   context.closePath();  
  15.   context.strokeStyle = clickColor[i];  
  16.   context.stroke();  
  17.   }  
  18.   } 

我們再設(shè)置畫筆每次繪畫筆觸范圍的大小,同樣,有四種選擇,分別為小,中,大和很大,并用clickSize數(shù)組記錄用戶的選擇,默認(rèn)的筆觸范圍大小用curSize進(jìn)行記錄。并且也要更新redraw方法,更新后的addClick,redraw代碼如下:

  1. function addClick(x, y, dragging)  
  2.   {  
  3.   clickX.push(x);  
  4.   clickY.push(y);  
  5.   clickDrag.push(dragging);  
  6.   clickColor.push(curColor);  
  7.   clickSize.push(curSize);  
  8.   }  
  9.   var radius;  
  10.   var i = 0;  
  11.   for(; i < clickX.length; i++)  
  12.   {  
  13.   if(clickSize[i] == "small"){  
  14.   radius = 2;  
  15.   }else if(clickSize[i] == "normal"){  
  16.  radius = 5;  
  17.   }else if(clickSize[i] == "large"){  
  18.   radius = 10;  
  19.   }else if(clickSize[i] == "huge"){  
  20.   radius = 20;  
  21.   }else{  
  22.   alert("Error: Radius is zero for click " + i);  
  23.   radius = 0;  
  24.   }  
  25.   function redraw(){  
  26.   ........ 
  27.   context.strokeStyle = clickColor[i];  
  28.   context.lineWidth = radius;  
  29.   context.stroke();  
  30.   }  
  31.   }  
  32.  
  33.   

最后,我們設(shè)置不同筆的繪畫效果,分別是蠟筆和普通筆以及橡皮擦功能。用clickTool記錄用戶選擇的工具種類,curTool則為當(dāng)前用戶選擇的工具,addClick的方法如下:

  1. function addClick(x, y, dragging)  
  2.   {  
  3.   clickX.push(x);  
  4.   clickY.push(y);  
  5.   clickDrag.push(dragging);  
  6.   if(curTool == "eraser"){  
  7.   clickColor.push("white");  
  8.   }else{  
  9.   clickColor.push(curColor);  
  10.   }  
  11.   clickColor.push(curColor);  
  12.   clickSize.push(curSize);  
  13.   }  

注意,這里判斷如果用戶選擇的工具是橡皮擦,則將白色加入到clickColor數(shù)組中。同樣要在redraw的方法中對新的兩個繪圖工具進(jìn)行處理,代碼如下:

  1. function redraw(){  
  2.   context.lineJoin = "round";  
  3.   for(var i=0; i < clickX.length; i++)  
  4.   {  
  5.   context.beginPath();  
  6.   if(clickDrag[i] && i){  
  7.   context.moveTo(clickX[i-1], clickY[i-1]);  
  8.   }else{  
  9.   context.moveTo(clickX[i]-1, clickY[i]);  
  10.   }  
  11.   context.lineTo(clickX[i], clickY[i]);  
  12.   context.closePath();  
  13.   context.strokeStyle = clickColor[i];  
  14.   context.lineWidth = radius;  
  15.   context.stroke();  
  16.   }  
  17.   if(curTool == "crayon") {  
  18.   context.globalAlpha = 0.4;  
  19.   context.drawImage(crayonTextureImage, 0, 0, canvasWidth, canvasHeight);  
  20.   }  
  21.   context.globalAlpha = 1;  
  22.   } 

這里針對當(dāng)用戶選擇“crazyon”蠟筆效果時,對繪畫的效果進(jìn)行了透明度的處理。

最后,我們要把小鴨子的圖在畫布中畫上,首先要聲明一個圖片對象如下:

  1.  var outlineImage = new Image(); 

然后在prepareCanvas()方法中加載事先準(zhǔn)備好的圖片:

  1. function prepareCanvas(){  
  2.   ...  
  3.   outlineImage.src = "images/watermelon-duck-outline.png";  
  4.  
  5.   } 

最后在redraw的繪畫方法中,要使用canvas畫布的drawImage方法進(jìn)行繪畫,代碼為:

  1. function redraw(){  
  2.   ...  
  3.   context.drawImage(outlineImage, drawingAreaX, drawingAreaY, drawingAreaWidth, drawingAreaHeight);  
  4.   }  

其中drawingAreaX, drawingAreaY為要在哪個具體位置繪畫圖形,drawingAreaWidth和

drawingAreaHeight則為具體圖片的寬度和高度。

我們還要把繪圖的區(qū)域限制在一個矩形框里,這要用到畫布的save和clip方法。其中save用來保存Canvas的狀態(tài),而clip方法則是指定一個區(qū)域進(jìn)行剪裁,規(guī)定了繪畫的區(qū)域,代碼如下:

  1.  function redraw()  
  2.   {  
  3.   ...  
  4.   context.save();  
  5.   context.beginPath();  
  6.   context.rect(drawingAreaX, drawingAreaY, drawingAreaWidth, drawingAreaHeight);  
  7.   context.clip(); //剪裁出指定的繪畫區(qū)域  
  8.   var radius;  
  9.   var i = 0;  
  10.   for(; i < clickX.length; i++)  
  11.   {  
  12.   ...  
  13.   }  
  14.   context.restore(); //使用restore方法,恢復(fù)每次保存的canvas狀態(tài)  
  15.   ...  
  16.   } 

總結(jié)

本文中只是對如何使用HTML5和javascript繪制小繪圖應(yīng)用進(jìn)行了思路和基本技術(shù)點(diǎn)的分析,其中著重介紹了畫布canvas的各種使用方法,完整的代碼請到這里下載

(http://www.williammalone.com/articles/create-html5-canvas-javascript-drawing-app/downloads/html5-canvas-drawing-app.zip ),代碼中完成實(shí)現(xiàn)了相關(guān)的各種功能,并加入了一些邏輯判斷等操作,由于篇幅關(guān)系,不再在文中詳細(xì)描述。

原文:http://tech.it168.com/a2011/1104/1269/000001269250_all.shtml

【編輯推薦】

  1. HTML 5 VS Flash 誰是海賊王
  2. HTML 5新特性與技巧
  3. HTML 5特效頁面及js測試頁面匯總推薦
  4. 學(xué)習(xí)HTML 5的10個頂級資源
  5. 49個超炫的HTML 5示例
責(zé)任編輯:陳貽新 來源: it168
相關(guān)推薦

2011-05-25 09:34:30

HTML5cssjavascript

2013-08-26 17:41:43

JavaScriptWindows 8.1

2011-04-07 11:33:00

HTML 5JavaScript

2011-01-27 13:08:57

HTML5JavascriptWeb

2012-09-19 15:21:48

Worklight

2011-12-15 01:01:16

ibmdw

2014-10-21 17:34:11

HTML5移動設(shè)計

2012-01-09 13:24:27

2012-05-30 09:22:56

Hybrid App助HTML5JavaScript

2014-04-17 09:54:47

HTML5JavaScript

2013-08-30 10:02:48

2013-09-16 10:19:08

htmlcssJavaScript

2014-02-11 11:21:00

html5工具

2012-06-13 14:19:27

2011-03-08 10:15:08

HTML 5

2015-06-26 11:51:26

HTML5JavaScript

2012-02-01 09:30:54

HTML 5

2013-01-18 10:59:44

IBMdW

2016-05-27 15:44:12

H5LeanCloudWex5

2010-07-28 08:41:17

HTML5Web移動應(yīng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號