国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > HTML > 正文

Canvas教程(3):Drawing shapes繪制圖形

2024-08-26 00:09:38
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

網(wǎng)格 the grid

before we can start drawing, we need to talk about the canvas grid or coordinate space. the html template on the previous page had a canvas element 150 pixels wide and 150 pixels high. i've drawn this image with the default grid overlayed. normally 1 unit in the grid corresponds to 1 pixel on the canvas. the origin of this grid is positioned in the top left corner (coordinate (0,0)). all elements are placed relative to this origin. so the position of the top left corner of the blue square becomes x pixels from the left and y pixels from the top (coordinate (x,y)). later in this tutorial we'll see how we can translate the origin to a different position, rotate the grid and even scale it. for now we'll stick to the default.

在真正開(kāi)始之前,我們需要先探討 canvas 的網(wǎng)格(grid)或者坐標(biāo)空間(coordinate space)。在前一頁(yè)的html模板里有一個(gè)150像素寬, 150像素高的 canvas 對(duì)象。我在畫面上疊加上默認(rèn)網(wǎng)格,如右圖。通常網(wǎng)格的1個(gè)單元對(duì)應(yīng) canvas 上的1個(gè)像素。網(wǎng)格的原點(diǎn)是定位在左上角(坐標(biāo)(0,0))。畫面里的所有物體的位置都是相對(duì)這個(gè)原點(diǎn)。這樣,左上角的藍(lán)色方塊的位置就是距左邊x像素和距上邊y像素(坐標(biāo)(x, y))。后面的教程中我們將學(xué)會(huì)如何把移動(dòng)原點(diǎn),旋轉(zhuǎn)以及縮放網(wǎng)格。不過(guò)現(xiàn)在我們會(huì)使用默認(rèn)的狀態(tài)。

繪制圖形 drawing shapes

unlike svg, canvas only supports one primitive shape - rectangles. all other shapes must be created by combining one or more paths. luckily, we have a collection of path drawing functions which make it possible to compose very complex shapes.

不像 svg,canvas 只支持一種基本形狀——矩形,所以其它形狀都是有一個(gè)或多個(gè)路徑組合而成。還好,有一組路徑繪制函數(shù)讓我們可以繪制相當(dāng)復(fù)雜的形狀。

矩形 rectangles

first let's look at the rectangle. there are three functions that draw rectangles on the canvas:

我們首先看看矩形吧,有三個(gè)函數(shù)用于繪制矩形的:

fillrect(x,y,width,height) : draws a filled rectangle
strokerect(x,y,width,height) : draws a rectangular outline
clearrect(x,y,width,height) : clears the specified area and makes it fully transparent

each of these three functions takes the same parameters. x and y specify the position on the canvas (relative to the origin) of the top-left corner of the rectangle. width and height are pretty obvious. let's see these functions in action.

它們都接受四個(gè)參數(shù), xy 指定矩形左上角(相對(duì)于原點(diǎn))的位置,width height 是矩形的寬和高。好,實(shí)戰(zhàn)一下吧。

below is the draw() function from the previous page, but now i've added the three functions above.

下面就是上頁(yè)模板里的 draw() 函數(shù),但添加了上面的三個(gè)函數(shù)。

繪制矩形的例子 rectangular shape example

觀看示例

function draw(){  var canvas = document.getelementbyid('tutorial');  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);  }}

the result should look something like the image on the right. the fillrect function draws a large black square 100x100 pixels. the clearrect function removes a 60x60 pixels square from the center and finally the strokerect draws a rectangular outline 50x50 pixels inside the cleared square. in the following pages we'll see two alternative methods for the clearrect function and we'll also see how to change the color and stroke style of the rendered shapes.

出來(lái)的結(jié)果應(yīng)該和右邊的是一樣的。fillrect 函數(shù)畫了一個(gè)大的黑色矩形(100x100),clearrect 函數(shù)清空了中間 60x60 大小的方塊,然后strokerect 函數(shù)又在清空了的空間內(nèi)勾勒出一個(gè) 50x50 的矩形邊框。在接下去的頁(yè)面里,我們會(huì)看到和 clearrect 函數(shù)差不多另外兩個(gè)方法,以及如何去改變圖形的填充和邊框顏色。

