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

首頁(yè) > 網(wǎng)站 > WEB開發(fā) > 正文

Canvas使用教程——幾何圖形繪制(Drawing shapes)

2024-04-27 13:52:42
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

原文:http://developer.mozilla.org/en/Canvas_tutorial/Drawing_shapes 

The grid

在我們開始繪制圖形前,我們先探討一下canvas中的網(wǎng)格及坐標(biāo)空間。在前一篇教程中,我們定義了一個(gè)150*150的canvas區(qū)域,并在該區(qū)域繪制了一個(gè)圖形。在canvas區(qū)域中,以左上角為坐標(biāo)原點(diǎn)(0,0),坐標(biāo)最小單位為1px。區(qū)域內(nèi)所有元素相對(duì)與原點(diǎn)定位。不過(guò)在以后的實(shí)例中,我們還會(huì)向你展示如何重定義坐標(biāo)原點(diǎn)、旋轉(zhuǎn)坐標(biāo)甚至是重新定義坐標(biāo)單位,但是現(xiàn)在,我們還是從默認(rèn)設(shè)置開始學(xué)習(xí)。

Drawing shapes

與SVG語(yǔ)法不同的是,canvas只提供了一個(gè)繪制矩形的語(yǔ)法,其他形狀的繪制就必須依靠路徑功能來(lái)繪制了,哈哈,其實(shí)我們已經(jīng)收集了很多多繪制各種復(fù)雜多邊形的function,拿來(lái)就能用嘍。

Rectangles

首先讓我們來(lái)看下,目前有三種繪制矩形的語(yǔ)法:

fillRect(x,y,width,height) : 繪制一個(gè)實(shí)心的舉行strokeRect(x,y,width,height) : 繪制一個(gè)矩形邊框clearRect(x,y,width,height) : 繪制一個(gè)透明的矩形

以上三種方法中都有x和y參數(shù),這對(duì)參數(shù)的值就是相對(duì)于canvas原點(diǎn)(左上角)的距離。

以下代碼為之前教程中出現(xiàn)過(guò)的draw()函數(shù),我們這次將三種矩形繪制的方法都寫進(jìn)去:

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);  }}
 

繪制的效果見右圖,fillRect函數(shù)繪制了一個(gè)100*100的大矩形,clearRect函數(shù)從這個(gè)矩形挖掉了一塊60*60的矩形并且strokeRect函數(shù)又繪制了一個(gè)50*50的矩形邊框。在以后的教材中我們將看到另外的clearRect方法以及我們?nèi)绾螢榫匦翁畛洳煌念伾屠L制不同的邊框。

與接下來(lái)我們要講的path方法不同,以上三個(gè)矩形繪制方法執(zhí)行后都會(huì)立即應(yīng)用到canvas區(qū)域內(nèi)。

Drawing paths

用路徑來(lái)繪制多邊形,以下這些方法我們都是需要的:

beginPath()closePath()stroke()fill()

第一步,我們使用beginPath方法聲明一個(gè)路徑,路徑的繪制需要用到一系列字方法(lines,arcs,ect)共同配合來(lái)完成一個(gè)多邊形,每次我們用到路徑來(lái)繪制多邊形時(shí),我們都需要聲明一個(gè)beginPath來(lái)開始繪制。

第二步,我們將需要調(diào)用一些特定方法來(lái)繪制我們需要的路徑,我們很快就會(huì)了解到。

第三步,closePath,是一個(gè)可選步驟,這個(gè)方法將封閉繪制路徑的起點(diǎn),如果該多邊形已經(jīng)被封閉,那么,這個(gè)方法將不產(chǎn)生任何作用。

最后的步驟,是運(yùn)用stroke或者fill方法,為繪制好的多邊形路徑填充顏色或者描邊。

注意:如果用fill方法填充一個(gè)未封閉的多邊形時(shí),該多邊形將被自動(dòng)封閉,無(wú)需closePath幫忙了。

例如,以下代碼將會(huì)繪制一個(gè)簡(jiǎn)單的三角形:

ctx.beginPath();ctx.moveTo(75,50);ctx.lineTo(100,75);ctx.lineTo(100,25);ctx.fill();

moveTo

這是一個(gè)非常有用的函數(shù),雖然該函數(shù)不會(huì)繪制任何東西,但是它是路徑描述中的一個(gè)重要的功能。

moveTo函數(shù)將傳入2個(gè)參數(shù),x坐標(biāo)和y坐標(biāo),以該坐標(biāo)點(diǎn)為一個(gè)新的繪制起點(diǎn)。

當(dāng)canvas初始化或者beginPath方法執(zhí)行后,最起始的坐標(biāo)點(diǎn)默認(rèn)是(0,0),在絕大多數(shù)的應(yīng)用中,我們會(huì)用moveTo方法來(lái)定位路徑繪制的起點(diǎn)。我們亦可以用此方法繪制一些沒(méi)有連接的路徑,比如右邊的這張笑臉圖,用紅色線條標(biāo)識(shí)出來(lái)的就是用moveTo方法來(lái)實(shí)現(xiàn)的。

