摘要:比如弧線或圓形從到繪制一條以為圓心,為半徑的弧線,其中和用弧度表示,為時,順時針畫弧線,反之,逆時針畫弧線。
最近筆者在學習HTML5的新元素,會分享一些基礎知識以及小例子,最終使用實現一個繪制簡單圖表(條形圖、線圖或者餅圖)的js庫,會更新一到兩篇文章~
下面我們開始吧~
我們首先應該指定標簽即畫布的寬度和高度屬性,并在開始和閉合標簽之間添加后備信息:
取得繪圖上下文
調用canvas的getContext()方法,這個方法接收一個參數,即上下文的名字:
var canvas = document.getElementById("canvas"); if(canvas.getContext) { var context = canvas.getContext("2d") }
上述例子中,我們在調用getContext()方法時,首先檢測其是否存在,這是由于有的瀏覽器遇到HTML規范之外的標簽時,也會創建一個DOM對象,比如我們在Chrome中嘗試以下代碼:
document.getElementById("ppp"); //
因此即使當前瀏覽器不能兼容HTML規范中的canvas元素,同樣會創建DOM對象,可其中卻不存在getContext()。
context上下文對象中包含了繪圖需要的一系列屬性和方法,大家在閱讀本文時,記得區分屬性和方法,改變屬性會影響到后續的繪圖效果,而調用方法往往是一次性的。
2D上下文的坐標默認開始于左上角,原點坐標為(0, 0),使用translate(x, y)可以更改坐標原點。
填充,就是用指定的樣式,比如顏色、漸變或圖像填充指定區域,對應的上下文屬性為fillStyle,默認值為#000000, 比如:
context.fillStyle = "orange";
描邊就是在指定區域邊緣畫指定樣式的線,比如:
context.strokeStyle = "grey";
矩形是唯一一個可以在2D上下文中直接話的形狀,其他的都需要繪制路徑,可以使用3個方法直接繪制矩形。
可以繪制一個由fillStyle指定填充樣式的矩形,比如:
context.translate(100, 100) context.fillStyle = "#99cccc"; context.fillRect(-100, -50, 200, 100); context.fillStyle="#3399cc"; context.fillRect(-60, -30, 120, 60);
可以繪制一個由strokeStyle lineWidth lineCap lineJoin等屬性指定描邊樣式的矩形,比如:
context.strokeStyle = "#99cccc"; context.lineWidth = "50"; context.lineJoin = "bevel"; context.strokeRect(0, 0, 400, 200);
屬性名 | 含義 | 取值 |
---|---|---|
lineCap | 線條末端的形狀 | butt平頭round圓頭square方頭 |
lineWidth | 線條寬度 | 整數 |
lineJoin | 線條相交的方式 | round圓交bevel斜交mitter斜接 |
可以清楚畫布上的指定區域,比如第一個例子中的兩個矩形,我們將中間一小塊清除:
context.translate(100, 100) context.fillStyle = "#99cccc"; context.fillRect(-100, -50, 200, 100); context.fillStyle="#3399cc"; context.clearRect(-60, -30, 120, 60);繪制路徑
使用路徑我們可以繪制出比較復雜的圖形,開始繪制前,首先執行:
context.beginPath();
結束繪制時,執行:
context.closePath();
以下我們列舉了繪制路徑的幾個方法:
lineTo(x, y),從當前游標至(x, y)畫一條直線。
moveTo(x, y) 將游標移動至(x, y),移動過程中不畫線。比如:
context.beginPath(); context.moveTo(10, 10); context.lineTo(50, 40); context.moveTo(50, 50); context.lineTo(100, 90); context.stroke(); context.closePath();
從startAngle到endAngle繪制一條以(x, y)為圓心,radius為半徑的弧線,其中startAngle和endAngle用弧度表示,couterclockwise為false時,順時針畫弧線, 反之,逆時針畫弧線。
var canvas = document.getElementById("canvas"); if(canvas.getContext) { var context = canvas.getContext("2d"); context.beginPath(); context.arc(400, 400, 50, arcUnit()*30, arcUnit()*180, false); context.stroke(); } function arcUnit() { return Math.PI/180; }
arcTo()方法將利用當前坐標、起點(startX,startY)和終點(endX,endY)這三個點所形成的夾角,繪制一段與夾角的兩邊相切并且半徑為radius的圓上的弧線。弧線的起點就是當前坐標所在邊與圓的切點,弧線的終點就是終點(endX,endY)所在邊與圓的切點,并且繪制的弧線是兩個切點之間長度最短的那個圓弧。此外,如果當前端點不是(startX,startY),arcTo()方法還將添加一條當前端點到(startX,startY)的直線線段。
如果大家還記得高中數學的話,我們應該可以猜到,使用這個方法畫弧線大致有三種情況:
** 只有一種半徑可以使弧線兩端正好在起點和終點
** 如果半徑過大,畫不出弧線
** 如果半徑較小,必定會有一條當前端點到起點的直線
我們舉三個例子:
首先定義一些通用的
var context = canvas.getContext("2d"); var currentPoint = { x: 0, y: 0 }; var startPoint = { x: 50, y: 50 }; var endPoint = { x: 100, y: 0 };
然后繪制參考線
context.moveTo(currentPoint.x, currentPoint.y); context.lineTo(startPoint.x, startPoint.y); context.lineTo(endPoint.x, endPoint.y); context.strokeStyle = "red"; context.stroke();
畫第一條弧線
context.moveTo(currentPoint.x, currentPoint.y); context.arcTo(startPoint.x, startPoint.y, endPoint.x, endPoint.y, 80); context.strokeStyle = "grey"; context.stroke();
context.arcTo(startPoint.x, startPoint.y, endPoint.x, endPoint.y, 120);
context.arcTo(startPoint.x, startPoint.y, endPoint.x, endPoint.y, 40);
quadraticCurveTo(cpX, cpY, x, y)
上述方法可以畫一條從當前位置到(x, y), 以(cpX, cpY)為控制點的貝塞爾曲線
bezierCurveTo(cpX1, cpY1, cpX2, cpY2, x, y)
上述方法可以畫一條從當前位置到(x, y), 以(cpX1, cpY1)和(cpX2, cpY2)為控制點的貝塞爾曲線。
二次貝塞爾與三次貝塞爾的繪制涉及到比較復雜的數學運算,筆者在此就忽略啦...
當然,大部分前端人士可能都跟筆者一樣,只希望能畫出一條優美的曲線,并不關心實現細節,那么一般認為什么樣的曲線才算是優美的曲線呢:
對稱的曲線
有一個適度的弧度
根據以上規則,我們寫一個工具方法:
function drawCurvePath( ctx, start, end, curveness ) { var cp = [ ( start.x + end.x ) / 2 - ( start.y - end.y ) * curveness, ( start.y + end.y ) / 2 - ( end.x - start.x ) * curveness ]; ctx.moveTo( start.x, start.y ); ctx.quadraticCurveTo( cp[ 0 ], cp[ 1 ], end.x, end.y ); ctx.stroke(); }
以上參考自用canvas繪制一個曲線動畫——深入理解貝塞爾曲線,大家可以前往了解更深入的貝塞爾曲線畫法。
使用rect(x, y, width, height)可以繪制一個左上角坐標為(x, y),寬width,高height的矩形路徑。
context.rect(300, 300, 100, 200); context.stroke();繪制文本
在繪制本文之前,如果有必要,我們首先應該指定context的幾個屬性, 比如:
context.font = "bold 14px Arial"; // 格式同css中指定字體樣式 context.textAlign = "center"; // start end center left right context.textBaseline = "middle"; // top hanging middle alphabetic ideographic bottom
fillText(text, x, y, maxWidth)使用fillStyle屬性顯示文本,strokeText(text, x, y, maxWidth)使用strokeStyle屬性為文本描邊。
使用measureText(text)方法可以獲得文本的寬度。如果我們并不清楚指定的寬度夠不夠顯示當前字體設置下的一段文字,可以使用如下方法:
var fontSize = 50; var maxWidth = 100; context.font = "bold " + fontSize+"px Arial"; var text = "Hello World!"; while(context.measureText(text).width > maxWidth) { fontSize--; context.font = "bold " + fontSize+"px Arial"; } context.fillText(text, 50, 50, maxWidth);變換
rotate(angle)
context.rotate(Math.PI/4) context.fillText(text, 50, 50, maxWidth);
scale(scaleX, scaleY)
context.scale(1.2, 1.2); context.fillText(text, 50, 50, maxWidth); context.scale(0.5, 0.5); context.fillText(text, 50, 50, maxWidth);
translate(x, y)
假如我們要繪制一個對稱圖形,移動坐標原點將會大大簡化對坐標的計算。
使用transform(scaleX,skewX,skewY,scaleY,transX,transY)可以進行矩陣變換,其實以上講的三個方法本質上都在調用矩陣變換,從參數名中可以看出,它們分別表示X軸方向的縮放,Y軸方向的縮放,X軸方向的斜切,Y軸方向的斜切,X軸方向的偏移量,Y軸方向的偏移量。默認值分別為1 0 0 1 0 0。
我們現在使用transform()重新定義一遍之前的三個方法:
rotate
function rotate (ctx, degree) { var unit = Math.PI/180; ctx.transform(Math.cos(degree*unit),Math.sin(degree*unit),-Math.sin(degree*unit),Math.cos(degree*unit),0,0) }
scale
function scale (ctx, scale) { ctx.transform(scale.x, 0, 0, scale.y, 0, 0); }
translate
function translate (ctx, translate) { ctx.transform(1, 0, 0, 1, translate.x, translate.y); }
我們現在繪制一段文本,先平移(50, 50),然后縮放2倍,最后旋轉30度。
context.fillText(text, 50, 50, maxWidth); translate(context, {x: 50, y: 50}); scale(context, {x: 2, y: 2}); rotate(context, 30); context.fillText(text, 50, 50, maxWidth);
每次執行transform()都是基于上一次的結果,并不是初始狀態,很多時候我們想執行的是基于初始狀態旋轉、平移或縮放,而非上一次的狀態,此時我們可以使用setTransfrom(scaleX,skewX,skewY,scaleY,transX,transY),此方法首先會重置變換矩陣,然后執行transform()。
更加詳細的內容可以參考html5 Canvas畫圖教程26:用transform來實現位移,縮放,旋轉等
使用drawImage(image, x1, y1, width1, height1, x2, y2, width2, height2)可以將圖像的指定部分按照指定的大小繪制到畫布指定的位置上。
參數 | 含義 |
---|---|
image | 要繪制的圖像,可以是HTMLImageElement,也可以是canvas |
x1 | 源圖像的x坐標 |
y1 | 源圖像的y坐標 |
width1 | 源圖像的寬度 |
height1 | 源圖像的高度 |
x2 | 畫布的x坐標 |
y2 | 畫布的y坐標 |
width2 | 圖像在畫布上顯示的寬度 |
height2 | 圖像在畫布上顯示的高度 |
如果要給形狀或路徑加上陰影,我們要在繪制前設置context對象的以下屬性:
屬性 | 含義 |
---|---|
shadowColor | 陰影顏色 |
shadowOffsetX | x軸偏移量 |
shadowOffsetY | y軸偏移量 |
shadowBlur | 模糊的像素數 |
context.shadowColor = "grey"; context.shadowOffsetX = "20"; context.shadowBlur = "5"; context.fillText(text, 50, 50, maxWidth);漸變
使用createLinearGradient(startX, startY, endX, endY)來創建線性漸變,這個方法確認了漸變的起始和方向,然后我們通過addColorStop(position, color)來添加漸變的顏色,position是0到1的數字。一下筆者畫一個超級喜歡的條紋漸變:
var grad = context.createLinearGradient(50, 50, 200, 200) grad.addColorStop(0, "grey"); grad.addColorStop(0.3, "grey"); grad.addColorStop(0.3, "red"); grad.addColorStop(0.5, "red"); grad.addColorStop(0.5, "orange"); grad.addColorStop(0.7, "orange"); context.fillStyle = grad; context.fillRect(50, 50, 150, 150);
使用createRadialGradient(centerX1, centerY1, radius1, centerX2, centerY2, radius2)創建徑向漸變。
圖像重復使用createPattern(image, repeatType)可以繪制重復的圖像,用來填充或描邊,第一個參數是要重復的HTMLImageElement或canvas或video,第二個參數表示如何重復該圖像,可取repeat repeat-x repeat-y no-repeat
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/52304.html
摘要:是新加的標簽,主要有和,的應用是動畫和圖像,的應用是游戲渲染。 HTML5 Canvas canvas是html5新加的標簽,主要有2D和3D,2D的應用是動畫和圖像,3D的應用是游戲渲染。 1. 2D基礎 1.1繪制線 canvas window.onload = function(){ ...
摘要:游戲開發實戰主要講解使用來開發和設計各類常見游戲的思路和技巧,在介紹相關特性的同時,還通過游戲開發實例深入剖析了其內在原理,讓讀者不僅知其然,而且知其所以然。HTML5 Canvas游戲開發實戰主要講解使用HTML5 Canvas來開發和設計各類常見游戲的思路和技巧,在介紹HTML5 Canvas相關特性的同時,還通過游戲開發實例深入剖析了其內在原理,讓讀者不僅知其然,而且知其所以然。在本書...
摘要:前端知識點總結新特性新的語義標簽增強型表單音頻和視頻繪圖繪圖地理定位拖動增強型表單新新的表單元素新特性數據列表本身不可見為提供輸入建議列表新特性進度條左右晃動進度條具有指定進度值進度條新特性刻度尺用于標示一個值所值的范圍不 前端知識點總結——H5 1.html5新特性 (1)新的語義標簽 (2)增強型表單* (3)音頻和視頻 (4)Canvas繪圖 (5)SVG繪圖 (6)地...
閱讀 881·2023-04-25 19:17
閱讀 2179·2021-09-10 11:26
閱讀 1898·2019-08-30 15:54
閱讀 3411·2019-08-30 15:53
閱讀 2681·2019-08-30 11:20
閱讀 3391·2019-08-29 15:12
閱讀 1229·2019-08-29 13:16
閱讀 2384·2019-08-26 12:19