使用HTML5和Javascript設計繪圖程序

2020-12-19 IT168

    【IT168 專稿】前言

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

  1) 如何動態在canvas畫布上繪畫圖形

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

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

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

  設計目標

  首先,我們來設計下這個繪圖程序將會擁有什麼功能。在這個簡單的繪圖程序中,首先要有的是一塊能給用戶塗鴉的畫布區域,上面有一隻可愛的小鴨,然後我們準備了4種不同顏色的蠟筆,可以給用戶給這隻小鴨上色,同時也要提供橡皮擦的功能,以方便隨時擦除這個小鴨。而除了蠟筆外,也提供了普通的油畫筆的效果,當然也指定了每次繪畫時筆觸範圍的大小,這裡設定了4個選擇。設計好後的繪圖應用,效果如下圖:

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

  開始使用Canvas畫布

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

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

  的方式,如下代碼:

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

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

  然而,同樣為了兼顧在IE下的使用,我們改用以下的代碼段實現:

var canvasDiv = document.getElementById('canvasDiv');

  canvas
= document.createElement('canvas');

  canvas.setAttribute(
'width', canvasWidth);

  canvas.setAttribute(
'height', canvasHeight);

  canvas.setAttribute(
'id', 'canvas');

  canvasDiv.appendChild(canvas);

  
if(typeof G_vmlCanvasManager != 'undefined') {

  canvas
= G_vmlCanvasManager.initElement(canvas);

  }

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

 

  可以看到,在上面的代碼中,通過document.createElement創建了一個標籤元素canvas,然後再用setAttribute方法設置了畫布的高度和寬度等屬性(這些都可以通過設置常量屬性值進行設置)。然後通過

canvasDiv.appendChild(canvas);

  為canvasDiv增加了一個子元素canvas。然後利用excanvas.js這個專門為IE擴展的canvas元素包中提供的處理方法initElement進行相應的判斷處理,即:

  

if(typeof G_vmlCanvasManager != 'undefined') {

  canvas
= G_vmlCanvasManager.initElement(canvas);

  }

 

  最後,要使用canvas的繪圖功能的話,必須調用canvas的上下文,這裡使用的語句是:

  

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

 

  在畫布上繪畫圖形

  接下來,我們開始在canvas上繪製圖形。這裡我們要對4個滑鼠的相關事件進行編碼,並且要編寫兩個相關的方法addClick和redraw。addClick方法記錄滑鼠移動的點,而redraw方法則將已記錄的數據點在canvas畫布中繪畫出來。

  先來看下滑鼠按下時的mouse down事件,代碼如下:

  

$('#canvas').mousedown(function(e){

  var mouseX
= e.pageX - this.offsetLeft;

  var mouseY
= e.pageY - this.offsetTop;

  paint
= true;

  addClick(e.pageX
- this.offsetLeft, e.pageY - this.offsetTop);

  redraw();

  });

 

  其中設置的變量paint為true時,表明當前正在繪製圖形,patint為false時,表示滑鼠已經鬆開。

  再看下滑鼠移動時的事件,代碼如下:

  

$('#canvas').mousemove(function(e){

  
if(paint){//是不是按下了滑鼠

  addClick(e.pageX
- this.offsetLeft, e.pageY - this.offsetTop, true);

  redraw();

  }

  });

 

  滑鼠鬆開時的事件代碼為:

 

 $('#canvas').mouseup(function(e){

  paint
= false;

  });

 

  滑鼠移開的事件代碼為:

  

$('#canvas').mouseleave(function(e){

  paint
= false;

  });

 

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

  

var clickX = new Array();

  var clickY
= new Array();

  var clickDrag
= new Array();

  var paint;

  
function addClick(x, y, dragging)

  {

  clickX.push(x);

  clickY.push(y);

  clickDrag.push(dragging);

  }

 

  可以看到,這裡分別用三個數組clickX,clickY及clickDrag記錄了滑鼠移動的點的X,Y坐標,以及判斷是否滑鼠鬆開的標誌。

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

function redraw(){

  canvas.width
= canvas.width; // Clears the canvas

  context.strokeStyle
= "#df4b26";

  context.lineJoin
= "round";

  context.lineWidth
= 5;

  
for(var i=0; i < clickX.length; i++)

  {

  context.beginPath();

  
if(clickDrag[i] && i){//當是拖動而且i!=0時,從上一個點開始畫線。

  context.moveTo(clickX[i
-1], clickY[i-1]);

  }
else{

  context.moveTo(clickX[i]
-1, clickY[i]);

  }

  context.lineTo(clickX[i], clickY[i]);

  context.closePath();

  context.stroke();

  }

  }

 

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

 

  var colorPurple = "#cb3594";

  var colorGreen