unlike the path functions we'll see in the next section, all three rectangle functions draw immediately to the canvas.

與下一節(jié)的路徑函數(shù)不一樣,這三個(gè)函數(shù)的效果會(huì)立刻在 canvas 上反映出來(lái)。

繪制路徑 drawing paths

to make shapes using paths, we need a couple of extra steps.

不像畫矩形那樣的直截了當(dāng),繪制路徑是需要一些額外的步驟的。

beginpath()
closepath()
stroke()
fill()

the first step to create a path is calling the beginpath method. internally, paths are stored as a list of sub-paths (lines, arcs, etc) which together form a shape. every time this method is called, the list is reset and we can start drawing new shapes.

第一步是用 beginpath 創(chuàng)建一個(gè)路徑。在內(nèi)存里,路徑是以一組子路徑(直線,弧線等)的形式儲(chǔ)存的,它們共同構(gòu)成一個(gè)圖形。每次調(diào)用 beginpath,子路徑組都會(huì)被重置,然后可以繪制新的圖形。

the second step is calling the methods that actually specify the paths to be drawn. we'll see these shortly.

第二步就是實(shí)際繪制路徑的部分,很快我們就會(huì)看到。

the third, and an optional step, would be to call the closepath method. this method tries to close the shape by drawing a straight line from the current point to the start. if the shape has already been closed or there's only one point in the list, this function does nothing.

第三步是調(diào)用 closepath 方法,它會(huì)嘗試用直線連接當(dāng)前端點(diǎn)與起始端點(diǎn)來(lái)關(guān)閉路徑,但如果圖形已經(jīng)關(guān)閉或者只有一個(gè)點(diǎn),它會(huì)什么都不做。這一步不是必須的。

the final step will be calling the stroke and/or fill methods. calling one of these will actually draw the shape to the canvas. stroke is used to draw an outlined shape, while fill is used to paint a solid shape.

最后一步是調(diào)用 strokefill 方法,這時(shí),圖形才是實(shí)際的繪制到 canvas 上去。stroke 是繪制圖形的邊框,fill 會(huì)用填充出一個(gè)實(shí)心圖形。

note: when calling the fill method any open shapes will be closed automatically and it isn't necessary to use the closepath method.

注意:當(dāng)調(diào)用 fill 時(shí),開(kāi)放的路徑會(huì)自動(dòng)閉合,而無(wú)須調(diào)用 closepath

the code for a drawing simple shape (a triangle) would look something like this.

畫一個(gè)簡(jiǎn)單圖形(如三角形)的代碼如下。

ctx.beginpath();ctx.moveto(75,50);ctx.lineto(100,75);ctx.lineto(100,25);ctx.fill();

moveto

one very useful function, which doesn't actually draw anything, but is part of the path list described above, is the moveto function. you can probably best think of this as lifting a pen or pencil from one spot on a piece of paper and placing it on the next.

moveto 是一個(gè)十分有用的方法,雖然并不能用它來(lái)畫什么,但卻是繪制路徑的實(shí)用方法的一部分。你可以把它想象成是把筆提起,并從一個(gè)點(diǎn)移動(dòng)到另一個(gè)點(diǎn)的過(guò)程。

moveto(x, y)

the moveto function takes two arguments - x and y, - which are the coordinates of the new starting point.

它接受 xy (新的坐標(biāo)位置)作為參數(shù)。

when the canvas is initialized or the beginpath method is called, the starting point is set to the coordinate (0,0). in most cases we would use the moveto method to place the starting point somewhere else. we could also use the moveto method to draw unconnected paths. take a look at the smiley face on the right. i've marked the places where i used the moveto method (the red lines).

當(dāng) canvas 初始化或者調(diào)用 beginpath 的時(shí)候,起始坐標(biāo)設(shè)置就是原點(diǎn)(0,0)。大多數(shù)情況下,我們用 moveto 方法將起始坐標(biāo)移至其它地方,或者用于繪制不連續(xù)的路徑。看看右邊的笑臉,紅線就是使用 moveto 移動(dòng)的軌跡。

