av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

HTML 5 Canvas 遞歸畫樹

上圖就是用html5隨機(jī)生成的大樹 : ) 但是你應(yīng)該沒想到40+行代碼就可以搞定了吧~接下來就跟大家說說這棵大樹是如何實(shí)現(xiàn)的。

創(chuàng)新互聯(lián)建站服務(wù)項(xiàng)目包括翼城網(wǎng)站建設(shè)、翼城網(wǎng)站制作、翼城網(wǎng)頁制作以及翼城網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,翼城網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到翼城省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

同樣必須要有html容器。新建Index.html,代碼如下:

 
 
 
 
  1.  
  2.  
  3.  
  4. canvas tree 
  5.  
  6.  
  7.  
  8.  
  9.  

接下來咱們開始tree.js:

 
 
 
 
  1. var canvas = document.createElement("canvas");  
  2. var ctx = canvas.getContext("2d");  
  3. canvas.width = 640;  
  4. canvas.height = 480;  
  5. document.body.appendChild(canvas); 

代碼很好理解,創(chuàng)建一個(gè)canvas畫布,然后選擇為2d畫布,設(shè)置長寬,***將這個(gè)畫布添加到body標(biāo)簽下。

這個(gè)腳本最重要的函數(shù)在下面,大樹就是遞歸調(diào)用這個(gè)函數(shù)實(shí)現(xiàn)的,調(diào)用一次畫一條線段:

 
 
 
 
  1. var drawTree = function (ctx, startX, startY, length, angle, depth, branchWidth){  
  2. var rand = Math.random,  
  3. newLength, newAngle, newDepth, maxBranch = 3,  
  4. endX, endY, maxAngle = 2 * Math.PI / 4,  
  5. subBraches;  
  6. ctx.beginPath();  
  7. ctx.moveTo(startX, startY);  
  8. endX = startX + length * Math.cos(angle);  
  9. endY = startY + length * Math.sin(angle);  
  10. ctx.lineCap = 'round';  
  11. ctx.lineWidth = branchWidth;  
  12. ctx.lineTo(endX, endY);  
  13. if (depth <= 2){  
  14. ctx.strokeStyle = 'rgb(0,' + (((rand() * 64) + 128) >> 0) + ',0)';  
  15. } else {  
  16. ctx.strokeStyle = 'rgb(' + (((rand() * 64) + 64) >> 0) + ',50,25)';  
  17. }  
  18. ctx.stroke();  
  19. newDepth = depth - 1;  
  20. if (!newDepth)  
  21. return;  
  22. subBranches = (rand() * (maxBranch - 1)) + 1;  
  23. branchWidth *= 0.7;  
  24. for (var i = 0; i < subBranches; i++){  
  25. newAngle = angle + rand() * maxAngle - maxAngle * 0.5;  
  26. newLength = length * (0.7 + rand() * 0.3);  
  27. drawTree(ctx, endX, endY, newLength, newAngle, newDepth, branchWidth);  
  28. }  

接下來一點(diǎn)點(diǎn)解釋:

首先,解釋下各個(gè)變量的含義。ctx就是前面我們的2d畫布;startX是線段開始的橫坐標(biāo),同理startY是縱坐標(biāo);length是線段長度;angle是角度;depth是深度,葉子深度為1,樹干為12(可自己設(shè)定);branchWidth就線段的粗細(xì)。有了這些信息,其實(shí)就描述了一個(gè)線段,通過這些信息我們才能畫一個(gè)線段。

接下來又很可恥地一大段定義:

 
 
 
 
  1. var rand = Math.random,  
  2. newLength, newAngle, newDepth, maxBranch = 3,  
  3. endX, endY, maxAngle = 2 * Math.PI / 4,  
  4. subBraches; 

rand其實(shí)就是隨機(jī)一個(gè)0~1之間的實(shí)數(shù),顧名思義,接下來這些new的就是下一節(jié)線段的各種參數(shù)。maxBranch就是最多有3個(gè)分叉,***的角度 PI/2 即為,下一級調(diào)整角度在90%范圍內(nèi)。subBranches就是分叉的個(gè)數(shù)。

好了,重要可以畫了:

 
 
 
 
  1. ctx.beginPath();  
  2. ctx.moveTo(startX, startY);  
  3. endX = startX + length * Math.cos(angle);  
  4. endY = startY + length * Math.sin(angle);  
  5. ctx.lineCap = 'round';  
  6. ctx.lineWidth = branchWidth;  
  7. ctx.lineTo(endX, endY); 

beginPath()表示告訴瀏覽器“我要開始畫了!”,把之前的記錄放棄了,這點(diǎn)有點(diǎn)像ps。moveTo()把光標(biāo)移動(dòng)到(startX, startY),再計(jì)算終點(diǎn)坐標(biāo),endX,endY,有點(diǎn)像高中學(xué)的參數(shù)方程。然后告訴瀏覽器,lineCap要round,線段的兩頭要是圓形的。有多粗呢?等于branchWidth。線段一直畫到(endX, endY)。

 
 
 
 
  1. if (depth <= 2){  
  2. ctx.strokeStyle = 'rgb(0,' + (((rand() * 64) + 128) >> 0) + ',0)';  
  3. } else {  
  4. ctx.strokeStyle = 'rgb(' + (((rand() * 64) + 64) >> 0) + ',50,25)';  

如果是已經(jīng)畫到了***兩級,即為葉子,那么就rgb就為(0, 128~192, 0)(rgb代表顏色,分別為紅綠藍(lán),red green blue)。還沒的話,就在(64~128, 50 ,25)中取。大家可能發(fā)現(xiàn)了,rgb必須為整數(shù),但是rand()只能rand實(shí)數(shù)。大家其實(shí)也注意到了有個(gè)” >>  0″,js當(dāng)中表示位運(yùn)算,整體向右移動(dòng)n位,0就是移動(dòng)0位。其實(shí)它的作用和Math.floor()一樣,但是速度更快。

動(dòng)手畫!

 
 
 
 
  1. ctx.stroke(); 

這個(gè)線段就畫好了,是時(shí)候準(zhǔn)備下它的分叉的時(shí)候了。

 
 
 
 
  1. newDepth = depth - 1;  
  2. if (!newDepth)  
  3. return; 

如果這個(gè)線段是***一級,就沒有分叉了,也是一個(gè)遞歸的終止條件。

 
 
 
 
  1. subBranches = (rand() * (maxBranch - 1)) + 1;  
  2. branchWidth *= 0.7;  
  3. for (var i = 0; i < subBranches; i++){  
  4. newAngle = angle + rand() * maxAngle - maxAngle * 0.5;  
  5. newLength = length * (0.7 + rand() * 0.3);  
  6. drawTree(ctx, endX, endY, newLength, newAngle, newDepth, branchWidth);  

分叉數(shù)是1~3中的一個(gè)數(shù)。然后有多少個(gè)分叉,就畫幾條線段,newAngle為原角度調(diào)整90度之內(nèi),新長度為原長度的0.7~1.0之間。

***畫出主干,這棵樹就可以開始畫了。

 
 
 
 
  1. drawTree(ctx, 320, 470, 60, -Math.PI / 2, 12, 12); 

大家可能注意到角度為負(fù),不符合傳統(tǒng)觀念。但你要知道,畫布的縱坐標(biāo)和傳統(tǒng)的坐標(biāo)軸正好是相反的。

剩下可以發(fā)揮的東西還很多,比如大家可以調(diào)整各種參數(shù),使樹的顏色、大小變化,或者用這種方法去做些其他的事~

打完收工~附上文件:tree.zip


網(wǎng)頁標(biāo)題:HTML 5 Canvas 遞歸畫樹
當(dāng)前鏈接:http://uogjgqi.cn/article/dhjhjdc.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們在微信上24小時(shí)期待你的聲音

解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流