今天講的例子比較多,可能篇幅長一些。從實用性看,前三個例子需要完全理解。后面的可以有興趣再回頭看,因為圓弧和曲線平時的設計當中不經常用到。
閑話少說,先來第一個例子:最基本的矩形
案例中涉及的函數
- fillRect(x, y, width, height):在(x, y)點上以width和height的長高來畫全填充矩形。
- strokeRect(x, y, width, height):在(x, y)點上以width和height的長高來給矩形描邊(只有邊框,里面為空)。
- clearRectt(x, y, width, height):在(x, y)點上以width和height的長高清空內容,使他變為透明)
效果圖:
直接貼上所有的代碼,具體的編號請根據方法名稱的最后一個字母索引值進行辨別。

/** * @author Administrator */ window.addEventListener("load", eventWindowLoaded, false); function eventWindowLoaded() { canvasApp(); } function canvasSupport() { // return !document.createElement('testcanvas').getContext; } function canvasApp() { var theCanvas = document.getElementById("canvas"); var context = theCanvas.getContext("2d"); //canvas中有很多不同的context,這里我們僅需要2D // if(!theCanvas || !theCanvas.getContext) { // return; // } function drawScreen1() { context.fillStyle = "#000000"; context.strokeStyle = "#ff00ff"; context.lineWidth = 2; context.fillRect(10, 10, 40, 40); context.strokeRect(0, 0, 60, 60); context.clearRect(20, 20, 20, 20); } function drawScreen2() { var ctx = document.getElementById('canvas').getContext('2d'); ctx.fillRect(0, 0, 150, 150); ctx.save(); //保存當前的context狀態 例如當前的context1 ctx.fillStyle = '#3399FF' //新的context對象 當前為context2 ctx.fillRect(15, 15, 120, 120); ctx.save(); //保存當前的context狀態 例如當前的context2 ctx.fillStyle = '#FFF'; //新的context對象 當前為context3 ctx.globalAlpha = 0.5; ctx.fillRect(30, 30, 90, 90); ctx.restore(); //恢復到context2狀態,也就是說ctx.fillSyle恢復到 #3399FF ctx.fillRect(45, 45, 60, 60); ctx.restore(); //再進行恢復 恢復到context1狀態,恢復到最開始的默認狀態 ctx.fillRect(60, 60, 30, 30); } function drawScreen3() { context.strokeStyle = "black"; context.lineWidth = 10; //線的粗細 context.lineJoin = "bevel"; /** * lineCap:線的兩端 * 1. butt:線的兩端是平坦的 * 2. round:線的兩端是半圓形 * 3. square:以線的寬度為長邊,線的寬度的一半為短邊的矩形 */ context.lineCap = "round"; context.beginPath(); context.moveTo(0, 0); context.lineTo(25, 0); context.lineTo(25, 25); /** * fill():實心 * stroke():描邊 */ context.stroke(); context.closePath(); context.beginPath(); context.moveTo(10, 50); context.lineTo(35, 50); context.lineTo(35, 75); context.stroke(); context.closePath(); /** * lineJoin:線的連接處 * 1. miter:在連接處畫出邊緣(例如垂直) * 2. bevel:在連接處畫出斜線 * 3. round:在連接處畫出圓形 */ context.lineJoin = "round"; context.lineCap = "butt"; context.beginPath(); context.moveTo(10, 100); context.lineTo(35, 100); context.lineTo(35, 125); context.stroke(); context.closePath(); } function drawScreen4() { context.beginPath(); context.strokeStyle = "black"; context.lineWidth = 5; /** * context.arc(x, y, radius, startAngle, endAngle, anticlockwise) * 畫圓弧,可以是整個弧,也可以是一部分 * @param: x 圓弧的中心坐標 * @param: y 圓弧的中心坐標 * @param: radius 圓弧的半徑 * @param: startAngle 圓弧的起始角度 * @param: endAngle 圓弧的結束角度 * @param: anticlockwise 是否為《逆》時針方向 * * 其中角度是沿着x軸方向為0或360度,x軸的反向為180度 * y軸的反向為90度,y軸方向為270度 */ context.arc(100, 100, 20, (Math.PI / 180) * 90, (Math.PI / 180) * 180, false); context.stroke(); context.closePath(); } function drawScreen5() { context.beginPath(); context.lineWidth = 5; context.moveTo(0, 0); context.quadraticCurveTo(100, 25, 0, 50); context.moveTo(250, 0); context.bezierCurveTo(0, 125, 300, 175, 150, 300); context.stroke(); context.closePath(); } drawScreen5(); }
drawScreen1()方法當中前面幾行應該都沒啥問題,最后一行因為它清空了(20, 20, 20, 20)的區域,因此中間會顯示白色的區域。
它是網頁的背景顏色,用戶可以調整<body>的背景顏色,進行檢查。
Canvas狀態
當我們使用canvas context進行畫畫的時候,我們可以使用畫畫狀態的一組棧。棧中保存着任何時候的Canvas context的信息(例如畫筆顏色)。
這里將列舉一些棧當中保存的數據。
- 矩陣的變化(旋轉,移動)
- 裁剪的區域
- canvas的一些屬性(例如fillStyle, strokeStyle, textAlign, globalAlpha等等)
但是當前的路徑(path)及在canvas當中操作的bitmap對象不會包含在狀態當中。
狀態的保存及恢復
- context.save();
- context.restore();
筆者找了一個很好的例子,練習context的保存及恢復。
效果圖如下:
如果能完全的理解這個例子,那基本的保存狀態及恢復應該沒什么問題,因代碼旁邊都有注釋就不說明了。
使用Path畫線條
因代碼有注釋,不介紹了。但大家思考一下第一個圖形,為什么上邊的橫線為細的。
圓弧
方法名稱:context.arc(x, y, radius, startAngle, endAngle, anticlockwises)
在這里唯一需要注意的是,開始的角度及,結束的角度。並且第五個參數是《是否為逆時針》,別慣性思維想成true為順時針。
還有一個畫圓弧的方法context.arcTo(),但很多瀏覽器不支持該方法,並且跟context.arc()方法有些重疊,這里不介紹了。
貝塞爾曲線
- context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y):這個有點復雜,有興趣的自行了解。筆者雖然查看文檔研究了一陣子,但實在不知道什么時候能用到。
- context.quadraticCurveTo(cpx, cpy, x, y):就是所謂的雙曲線
這次的到此結束了,有任何問題或建議希望給我留言,謝謝。