to try this for yourself, you can use the code snippet below. just paste it into the draw function we saw earlier.

試一試下面的代碼,粘貼到之前用過(guò)的 draw 函數(shù)內(nèi)在看看效果吧。

moveto 的使用示例

ctx.beginpath();ctx.arc(75,75,50,0,math.pi*2,true); // outer circlectx.moveto(110,75);ctx.arc(75,75,35,0,math.pi,false);   // mouth (clockwise)ctx.moveto(65,65);ctx.arc(60,65,5,0,math.pi*2,true);  // left eyectx.moveto(95,65);ctx.arc(90,65,5,0,math.pi*2,true);  // right eyectx.stroke();

note: remove the moveto methods to see the connecting lines.
note: for a description of the arc function and its parameters look below.

注意:你可以注釋 moveto 方法來(lái)觀察那些連接起來(lái)的線。
注意:arc 方法的用法見(jiàn)下面。

直線 lines

for drawing straight lines we use the lineto method.

我們用 lineto 方法來(lái)畫直線。

lineto(x, y)

this method takes two arguments - x and y, - which are the coordinates of the line's end point. the starting point is dependent on previous drawn paths, where the end point of the previous path is the starting point for the following, etc. the starting point can also be changed by using the moveto method.

lineto 方法接受終點(diǎn)的坐標(biāo)(x,y)作為參數(shù)。起始坐標(biāo)取決于前一路徑,前一路徑的終點(diǎn)即當(dāng)前路徑的起點(diǎn),起始坐標(biāo)也可以通過(guò) moveto 方法來(lái)設(shè)置。

lineto 的使用示例

in the example below two triangles are drawn, one filled and one outlined. (the result can be seen in the image on the right). first the beginpath method is called to begin a new shape path. we then use the moveto method to move the starting point to the desired position. below this two lines are drawn which make up two sides of the triangle.

示例(如右圖)畫的是兩個(gè)三角形,一個(gè)實(shí)色填充,一個(gè)勾邊。首先調(diào)用 beginpath 方法創(chuàng)建一個(gè)新路徑,然后用moveto 方法將起始坐標(biāo)移至想要的位置,然后畫兩條直線來(lái)構(gòu)成三角形的兩條邊。

you'll notice the difference between the filled and stroked triangle. this is, as mentioned above, because shapes are automatically closed when a path is filled. if we would have done this for the stroked triangle only two lines would have been drawn, not a complete triangle.

可以注意到 fill 和 strok 繪三角形的區(qū)別,上面也提到過(guò),使用 fill 路徑會(huì)自動(dòng)閉合,但使用 stroke 不會(huì),如果不關(guān)閉路徑,勾畫出來(lái)的只有兩邊。

觀看示例

// 填充三角形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(); 

弧線 arcs

for drawing arcs or circles we use the arc method. the specification also describes the arcto method, which is supported by safari but hasn't been implemented in the current gecko browsers.

我們用 arc 方法來(lái)繪制弧線或圓。標(biāo)準(zhǔn)說(shuō)明中還包含 arcto 方法,當(dāng)前 safari 是支持的,但基于 gecko 的瀏覽器還未實(shí)現(xiàn)。

arc(x, y, radius, startangle, endangle, anticlockwise)

this method takes five parameters: x and y are the coordinates of the circle's center. radius is self explanatory. the startangle and endangle parameters define the start and end points of the arc in radians. the starting and closing angle are measured from the x axis. the anticlockwise parameter is a boolean value which when true draws the arc anticlockwise, otherwise in a clockwise direction.

方法接受五個(gè)參數(shù):x,y 是圓心坐標(biāo),radius 是半徑,startangleendangle 分別是起末弧度(以 x 軸為基準(zhǔn)),anticlockwise 為 true 表示逆時(shí)針,反之順時(shí)針。

warning: in the firefox beta builds, the last parameter is clockwise. the final release will support the function as described above. all scripts that use this method in its current form will need to be updated once the final version is released.