示例

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();

Lines

顧名思義,畫直線的方法。

lineTo(x, y)
 

該方法帶的2個(gè)參數(shù)為線段終點(diǎn)的坐標(biāo),起點(diǎn)坐標(biāo)則依賴于上一個(gè)路徑所申明的終點(diǎn),當(dāng)然該線段的起點(diǎn)也可以是由moveTo方法所申明的坐標(biāo)。

示例:如右邊的圖片所示,我們繪制了2個(gè)三角形,一個(gè)做填充,一個(gè)做描邊。首先用beginPath方法申明一個(gè)新的路徑繪制,用moveTo方法定義繪制起點(diǎn)。

你可能會(huì)注意到繪制實(shí)心和空心的三角形,其語(yǔ)法略有差異,那是因?yàn)楫?dāng)一個(gè)多邊形需要填充時(shí),其會(huì)自動(dòng)封閉路徑的始末端。

 

// Filled trianglectx.beginPath();ctx.moveTo(25,25);ctx.lineTo(105,25);ctx.lineTo(25,105);ctx.fill();// Stroked trianglectx.beginPath();ctx.moveTo(125,125);ctx.lineTo(125,45);ctx.lineTo(45,125);ctx.closePath();ctx.stroke();

Arcs

該方法為繪制弧線或者圓形路徑時(shí)使用,該方法另一個(gè)寫法為arcTo,不過(guò)該寫法僅僅用于safari瀏覽器,而不會(huì)兼容采用Gecko為核心的瀏覽器。

arc(x, y, radius, startAngle, endAngle, anticlockwise)
 

該方法接收N個(gè)參數(shù):x和y為該段弧線所對(duì)應(yīng)的原點(diǎn)坐標(biāo);radius為半徑;startAngle和endAngle則決定了該段弧線的2個(gè)端點(diǎn),起始和結(jié)束的角度以坐標(biāo)系X軸為衡量基準(zhǔn);anticlockwise為一個(gè)布爾值參數(shù),當(dāng)為true時(shí)則逆時(shí)針?lè)较虍嫼粗畡t順時(shí)針。

警告:在firefox的某些beta版本中,最后一個(gè)參數(shù)被定義為clockwise,請(qǐng)確保將你的瀏覽器版本升級(jí)至最終發(fā)布版本。

注意:在本表達(dá)式中的Angle是以弧度為單位呈現(xiàn)的,實(shí)際運(yùn)用中,我們經(jīng)常需要在角度與弧度之間做一個(gè)轉(zhuǎn)換,其JS的轉(zhuǎn)換表達(dá)式為:var radians = (Math.PI/180)*degrees

 

示例:

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

如果我們需繪制更加復(fù)雜的曲線路徑,我們或許該用到貝塞爾或者2次方程曲線。

quadraticCurveTo(cp1x, cp1y, x, y) // BROKEN in Firefox 1.5 (see work around below)bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
 

兩種曲線有何區(qū)別?我們可以參看一下右邊這張圖,2種曲線都有一個(gè)起點(diǎn)和終點(diǎn)(blue point),但是貝塞爾曲線僅有一個(gè)“control point”(red point),2次曲線則有2個(gè)。

兩個(gè)方法中的x和y參數(shù)都為曲線的終點(diǎn)坐標(biāo),cp1x和cp1y為第一control point的坐標(biāo),cp2x和cp2y為2次曲線的第二控制點(diǎn)。

熟練運(yùn)用2次曲線和貝塞爾曲線進(jìn)行路徑繪制,是一件蠻有挑戰(zhàn)性的工作,因?yàn)樗幌衲承┦噶坷L圖軟件,比如ADOBE Illustrator等具有直觀的視覺反饋,所以這使得我們?cè)诶L制一些復(fù)雜的曲線時(shí)會(huì)遇到一點(diǎn)小困難,不過(guò)如果你有耐心和時(shí)間的話,你肯定能繪制出許多復(fù)雜的曲線來(lái)。

二次曲線示例:

 

// 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();

貝塞爾曲線示例:

 

// 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();
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 从化市| 安吉县| 延安市| 海城市| 休宁县| 错那县| 连云港市| 固原市| 镇安县| 大姚县| 湾仔区| 玛沁县| 东莞市| 建瓯市| 光山县| 邹平县| 安国市| 双牌县| 锦州市| 蒲江县| 焉耆| 塔城市| 舟山市| 张掖市| 鄂托克前旗| 深州市| 从化市| 武威市| 年辖:市辖区| 汉源县| 龙州县| 清丰县| 英山县| 南昌县| 柳林县| 雷波县| 高雄县| 明光市| 庆元县| 太和县| 肃宁县|