= "#659b41";

  var colorYellow
= "#ffcf33";

  var colorBrown
= "#986928";

  var curColor
= colorPurple;

  var clickColor
= new Array();

 

 

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

  

function addClick(x, y, dragging)

  {

  clickX.push(x);

  clickY.push(y);

  clickDrag.push(dragging);

  clickColor.push(curColor);

  }

 

  而在redraw的方法中,我們去掉context.strokeStyle一句,將繪畫筆的顏色設置到for循環中去設置,更新後的redraw代碼如下:

 

function redraw(){

  
/* context.strokeStyle = "#df4b26"; */

  context.lineJoin
= "round";

  context.lineWidth
= 5;

  
for(var i=0; i < clickX.length; i++)

  {

  context.beginPath();

  
if(clickDrag[i] && i){

  contex.moveTo(clickX[i
-1], clickY[i-1]);

  }
else{

  context.moveTo(clickX[i]
-1, clickY[i]);

  }

  context.lineTo(clickX[i], clickY[i]);

  context.closePath();

  context.strokeStyle
= clickColor[i];

  context.stroke();

  }

  }

 

    我們再設置畫筆每次繪畫筆觸範圍的大小,同樣,有四種選擇,分別為小,中,大和很大,並用clickSize數組記錄用戶的選擇,默認的筆觸範圍大小用curSize進行記錄。並且也要更新redraw方法,更新後的addClick,redraw代碼如下:

 

function addClick(x, y, dragging)

  {

  clickX.push(x);

  clickY.push(y);

  clickDrag.push(dragging);

  clickColor.push(curColor);

  clickSize.push(curSize);

  }

  var radius;

  var i
= 0;

  
for(; i < clickX.length; i++)

  {

  
if(clickSize[i] == "small"){

  radius
= 2;

  }
else if(clickSize[i] == "normal"){

  radius
= 5;

  }
else if(clickSize[i] == "large"){

  radius
= 10;

  }
else if(clickSize[i] == "huge"){

  radius
= 20;

  }
else{

  alert(
"Error: Radius is zero for click " + i);

  radius
= 0;

  }

  
function redraw(){

  。。。。。。。。

  context.strokeStyle
= clickColor[i];

  context.lineWidth
= radius;

  context.stroke();

  }

  }

 

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

 

function addClick(x, y, dragging)

  {

  clickX.push(x);

  clickY.push(y);

  clickDrag.push(dragging);

  
if(curTool == "eraser"){

  clickColor.push(
"white");

  }
else{

  clickColor.push(curColor);

  }

  clickColor.push(curColor);

  clickSize.push(curSize);

  }

 

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

function redraw(){

  context.lineJoin
= "round";

  
for(var i=0; i < clickX.length; i++)

  {

  context.beginPath();

  
if(clickDrag[i] && i){

  context.moveTo(clickX[i
-1], clickY[i-1]);

  }
else{

  context.moveTo(clickX[i]
-1, clickY[i]);

  }

  context.lineTo(clickX[i], clickY[i]);

  context.closePath();

  context.strokeStyle
= clickColor[i];

  context.lineWidth
= radius;

  context.stroke();

  }

  
if(curTool == "crayon") {

  context.globalAlpha
= 0.4;

  context.drawImage(crayonTextureImage,
0, 0, canvasWidth, canvasHeight);

  }

  context.globalAlpha
= 1;

  }

 

  這裡針對當用戶選擇「crazyon」蠟筆效果時,對繪畫的效果進行了透明度的處理。

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

 

 var outlineImage = new Image();

 

  然後在prepareCanvas()方法中加載事先準備好的圖片:

  

function prepareCanvas(){

  ...

  outlineImage.src
= "images/watermelon-duck-outline.png";

  }

 

  最後在redraw的繪畫方法中,要使用canvas畫布的drawImage方法進行繪畫,代碼為:

  