警告:在 firefox 的 beta 版本里,最后一個(gè)參數(shù)是 clockwise,而最終版本不是。因此如果是從 beta 升級(jí)至發(fā)行版需要做相應(yīng)修改。

note: angles in the arc function are measured in radians, not degrees. to convert degrees to radians you can use the following javascript expression: var radians = (math.pi/180)*degrees.

注意:arc 方法里用到的角度是以弧度為單位而不是度。度和弧度直接的轉(zhuǎn)換可以用這個(gè)表達(dá)式:var radians = (math.pi/180)*degrees;。

arc 的使用示例

the following example is a little more complex than the ones we've seen above. i've drawn 12 different arcs all with different angles and fills. if i would have written this example just like the smiley face above, firstly this would have become a very long list of statements and secondly, when drawing arcs, i would need to know every single starting point. for arcs of 90, 180 and 270 degrees, like the ones i used here, this wouldn't be to much of a problem, but for more complex ones this becomes way too difficult.

這個(gè)示例比之前見(jiàn)到過(guò)的要復(fù)雜一些,畫了12個(gè)不同的弧形,有不同夾角和填充狀態(tài)的。如果我用上面畫笑臉的方式來(lái)畫這些弧形,那會(huì)是一大段的代碼,而且,畫每一個(gè)弧形時(shí)我都需要知道其圓心位置。像這里畫 90,180 和 270 度的弧形同樣是一個(gè)問(wèn)題,如果圖形越繁雜實(shí)現(xiàn)起來(lái)會(huì)越困難。

the two for loops are for looping through the rows and columns of arcs. for every arc i start a new path using beginpath. below this i've written out all the parameters as variables, so it's easier to read what's going on. normally this would be just one statement. the x and y coordinates should be clear enough. radius and startangle are fixed. the endangle starts of as 180 degrees (first column) and is increased with steps of 90 degrees to form a complete circle (last column). the statement for the clockwise parameter results in the first and third row being drawn as clockwise arcs and the second and fourth row as counterclockwise arcs. finally, the if statement makes the top half stroked arcs and the bottom half filled arcs.

這里使用兩個(gè) for 循環(huán)來(lái)畫多行多列的弧形。每一個(gè)弧形都用 beginpath 方法創(chuàng)建一個(gè)新路徑。然后為了方便閱讀和理解,我把所有參數(shù)都寫成變量形式。顯而易見(jiàn),x 和 y 作為圓心坐標(biāo)。 radius startangle 都是固定,endangle 從 180 度半圓開(kāi)始,以 90 度方式遞增至圓。anticlockwise 則取決于奇偶行數(shù)。最后,通過(guò) if 語(yǔ)句判斷使前兩行表現(xiàn)為勾邊,而后兩行為填充效果。

