canvas的基礎使用。

来源:http://www.cnblogs.com/hiuman/archive/2016/10/31/6016720.html
-Advertisement-
Play Games

目錄: 創建canvas。 繪製直線、多邊形和七巧板。 繪製弧和圓。 (有些圖過於寬,被擠壓了。可以去相冊【canvas用到的圖。】看原圖。) 創建canvas。 HTML5的新標簽<canvas></canvas> 在使用時會添加id,通過id來獲取canvas元素來進行繪圖操作。 可以添加樣式。 ...


目錄:

創建canvas。

繪製直線、多邊形和七巧板。

繪製弧和圓。

(有些圖過於寬,被擠壓了。可以去相冊【canvas用到的圖。】看原圖。)

 

創建canvas。

HTML5的新標簽<canvas></canvas>

在使用時會添加id,通過id來獲取canvas元素來進行繪圖操作。

<canvas id="canvas"></canvas>

可以添加樣式。在不指定寬高的時候,預設是300px*150px。

<canvas id="canvas" style="border:1px solid #aaa;display:block;margin:50px auto;"></canvas>

指定canvas大小是通過canvas標簽的width屬性和height屬性,而不是通過CSS指定,並且指定時是沒有單位的。

<canvas id="canvas" width="1024" height="768"></canvas>

使用JavaScript來獲取canvas,通過getContext得到繪圖的上下文環境。

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');  //使用context進行繪製

除了在標簽內指定canvas的大小,還可以在JS中指定。

canvas.width=1024;
canvas.height=768;

當瀏覽器不支持canvas時,可以使用以下兩種方法。

<canvas>當前瀏覽器不支持canvas,請更換瀏覽器後再試。</canvas>

(當瀏覽器支持canvas時,canvas標簽的內容會被瀏覽器忽略)

或者

var canvas = document.getElementById("canvas");
if(canvas.getContext("2d")){
    var context = canvas.getContext("2d");
}else{
    alert("當前瀏覽器不支持canvas,請更換瀏覽器後再試。")
}

使用到的內容:

canvas.width

canvas.height

canvas.getContext()

 

繪製直線、多邊形和七巧板。

context.moveTo(100,100);
context.lineTo(200,200);
context.stroke();

這三行代碼就可以實現繪製一條直線。

moveTo,相當於把筆觸放在坐標為100,100的位置。lineTo,就是從100,100畫到200,200的位置。此時直線還沒繪製出來,使用了context.stroke()方法才繪製出來。(這裡的坐標是相對於<canvas>來說的。<canvas>的左上角為坐標原點。)

moveTo和lineTo都是繪製狀態設置,而stroke()則是繪製。

繪製一條直線。

除了moveTo,lineTo這兩個狀態設置。還有:

lineWidth。線條的寬度。

strokeStyle。線條樣式(顏色),字元串的格式。

context.lineWidth = 5;
context.strokeStyle = 'blue';

先寫狀態再寫繪製。

直線的粗細,顏色設置。

繪製多條線段。只需要接上lineTo()就可以。

context.lineTo(100,200);

多個線段。

當最後的lineTo()的坐標和moveTo()的坐標一致,就可以實現首尾銜接的多邊形。

context.lineTo(100,100);

首尾銜接的多邊形。

矩形,梯形,五星形等的畫法同理。

stroke()主要是繪製線條。

 

對多邊形進行著色,狀態:fillStyle,繪製方法:fill()

context.fillStyle = 'rgb(30,60,90)';
context.fill();

對多邊形著色。

繪製路徑並且著色:

var canvas = document.getElementById('canvas');
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext('2d');
context.moveTo(
100,100); context.lineTo(200,200); context.lineTo(100,200); context.lineTo(100,100); context.fillStyle = 'rgb(30,60,90)'; context.fill(); context.lineWidth = 5; context.strokeStyle = 'blue'; context.stroke();

多邊形的繪製並著色。

當畫第二個線段/多邊形的時候,只需要重新調用moveTo()。

context.moveTo(200,100);
context.lineTo(250,250);
context.strokeStyle = 'red';
context.stroke();

繪製第二個線段。

問題:為什麼兩條線條顏色,粗細一樣?

答案:canvas的繪製是基於狀態的,在調用第二個線段的stroke()方法時,第一個線段的狀態依然起作用,(既繪製了三角形又繪製了第二條線段),而第二個線段的strokeStyle覆蓋了第一個線段的strokeStyle。

 

把兩個線段的狀態分開,方法:beginPath(),在定義路徑前調用(moveTo()之前)。相應的,在路徑定義完後,使用closePath()。

分開兩個線段的狀態。

使用到的內容:

context.moveTo(x1,y1)

context.lineTo(x2,y2)

 

context.beginPath()

context.closePath()

 

context.lineWidth

context.strokeStyle

context.fillStyle

 

context.stroke()

context.fill()

 

繪製七巧板。

<canvas id="canvas" style="border:1px solid #aaa;display: block;margin: 50px auto;">
    當前瀏覽器不支持canvas,請更換瀏覽器後再試。
</canvas>
var tangram = [
        {p:[{x:0,y:0},{x:800,y:0},{x:400,y:400}],color:'red'},
    {p:[{x:0,y:0},{x:400,y:400},{x:0,y:800}],color:'orange'},
    {p:[{x:800,y:0},{x:800,y:400},{x:600,y:600},{x:600,y:200}],color:'yellow'},
    {p:[{x:600,y:200},{x:600,y:600},{x:400,y:400}],color:'green'},
    {p:[{x:400,y:400},{x:600,y:600},{x:400,y:800},{x:200,y:600}],color:'lightblue'},
    {p:[{x:200,y:600},{x:400,y:800},{x:0,y:800}],color:'blue'},
    {p:[{x:800,y:400},{x:800,y:800},{x:400,y:800}],color:'purple'}
]
window.onload = function(){
    var canvas = document.getElementById('canvas');
    canvas.width = 800;
    canvas.height = 800;
    var context = canvas.getContext('2d');

    for(var i=0;i<tangram.length;i++){
        draw(tangram[i],context);
    }
}