function redraw(){

  ...

  context.drawImage(outlineImage, drawingAreaX, drawingAreaY, drawingAreaWidth, drawingAreaHeight);

  }

 

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

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

  我們還要把繪圖的區域限制在一個矩形框裡,這要用到畫布的save和clip方法。其中save用來保存Canvas的狀態,而clip方法則是指定一個區域進行剪裁,規定了繪畫的區域,代碼如下:

 

 function redraw()

  {

  ...

  context.save();

  context.beginPath();

  context.rect(drawingAreaX, drawingAreaY, drawingAreaWidth, drawingAreaHeight);

  context.clip();
//剪裁出指定的繪畫區域

  var radius;

  var i
= 0;

  
for(; i < clickX.length; i++)

  {

  ...

  }

  context.restore();
//使用restore方法,恢復每次保存的canvas狀態

  ...

  }

 

   總結

  本文中只是對如何使用HTML5和javascript繪製小繪圖應用進行了思路和基本技術點的分析,其中著重介紹了畫布canvas的各種使用方法,完整的代碼請到這裡下載

  (http://www.williammalone.com/articles/create-html5-canvas-javascript-drawing-app/downloads/html5-canvas-drawing-app.zip),代碼中完成實現了相關的各種功能,並加入了一些邏輯判斷等操作,由於篇幅關係,不再在文中詳細描述。

相關焦點

  • 使用HTML5畫布實現的超棒javascript動畫儀錶板:gauge.js
    使用HTML5畫布實現的超棒javascript動畫儀錶板:gauge.js 在線演示今天我們分享來自guage.js的超棒動畫儀錶板實現,這個類庫使用
  • 分享10款超酷的Javascript繪畫和畫布類庫
    javascript開發和設計人員通過使用各種JS繪圖和畫布類庫來添加圖形或者繪製功能到web應用和網站中。1. oCanvas一個javascript的類庫幫助大家更加容易的使用HTML5的畫布來開發。這個類庫使用對象而非像素來開發。使用簡單並且明了。2. Drawing lines in Mozilla based browsers and the Internet ExplorerHTML本身不能繪製直線。
  • Python使用tkinter製作一個簡易的繪圖程序一(Python GUI編程)
    Python有很多GUI庫,tkinter作為一款入門級的圖形庫,基本具備了圖形界面的大部分元素,如果結合ttk、Pmw庫使用的話,其功能就得到了擴展,使用這些庫基本能構建簡單的圖形界面應用。但是,tkinter唯一美中不足的是它的性能問題,它不具備如QT等一些第三方庫的性能,在同一應用程式中設計了關於獲取系統性能的一些功能,tkinter就顯得非常慢(參加Python高手養成關於系統性能查看器製作的內容),雖然其性能可以通過不同的方法得到提升,但這是後話,我們後續章節進行討論。今天結合一個實例,帶大家一起見識一下tkinter的基本使用方法。
  • C語言編程:使用EasyX庫,讓你的控制臺程序支持繪圖功能
    對於C/C++語言初學者來講,當寫控制臺程序時是不是已經看膩了一成不變的命令行式結果輸出?你是不是想在你的控制臺程序中添加豐富多彩的繪圖顯示功能呢?那麼,藉助於EasyX庫,我們可以讓控制臺程序通過簡單的編程,就可以達到我們的這個目的。
  • 淺談如何實現HTML5的離線存儲
    2.NETWORK:表示在它下面列出來的資源只有在在線的情況下才能訪問,他們不會被離線存儲,所以在離線情況下無法使用這些資源。尚學堂百戰程式設計師陳老師指出,如果在CACHE和NETWORK中有一個相同的資源,那麼這個資源還是會被離線存儲,也就是說CACHE的優先級更高。
  • 怎麼理解Html5?Html5和html4相比有哪些優勢?怎麼學好html5?
    Html5(超文本標記語言)簡單理解是HTML(超文本標記語言)的第五次重大修改的版本,由WHATWG(Web Hypertext Application Technology Working Group中文全稱Web超文本應用技術工作組)和一些公司在html4.0基礎研究下一代html版本,2004年正式提出html5於2007正式被w3c接納
  • 前端HTML5面試官和應試者一問一答
    6.Canvas和SVG的區別是什麼SVG是可縮放矢量圖形,它是基於文本的圖形語言,使用文本,線條,點等來繪製圖像。a. 一旦Canvas繪製完成將不能訪問像素或操作它,任何使用SVG繪製的形狀都能被記憶和操作,可以被瀏覽器再次顯示。b.
  • HTML5常用的標籤
    目錄:HTML5新結構標籤HTML5新其他標籤HTML5新input類型HTML5新屬性HTML5高級應用html4和html5 <img src=「a.jpg」> <img src=「b.jpg」> <img src=「c.jpg」></figure>新元素標籤追加樣式:說明:因為很多瀏覽器還未支持html5
  • [分享]Rhino使JavaScript應用程式更靈動
    除了瀏覽器之外,JavaScript也可以應用在其他場合,比如伺服器端程序中。Rhino是使用Java語言實現的JavaScript 引擎,本文將介紹如何利用Rhino來使您的應用程式提供JavaScript腳本的支持。
  • 最強大、最牛逼的javascript視頻免費發布啦
    函數(【六】執行環境和作用域鏈概念)16_尚學堂科技_javascript視頻教程_白賀翔_函數(【七】垃圾收集和塊級作用域的概念)17_尚學堂科技_javascript視頻教程_白賀翔_函數(【八】閉包)18_尚學堂科技_javascript視頻教程_白賀翔_面向對象程序設計(對象【一】類的創建於實例對象)19_尚學堂科技_javascript
  • Web前端開發基礎教程:認識h5和html5,以及前端和全棧之間的關係
    什麼是html5?html5是html網頁標準的5.0版本,5.0版本相比4.0的版本,新增了很多的技術內容。這次的變化是比較大的,甚至是革命性的,他的誕生帶動了很多技術領域的發展,尤其是在我們的移動端設備上面,因此我們今天談論的htm5這個詞,它已經產生了一些變化,它代表的已經不再是簡單的,html的網頁設計標準,而是圍繞著html這個東西,以及它周邊的一系列網頁相關技術的總稱。這其中既包含了html加CSS的網頁製作,也包含了JavaScript。
  • Python使用tkinter製作一個簡易的繪圖程序二(Python GUI編程)
    上節課,我們使用Python中tkinter庫製作了一個簡易的畫圖板程序,基本實現了圓、橢圓、矩形、直線等圖形的繪製功能。但是,效果還不是很令人滿意,我們的多邊形還不能正確繪製。這一節我們對多邊形繪製功能進行完善。
  • 如何正確地在XHTML文檔中使用JavaScript和CSS
    正確的XHTML格式是一個XML程序並且在書寫的時候需要按照以下的嚴格規則:1.字符<和&不允許出現在XHTML文檔內容中,除非它們被包含在CDATA標籤中(<![CDATA[...]]>)2.注釋標籤(<!--...-->)內容中不能包含兩個連續的橫槓(--)3.包含在注釋標籤(<!--...
  • 50個實用的JavaScript工具
    安全工具  AttackAPI  AttackAPI是一個基於Web的攻擊構造庫,它可以結合PHP、JavaScript及其他客戶端和伺服器端技術進行使用。JavaScriptMVC應用了模型-視圖-控制器架構模式,把業務邏輯和表示分離,使得代碼更加模塊化。  qooxdoo  是一個功能強大基於JavaScript GUI工包,它讓你可以用JavaScript來開發類似於VB/Delphi風格的具有Ajax功能的web2.0應用程式。
  • 設計必備錦囊05 | 最佳的2D和3D CAD繪圖軟體
    QCAD是另一款免費的開源2D繪圖軟體。用於二維計算機輔助繪圖(CAD)(2D)。使用QCAD,您可以創建技術圖紙,例如建築物,內部,機械部件或原理圖和圖表。QCAD適用於Windows,macOS和Linux。
  • 分享10款最棒的免費HTML5視頻播放器
    一個免費的開源的使用javascript開發的HTML5播放器。解決了瀏覽器兼容性問題並且添加了很多非標準的強大功能。videoJS是一個HTML5視頻播放器,使用js和css開發,會自動使用一個fallback調用flash來播放視頻一旦瀏覽器不支持HTML5視頻
  • 使用React和HTML5表單驗證API處理表單
    在本教程中,我們將看看如何使用React和HTML5的現代組合來處理表單提交和驗證。當我們在Web應用程式中討論用戶輸入時,我們經常首先想到HTML表單。Web表單從HTML的第一個版本開始就已經可用。顯然,該功能已於1991年推出,並在1995年以RFC 1866標準進行了標準化。
  • 顛覆設計方式 Adobe專業iPad繪圖觸控筆
    Adobe Ink 手寫筆是雲筆,而slide是iPad上用的數字標尺,通過兩款新的應用程式可以使用它們。一款叫Adobe Line,是直線繪圖應用程式,另一款叫Adobe Sketch,是美術應用程式。這對於塗鴉、即時設計和現場編輯等等,都是一個理想的組合。
  • JavaScript是什麼
    面向過程的思想----C語言【指針】面向對象的思想就是只需要知道開始和結束位置就可以,至於中間是如何完成的不需要關注。開始和結束位置就是對象。面向對象的思想—java、 C#腳本—寫好的程序不需要中間轉換,就能立即在運行環境中運行。javaScript,SQL為html網頁提供動態效果【特效】。