for (i=0;i<4;i++){  for(j=0;j<3;j++){    ctx.beginpath();    var x              = 25+j*50;               // x coordinate    var y              = 25+i*50;               // y coordinate    var radius         = 20;                    // arc radius    var startangle     = 0;                     // starting point on circle    var endangle       = math.pi+(math.pi*j)/2; // end point on circle    var anticlockwise  = i%2==0 ? false : true; // clockwise or anticlockwise    ctx.arc(x,y,radius,startangle,endangle, anticlockwise);    if (i>1){      ctx.fill();    } else {      ctx.stroke();    }  }}

貝塞爾和二次方曲線 bezier and quadratic curves

the next type of paths available are bézier curves, available in the cubic and quadratic varieties. these are generally used to draw complex organic shapes.

 接下來(lái)要介紹的路徑是 貝塞爾曲線 ,它可以是二次和三次方的形式,一般用于繪制復(fù)雜而有規(guī)律的形狀。

quadraticcurveto(cp1x, cp1y, x, y) // broken in firefox 1.5 (see work around below)
beziercurveto(cp1x, cp1y, cp2x, cp2y, x, y)


the difference between these can best be described using the image on the right. a quadratic bézier curve has a start and an end point (blue dots) and just one control point (red dot) while a cubic bézier curve uses two control points.

上面兩行代碼的區(qū)別見(jiàn)右圖。它們都有一個(gè)起點(diǎn)一個(gè)終點(diǎn)(圖中的藍(lán)點(diǎn)),但二次方貝塞爾曲線只有一個(gè)(紅色)控制點(diǎn)點(diǎn))而三次方貝塞爾曲線有兩個(gè)。

the x and y parameters in both these methods are the coordinates of the end point. cp1x and cp1y are the coordinates of the first control point, and cp2x and cp2y are the coordinates of the second control point.

參數(shù) xy 是終點(diǎn)坐標(biāo),cp1x cp1y 是第一個(gè)控制點(diǎn)的坐標(biāo),cp2x cp2y 是第二個(gè)的。

using quadratic and cubic bézier curves can be quite challenging, because unlike vector drawing software like adobe illustrator, we don't have direct visual feedback as to what we're doing. this makes it pretty hard to draw complex shapes. in the following example, we'll be drawing some simple organic shapes, but if you have the time and, most of all, the patience, much more complex shapes can be created.

使用二次方和三次方的貝塞爾曲線是相當(dāng)有挑戰(zhàn)的,因?yàn)椴幌裨谑噶坷L圖軟件 adobe illustrator 里那樣有即時(shí)的視覺(jué)反饋。因?yàn)橛盟鼇?lái)畫復(fù)雜圖形是比較麻煩的。但如果你有時(shí)間,并且最重要是有耐心,再?gòu)?fù)雜的圖形都可以繪制出來(lái)的。下面我們來(lái)畫一個(gè)簡(jiǎn)單而又規(guī)律的圖形。

there's nothing very difficult in these examples. in both cases we see a succession of curves being drawn which finally result in a complete shape.

這些例子都比較簡(jiǎn)單。我們繪制的都是完整的圖形。

quadraticcurveto 的使用示例

// quadratric curves examplectx.beginpath();ctx.moveto(75,25);ctx.quadraticcurveto(25,25,25,62.5);ctx.quadraticcurveto(25,100,50,100);ctx.quadraticcurveto(50,120,30,125);ctx.quadraticcurveto(60,120,65,100);ctx.quadraticcurveto(125,100,125,62.5);ctx.quadraticcurveto(125,25,75,25);ctx.stroke();

it is possible to convert any quadratic bézier curve to a cubic bézier curve by correctly computing both cubic bézier control points from the single quadratic bézier control point, although the reverse is not true. an exact conversion of a cubic bézier curve to a quadratic bézier curve is only possible if the cubic term is zero, more commonly a subdivision method is used to approximate a cubic bézier using multiple quadratic bézier curves.

通過(guò)計(jì)算,可以由二次曲線的單個(gè)控制點(diǎn)得出相應(yīng)三次方曲線的兩個(gè)控制點(diǎn),因此二次方轉(zhuǎn)三次方是可能的,但是反之不然。僅當(dāng)三次方程中的三次項(xiàng)為零是才可能轉(zhuǎn)換為二次的貝塞爾曲線。通常地可以用多條二次方曲線通過(guò)細(xì)分算法來(lái)近似模擬三次方貝塞爾曲線。

beziercurveto 的使用示例

// bezier curves examplectx.beginpath();ctx.moveto(75,40);ctx.beziercurveto(75,37,70,25,50,25);ctx.beziercurveto(20,25,20,62.5,20,62.5);ctx.beziercurveto(20,80,40,102,75,120);ctx.beziercurveto(110,102,130,80,130,62.5);ctx.beziercurveto(130,62.5,130,25,100,25);ctx.beziercurveto(85,25,75,37,75,40);ctx.fill();

firefox 1.5 quadraticcurveto() bug 的應(yīng)對(duì)方案

there is a bug in the firefox 1.5 implementation of quadatriccurveto(). it does not draw a quadratic curve, as it is just calling the same cubic curve function beziercurveto() calls, and repeating the single quadratic control point (x,y) coordinate twice. for this reason quadraticcurveto() will yield incorrect results. if you require the use of quadraticcurveto() you must convert your quadratic bézier curve to a cubic bézier curve yourself, so you can use the working beziercurveto() method.