function draw( piece , ctx ){
    ctx.beginPath();
    ctx.moveTo(piece.p[0].x,piece.p[0].y);
    for(var i=1;i<piece.p.length;i++){
        ctx.lineTo(piece.p[i].x,piece.p[i].y);
    }
    ctx.closePath();

    ctx.fillStyle = piece.color;
    ctx.fill();

    ctx.strokeStyle = 'pink';
    ctx.lineWidth = 3;
    ctx.stroke();
}

繪製七巧板。

 

繪製弧和圓。

context.arc(x,y,radius,startingAngle,endingAngle,anticlockwise=false)

繪製弧線。參數分別是,圓心的坐標x,y,圓的半徑radius,開始的弧度值,結束的弧度值,順時針轉動/逆時針轉動(false代表順時針轉動,true代表逆時針轉動)。

弧度/角度。

無論順時針/逆時針,弧度是不變的。

以下是順時針的角度。

弧度。

畫3/4個圓。arc()也是狀態設置。最後一個參數不填時,預設false,即順時針。

context.lineWidth = 5;
context.strokeStyle= 'blue';
context.arc(150,150,100,0,1.5*Math.PI);  //圓心(150,150),半徑100,從0弧度到1.5PI弧度。
context.stroke();

繪製3/4個圓。

將最後一個參數設置為true時。

context.arc(150,150,100,0,1.5*Math.PI,true);

繪製3/4個圓。逆時針。

 

繪製多段弧。

context.lineWidth = 5;
context.strokeStyle= 'blue';
for(var i=0;i<10;i++){
    context.beginPath();
    context.arc(50+i*100,60,40,0,2*Math.PI*(i+1)/10);
    context.closePath();
    context.stroke();
}

繪製多個弧。

問題:為什麼弧的開始開始和結尾處被一條直線連接起來了?

答案:這是closePath()的另一個作用。噹噹前繪製的路徑不是封閉路徑時,使用了closePath()的話,就會自動將這段不封閉的路徑在首尾處使用一條線連接。

 

以上代碼不使用closePath()就不會首尾相連:

繪製多個弧。2

使用closePath(),並且逆時針方向繪製:

繪製多個弧。3

不使用closePath(),並且逆時針方向繪製:

繪製多個弧。4

填充處理。strokeStyle改為fillStyle。stroke()改為fill()。並且closePath()的效果:

繪製多個弧。5

去掉closePath():

繪製多個弧。6

註意:closePath()對於fill()來說是不起作用的。當調用fill()時,無論你是否調用closePath(),會自動將不封閉的內容首尾相連再填充。

使用到的內容:

context.arc(x,y,radius,startingAngle,endingAngle,anticlockwise=false)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 由於html是從上至下載入的,通常我們如果在head部分引入javascript文件,那麼我們都會在javascript的開頭添加window.onload事件,防止在文檔問載入完成時進行DOM操作所出現的錯誤。如果有多個javascript文件,那麼極有可能出現多個window.onload事件, ...
  • 因集團的組織結構比較特別,為了很好的體現層級,又擺放美觀,自己謝了一個簡單的頁面,有需要的可供參考。 ...
  • 之前根據網易前端微專業的課程,寫了博客 水平居中 方案 垂直居中 方案 水平居中和垂直居中 方案 在最後,老師總結了『解決方案』提出的思路 比如說用到的 display : flex display:table display: inline-block display : table-cell v... ...
  • 單擊頁面任何地方關閉隱藏層的一種新的實現方法,有需要得朋友可以參考對比一下,可以自己在此基礎上擴展相關功能。(也可以在框架頁中綁定單擊事件,自己加一下即可。) ...
  • 前言: 上篇博文AngularJs之directive中說了Scope作用域是個大坑,所以拿出來作為重點總結! 什麼是scope AngularJS 中,作用域是一個指嚮應用模型的對象,它是表達式的執行環境。作用域有層次結構,這個層次和相應的 DOM 幾乎是一樣的。作用域能監控表達式和傳遞事件。 在 ...
  • 就web元素排版佈局而言,在此之前,Web設計師需對Document元素完全按照HTML/CSS語言語法來編寫Web頁面,這意味著所有Web設計師都必須遵循許多瀏覽器的非標準差異來編寫頁面,而W3C又遲遲未統一這一標準,長久以來,導致編寫網頁Web設計師需處理不同瀏覽器之間的各種差異,一但排版佈局稍... ...
  • 方案一 水平居中和垂直居中,並且父容器的寬度高度都是未知的,裡面的子容器大小也是不一定的 DEMO 方案二 水平居中和垂直居中 absolute_transform DEMO 方案三 水平居中和垂直居中flex_justify-content_... ...
  • 已測適用於ios,某些安卓手機微信下播放視頻會出現播放器控制項(這個實在是無力吐槽了,因為之前還遇到過微信播放完視頻後竟然無法退出全屏出現廣告的情況,只有播放完後刷新頁面並且要放到框架頁里才能屏蔽微信視頻廣告!),之前用canvans渲染,感覺不夠太完美,又弄成背景切換形式得(用背景切換形式可以完美解 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...