摘要:二次以及三次貝塞爾曲線都十分有用,一般用來繪制復雜有規律的圖形。繪制三次貝塞爾曲線,為結束點,為控制點一,為控制點二。下邊的圖能夠很好的描述兩者的關系,二次貝塞爾曲線有一個開始結束點藍色以及一個控制點紅色,而三次貝塞爾曲線使用兩個控制點。
Canvas tutorial 您的瀏覽器不支持canvas
模板看起來會是這樣。如這里所示,它最初是空白的。
一個簡單例子
一開始,讓我們來看個簡單的例子,我們繪制了兩個有趣的長方形,其中的一個有著alpha透明度。我們將在接下來的例子里深入探索一下這是如何工作的。
效果
在我們開始畫圖之前,我們需要了解一下畫布柵格(canvas grid)以及坐標空間。上一頁中的HTML模板中有個寬150px, 高150px的canvas元素。如右圖所示,canvas元素默認被網格所覆蓋。通常來說網格中的一個單元相當于canvas元素中的一像素。柵格的起點為左上角(坐標為(0,0))。所有元素的位置都相對于原點定位。所以圖中藍色方形左上角的坐標為距離左邊(Y軸)x像素,距離上邊(X軸)y像素(坐標為(x,y))。在課程的最后我們會平移原點到不同的坐標上,旋轉網格以及縮放。現在我們還是使用原來的設置。
HTML中的元素canvas只支持一種原生的圖形繪制:矩形。所有其他的圖形的繪制都至少需要生成一條路徑。不過,我們擁有眾多路徑生成的方法讓復雜圖形的繪制成為了可能。
首先,我們回到矩形的繪制中。canvas提供了三種方法繪制矩形:
fillRect(x, y, width, height)
繪制一個填充的矩形
strokeRect(x, y, width, height)
繪制一個矩形的邊框
clearRect(x, y, width, height)
清除指定矩形區域,讓清除部分完全透明,例如一個鏤空的矩形。
上面提供的方法之中每一個都包含了相同的參數。x與y指定了在canvas畫布上所繪制的矩形的左上角(相對于原點)的坐標。width和height設置矩形的尺寸。
下面的draw() 函數是前面中取得的,現在就來使用上面的三個函數。
function draw() { var canvas = document.getElementById("canvas"); if (canvas.getContext) { var ctx = canvas.getContext("2d"); ctx.fillRect(25,25,100,100); ctx.clearRect(45,45,60,60); ctx.strokeRect(50,50,50,50); } }
效果
fillRect()函數繪制了一個邊長為100px的黑色正方形。clearRect()函數從正方形的中心開始擦除了一個6060px的正方形,接著strokeRect()在清除區域內生成一個5050的正方形邊框。
繪制路徑
圖形的基本元素是路徑。路徑是通過不同顏色和寬度的線段或曲線相連形成的不同形狀的點的集合。一個路徑,甚至一個子路徑,都是閉合的。使用路徑繪制圖形需要一些額外的步驟。
首先,你需要創建路徑起始點。
然后你使用畫圖命令去畫出路徑。
之后你把路徑封閉。
一旦路徑生成,你就能通過描邊或填充路徑區域來渲染圖形。
以下是所要用到的函數:
beginPath()
新建一條路徑,生成之后,圖形繪制命令被指向到路徑上生成路徑。
closePath()
閉合路徑之后圖形繪制命令又重新指向到上下文中。
stroke()
通過線條來繪制圖形輪廓。
fill()
通過填充路徑的內容區域生成實心的圖形。
生成路徑:
第一步叫做beginPath()。本質上,路徑是由很多子路徑構成,這些子路徑都是在一個列表中,所有的子路徑(線、弧形、等等)構成圖形。而每次這個方法調用之后,列表清空重置,然后我們就可以重新繪制新的圖形。
第二步就是調用函數指定繪制路徑,本文稍后我們就能看到了。
第三,就是閉合路徑closePath(),不是必需的。這個方法會通過繪制一條從當前點到開始點的直線來閉合圖形。如果圖形是已經閉合了的,即當前點為開始點,該函數什么也不做。
繪制一個三角形
function draw() { var canvas = document.getElementById("canvas"); if (canvas.getContext){ var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(75,50); ctx.lineTo(100,75); ctx.lineTo(100,25); ctx.fill(); } }
效果
移動筆觸
一個非常有用的函數,而這個函數實際上并不能畫出任何東西,也是上面所描述的路徑列表的一部分,這個函數就是moveTo()。或者你可以想象一下在紙上作業,一支鋼筆或者鉛筆的筆尖從一個點到另一個點的移動過程。
moveTo(x, y)
將筆觸移動到指定的坐標x以及y上。
當canvas初始化或者beginPath()調用后,你通常會使用moveTo()函數設置起點。我們也能夠使用moveTo()繪制一些不連續的路徑。看一下下面的笑臉例子。我將用到moveTo()方法(紅線處)的地方標記了。
你可以嘗試一下,使用下邊的代碼片。只需要將其復制到之前的draw()函數即可。
function draw() { var canvas = document.getElementById("canvas"); if (canvas.getContext){ var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.arc(75,75,50,0,Math.PI*2,true); // 繪制 ctx.moveTo(110,75); ctx.arc(75,75,35,0,Math.PI,false); // 口(順時針) ctx.moveTo(65,65); ctx.arc(60,65,5,0,Math.PI*2,true); // 左眼 ctx.moveTo(95,65); ctx.arc(90,65,5,0,Math.PI*2,true); // 右眼 ctx.stroke(); } }
效果
arc()函數介紹:
由于canvas中所有于角有關的API,都需要以弧度(R)來指定該角的值。三角函數也都采用弧度制。所以需要記好以下公式:
180度=π弧度
1弧度=(π/180)×度
1度=(180/π)×弧度
π=3.14,所以45度等于(3.14/180)×45度得0.7853弧度
如果你想看到連續的線,你可以移除調用的moveTo()。
線
繪制直線,需要用到的方法lineTo()。
lineTo(x, y)
繪制一條從當前位置到指定x以及y位置的直線。
該方法有兩個參數:x以及y ,代表坐標系中直線結束的點。開始點和之前的繪制路徑有關,之前路徑的結束點就是接下來的開始點,等等。。。開始點也可以通過moveTo()函數改變。
下面的例子繪制兩個三角形,一個是填充的,另一個是描邊的。
function draw() { var canvas = document.getElementById("canvas"); if (canvas.getContext){ var ctx = canvas.getContext("2d"); // 填充三角形 ctx.beginPath(); ctx.moveTo(25,25); ctx.lineTo(105,25); ctx.lineTo(25,105); ctx.fill(); // 描邊三角形 ctx.beginPath(); ctx.moveTo(125,125); ctx.lineTo(125,45); ctx.lineTo(45,125); ctx.closePath(); ctx.stroke(); } }
這里從調用beginPath()函數準備繪制一個新的形狀路徑開始。然后使用moveTo()函數移動到目標位置上。然后下面,兩條線段繪制后構成三角形的兩條邊。
你會注意到填充與描邊三角形步驟有所不同。正如上面所提到的,因為路徑使用填充(filled)時,路徑自動閉合,使用描邊(stroked)則不會閉合路徑。如果沒有添加閉合路徑closePath()到描述三角形函數中,則只繪制了兩條線段,并不是一個完整的三角形。
圓弧
繪制圓弧或者圓,我們使用arc()方法。當然可以使用arcTo(),不過這個的現實并不是那么的可靠,所以我們這里不作介紹。
arc(x, y, radius, startAngle, endAngle, anticlockwise)
畫一個以(x,y)為圓心的以radius為半徑的圓弧(圓),從startAngle開始到endAngle結束,按照anticlockwise給定的方向(默認為順時針)來生成。
arcTo(x1, y1, x2, y2, radius)
根據給定的控制點和半徑畫一段圓弧,再以直線連接兩個控制點。
該方法有五個參數:x,y為繪制圓弧所在圓上的圓心坐標。radius為半徑。startAngle以及endAngle參數用弧度定義了開始以及結束的弧度。這些都是以x軸為基準。參數anticlockwise 為一個布爾值。為true時,是逆時針方向,否則順時針方向。
下面的例子比上面的要復雜一下,下面繪制了12個不同的角度以及填充的圓弧。
下面兩個for循環,生成圓弧的行列(x,y)坐標。每一段圓弧的開始都調用beginPath()。代碼中,每個圓弧的參數都是可變的,實際生活中,我們并不需要這樣做。
x,y坐標是可變的。半徑(radius)和開始角度(startAngle)都是固定的。結束角度(endAngle)在第一列開始時是180度(半圓)然后每列增加90度。最后一列形成一個完整的圓。
clockwise 語句作用于第一、三行是順時針的圓弧,anticlockwise作用于二、四行為逆時針圓弧。if 語句讓一、二行描邊圓弧,下面兩行填充路徑。
function draw() { var canvas = document.getElementById("canvas"); if (canvas.getContext){ var ctx = canvas.getContext("2d"); for(var i=0;i<4;i++){ for(var j=0;j<3;j++){ ctx.beginPath(); var x = 25+j*50; // x 坐標值 var y = 25+i*50; // y 坐標值 var radius = 20; // 圓弧半徑 var startAngle = 0; // 開始點 var endAngle = Math.PI+(Math.PI*j)/2; // 結束點 var anticlockwise = i%2==0 ? false : true; // 順時針或逆時針 ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise); if (i>1){ ctx.fill(); } else { ctx.stroke(); } } } } }
效果
貝塞爾(bezier)以及二次貝塞爾
下一個十分有用的路徑類型就是 貝塞爾曲線。二次以及三次貝塞爾曲線都十分有用,一般用來繪制復雜有規律的圖形。
quadraticCurveTo(cp1x, cp1y, x, y)
繪制二次貝塞爾曲線,x,y為結束點,cp1x,cp1y為控制點。
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
繪制三次貝塞爾曲線,x,y為結束點,cp1x,cp1y為控制點一,cp2x,cp2y為控制點二。
下邊的圖能夠很好的描述兩者的關系,二次貝塞爾曲線有一個開始、結束點(藍色)以及一個控制點(紅色),而三次貝塞爾曲線使用兩個控制點。
參數x、y在這兩個方法中都是結束點坐標。cp1x,cp1y為坐標中的第一個控制點,cp2x,cp2y為坐標中的第二個控制點。
使用二次以及三次貝塞爾曲線是有一定的難度的,因為不同于像Adobe Illustrators這樣的矢量軟件,我們所繪制的曲線沒有直接的視覺反饋給我們。這讓繪制復雜的圖形十分的困難。在下面的例子中,我們會繪制一些簡單有規律的圖形,如果你有時間,以及更多的耐心很多復雜的圖形你都可以繪制出來。
可以看我自己寫的一個實際項目例子,在我的文章里有。
今天就先寫到這了。后面再慢慢給大家寫,我也是剛剛學這個。不足之處多諒解。關注我哦^_^!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/91645.html
摘要:二次以及三次貝塞爾曲線都十分有用,一般用來繪制復雜有規律的圖形。繪制三次貝塞爾曲線,為結束點,為控制點一,為控制點二。下邊的圖能夠很好的描述兩者的關系,二次貝塞爾曲線有一個開始結束點藍色以及一個控制點紅色,而三次貝塞爾曲線使用兩個控制點。 元素 看起來和 元素很相像,唯一的不同就是它并沒有 src 和 alt 屬性。實際上, 標簽只有兩個屬性—— width和height。當沒有...
摘要:二次以及三次貝塞爾曲線都十分有用,一般用來繪制復雜有規律的圖形。繪制三次貝塞爾曲線,為結束點,為控制點一,為控制點二。下邊的圖能夠很好的描述兩者的關系,二次貝塞爾曲線有一個開始結束點藍色以及一個控制點紅色,而三次貝塞爾曲線使用兩個控制點。 元素 看起來和 元素很相像,唯一的不同就是它并沒有 src 和 alt 屬性。實際上, 標簽只有兩個屬性—— width和height。當沒有...
摘要:以上代碼功能很簡單,就是把定義為一個模塊,在中引用,最終兩文件中要添加的內容都顯示在中。我們的任務完成了,成功生成,合并,引入了,被執行了。安裝,處理文件。 前言: 本套教程是零基礎學打包工具webpack; 后面會結合gulp+webpack搞定所有你得需求; 閑談: 百度搜了一下,雖然教程多,但是雜亂無章,實用的沒多少,都是匆匆了事,所以我就自己學了兩天,現在從最底層教大家完成we...
摘要:以上代碼功能很簡單,就是把定義為一個模塊,在中引用,最終兩文件中要添加的內容都顯示在中。我們的任務完成了,成功生成,合并,引入了,被執行了。安裝,處理文件。 前言: 本套教程是零基礎學打包工具webpack; 后面會結合gulp+webpack搞定所有你得需求; 閑談: 百度搜了一下,雖然教程多,但是雜亂無章,實用的沒多少,都是匆匆了事,所以我就自己學了兩天,現在從最底層教大家完成we...
閱讀 3110·2021-11-24 09:39
閱讀 968·2021-09-07 10:20
閱讀 2389·2021-08-23 09:45
閱讀 2254·2021-08-05 10:00
閱讀 566·2019-08-29 16:36
閱讀 833·2019-08-29 11:12
閱讀 2813·2019-08-26 11:34
閱讀 1839·2019-08-26 10:56