在 firefox 1.5 里,quadatriccurveto() 的實(shí)現(xiàn)是有 bug 的,它不是直接繪制二次方曲線,而是調(diào)用 beziercurveto() ,其中兩個(gè)控制點(diǎn)都是二次方曲線的那個(gè)單控制點(diǎn)。因此,它會(huì)繪制出不正確的曲線。如果必須使用到 quadraticcurveto(),你需要自行去將二次方曲線轉(zhuǎn)換成三次方的,這樣就可以用 beziercurveto() 方法了。

var currentx, currenty;  // set to last x,y sent to lineto/moveto/beziercurveto or quadraticcurvetofixed()function quadraticcurvetofixed( cpx, cpy, x, y ) {  /*   for the equations below the following variable name prefixes are used:     qp0 is the quadratic curve starting point (you must keep this from your last point sent to moveto(), lineto(), or beziercurveto() ).     qp1 is the quadatric curve control point (this is the cpx,cpy you would have sent to quadraticcurveto() ).     qp2 is the quadratic curve ending point (this is the x,y arguments you would have sent to quadraticcurveto() ).   we will convert these points to compute the two needed cubic control points (the starting/ending points are the same for both   the quadratic and cubic curves.   the equations for the two cubic control points are:     cp0=qp0 and cp3=qp2     cp1 = qp0 + 2/3 *(qp1-qp0)     cp2 = cp1 + 1/3 *(qp2-qp0)    in the code below, we must compute both the x and y terms for each point separately.     cp1x = qp0x + 2.0/3.0*(qp1x - qp0x);    cp1y = qp0y + 2.0/3.0*(qp1y - qp0y);    cp2x = cp1x + (qp2x - qp0x)/3.0;    cp2y = cp1y + (qp2y - qp0y)/3.0;   we will now      a) replace the qp0x and qp0y variables with currentx and currenty (which *you* must store for each moveto/lineto/beziercurveto)     b) replace the qp1x and qp1y variables with cpx and cpy (which we would have passed to quadraticcurveto)     c) replace the qp2x and qp2y variables with x and y.   which leaves us with:   */  var cp1x = currentx + 2.0/3.0*(cpx - currentx);  var cp1y = currenty + 2.0/3.0*(cpy - currenty);  var cp2x = cp1x + (x - currentx)/3.0;  var cp2y = cp1y + (y - currenty)/3.0;  // and now call cubic bezier curve to function   beziercurveto( cp1x, cp1y, cp2x, cp2y, x, y );  currentx = x;  currenty = y;}

又是矩形 rectangles

besides the three methods we saw above which draw rectangular shapes directly to the canvas, we also have a method rect which adds a rectangular path to the path list.

除了上面提到的三個(gè)方法可以直接繪制矩形之外,我們還有一個(gè) rect 方法是用于繪制矩形路徑的。

rect(x, y, width, height)

this method takes four arguments. the x and y parameters define the coordinate of the top left corner of the new rectangular path. width and height define the width and the height of the rectangle.

它接受四個(gè)參數(shù),x y 是其左上角坐標(biāo),width height 是其寬和高。

when this method is executed, the moveto method is automatically called with the parameters (0,0) (i.e. it resets the starting point to its default location).

當(dāng)它被調(diào)用時(shí),moveto 方法會(huì)自動(dòng)被調(diào)用,于是起始坐標(biāo)又恢復(fù)成原點(diǎn)了。

大雜燴 making combinations

in all examples on this page i've only used one type of path function per shape. however there's absolutely no limitation to the amount or type of paths you can use to create a shape. so in this last example i've tried to combine all of the path functions to make a set of very famous game characters.

上面所用到的例子都只用到了一種類型的路徑,當(dāng)然 canvas 不會(huì)限制所使用的路徑類型的多少。所以,我們來(lái)看一個(gè)路徑大雜燴。

大雜燴樣例

i'm not going to run through this complete script, but the most important things to note are the function roundedrect and the use of the fillstyle property. it can be very usefull and time saving to define your own functions to draw more complex shapes. in this script it would have taken me twice as many lines of code as i have now.
we will look at the fillstyle property in greater depth later in this tutorial. here i'm using it to change the fill color from the default black, to white, and back again.

在整個(gè)例子里,最值得注意的是 roundedrect 函數(shù)的使用和 fillstyle 屬性的設(shè)置。自定義函數(shù)對(duì)于封裝復(fù)雜圖形的繪制是非常有用的。在這個(gè)例子里使用自定義函數(shù)就省掉了大約一半的代碼。

在接下來(lái)的例子里會(huì)深入探討 fillstyle 屬性的使用。這里是用它來(lái)改變填充顏色,從默認(rèn)的黑色,到白色,然后再回到黑色。

查看示例

function draw() {  var ctx = document.getelementbyid('canvas').getcontext('2d');  roundedrect(ctx,12,12,150,150,15);  roundedrect(ctx,19,19,150,150,9);  roundedrect(ctx,53,53,49,33,10);  roundedrect(ctx,53,119,49,16,6);  roundedrect(ctx,135,53,49,33,10);  roundedrect(ctx,135,119,25,49,10);  ctx.beginpath();  ctx.arc(37,37,13,math.pi/7,-math.pi/7,true);  ctx.lineto(31,37);  ctx.fill();  for(i=0;i<8;i++){    ctx.fillrect(51+i*16,35,4,4);  }  for(i=0;i<6;i++){    ctx.fillrect(115,51+i*16,4,4);  }  for(i=0;i<8;i++){    ctx.fillrect(51+i*16,99,4,4);  }  ctx.beginpath();  ctx.moveto(83,116);  ctx.lineto(83,102);  ctx.beziercurveto(83,94,89,88,97,88);  ctx.beziercurveto(105,88,111,94,111,102);  ctx.lineto(111,116);  ctx.lineto(106.333,111.333);  ctx.lineto(101.666,116);  ctx.lineto(97,111.333);  ctx.lineto(92.333,116);  ctx.lineto(87.666,111.333);  ctx.lineto(83,116);  ctx.fill();  ctx.fillstyle = "white";  ctx.beginpath();  ctx.moveto(91,96);  ctx.beziercurveto(88,96,87,99,87,101);  ctx.beziercurveto(87,103,88,106,91,106);  ctx.beziercurveto(94,106,95,103,95,101);  ctx.beziercurveto(95,99,94,96,91,96);  ctx.moveto(103,96);  ctx.beziercurveto(100,96,99,99,99,101);  ctx.beziercurveto(99,103,100,106,103,106);  ctx.beziercurveto(106,106,107,103,107,101);  ctx.beziercurveto(107,99,106,96,103,96);  ctx.fill();  ctx.fillstyle = "black";  ctx.beginpath();  ctx.arc(101,102,2,0,math.pi*2,true);  ctx.fill();  ctx.beginpath();  ctx.arc(89,102,2,0,math.pi*2,true);  ctx.fill();}function roundedrect(ctx,x,y,width,height,radius){  ctx.beginpath();  ctx.moveto(x,y+radius);  ctx.lineto(x,y+height-radius);  ctx.quadraticcurveto(x,y+height,x+radius,y+height);  ctx.lineto(x+width-radius,y+height);  ctx.quadraticcurveto(x+width,y+height,x+width,y+height-radius);  ctx.lineto(x+width,y+radius);  ctx.quadraticcurveto(x+width,y,x+width-radius,y);  ctx.lineto(x+radius,y);  ctx.quadraticcurveto(x,y,x,y+radius);  ctx.stroke();}
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 邳州市| 西华县| 桃园市| 阿巴嘎旗| 罗江县| 九台市| 太仆寺旗| 开江县| 论坛| 宜城市| 辽宁省| 印江| 定兴县| 房产| 宁化县| 巴南区| 金平| 泰州市| 宜君县| 汉寿县| 兴业县| 望都县| 哈尔滨市| 永丰县| 临夏县| 塔城市| 泰和县| 聂荣县| 邓州市| 东海县| 青岛市| 三原县| 荣成市| 泰来县| 深水埗区| 龙口市| 武清区| 丰宁| 吴堡县| 齐河县| 长春市|