如果當(dāng)做一物件的話,數(shù)就是物件本身,樹干、樹葉、樹根、樹枝都是樹的屬性

創(chuàng)新互聯(lián)于2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目做網(wǎng)站、網(wǎng)站制作網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元白水做網(wǎng)站,已為上家服務(wù),為白水各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:13518219792
你可以依據(jù)這些屬性,再判斷是中給他不同的 css 樣式,而通常會(huì)先定義好類別
最后用 javascript 依照個(gè)屬性的不同,套上不同狀態(tài)的類別
不懂想問詳細(xì)可以私信我
HTML5的學(xué)習(xí)內(nèi)容
前端頁面重構(gòu):PC端網(wǎng)站布局、HTML5+CSS3基礎(chǔ)項(xiàng)目、WebAPP頁面布局;
JavaScript高級(jí)程序設(shè)計(jì):原生JavaScript交互功能開發(fā)、面向?qū)ο箝_發(fā)與ES5/ES6、JavaScript工具庫(kù)自主研發(fā);
PC端全棧項(xiàng)目開發(fā):jQuery經(jīng)典特效交互開發(fā)、HTTP協(xié)議,Ajxa進(jìn)階與后端開發(fā)、前端工程化與模塊化應(yīng)用、PC端網(wǎng)站開發(fā)、PC端管理信息系統(tǒng)前端開發(fā);
移動(dòng)端項(xiàng)目開發(fā):Touch端項(xiàng)目、微信場(chǎng)景項(xiàng)目、應(yīng)用Vue.js開發(fā)WebApp項(xiàng)目、應(yīng)用Ionic開發(fā)WebApp項(xiàng)目、應(yīng)用React.js開發(fā)WebApp;
混合(Hybrid)開發(fā):各類混合應(yīng)用開發(fā);
NodeJS全棧開發(fā):WebApp后端系統(tǒng)開發(fā)。
F12 調(diào)試頁面,Ctrl+F 搜索 Come Baby 找到它的位置,修改它,保存源碼,重新運(yùn)行
站內(nèi)搜索: (僅支持單關(guān)鍵字)
用HTML5 Canvas制作擺動(dòng)的樹
下載源代碼
〖 作者:cyclegtx 〗〖 發(fā)布日期:2014-07-05 〗
根據(jù)工作的需要,制作一個(gè)擺動(dòng)的樹做為頁面的背景。為了增加頁面的交互性,我又為背景中的樹增加了鼠標(biāo)(觸控)事件,使他能夠根據(jù)鼠標(biāo)(觸控)做出相應(yīng)的動(dòng)作,當(dāng)手指做上下或者左右滑動(dòng)的時(shí)候樹會(huì)跟著擺動(dòng)。先看看最終效果。
Step1.完成HTML頁面,新建一個(gè)Tree類
完成HTML頁面后新建一個(gè)Tree類用來記錄樹的各個(gè)屬性。其中x,y為樹根部的坐標(biāo)值,branchLen,branchWidth分別是樹枝的長(zhǎng)度與寬度,depth為樹枝的層數(shù),canvas用來接頁面中的canvas元素(默認(rèn)是ID為canvas的元素)。
html
meta charset="utf-8" /
head
style
body {
margin: 0;
background: #7ACFFA;
}
#canvas {
position: absolute;
top: 0; left: 0;
}
/style/headbody
canvas id="canvas" width="1" height="1"/canvas
script type='text/javascript'
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
function Tree(x,y,branchLen,branchWidth,depth,canvas){
this.canvas = canvas || document.getElementById('canvas');
this.ctx = this.canvas.getContext('2d');
this.x = x||0;
this.y = y||0;
this.branchLen = branchLen||0;
this.branchWidth = branchWidth||0;
var depth = depth || 5;
}
/script
/body/html
Step2.添加drawRoot方法,用來繪制樹干
首先在drawRoot中畫第一個(gè)枝干。drawRoot的參數(shù)意義同上。并且在Tree類的構(gòu)造函數(shù)中運(yùn)行drawRoot并把Tree接受到的參數(shù)傳入。最后new一個(gè)Tree類,使樹根位于屏幕的底部正中心,樹枝長(zhǎng)100px,樹枝寬度為8px,樹枝層數(shù)為8層(暫時(shí)用不上)。
var atree = new Tree(canvas.width/2-4,canvas.height,100,8,8,canvas);
在drawRoot中我們需要用lineTo()畫出樹枝。樹枝的起始的坐標(biāo)值(x,y)已經(jīng)給出,結(jié)束的坐標(biāo)值(toX,toY)需要進(jìn)行計(jì)算。第一個(gè)畫的是樹干,由于樹干垂直于地面所以結(jié)束坐標(biāo)toX等于初始坐標(biāo)x,而結(jié)束坐標(biāo)toY等于初始y減去樹干長(zhǎng)度branchLen(注意坐標(biāo)的0,0點(diǎn)在canvas的左上角)。
var toX = x;var toY = y-branchLen;
function Tree(x,y,branchLen,branchWidth,depth,canvas){
this.canvas = canvas || document.getElementById('canvas');
this.ctx = this.canvas.getContext('2d');
this.x = x||0;
this.y = y||0;
this.branchLen = branchLen||0;
this.branchWidth = branchWidth||0;
var depth = depth || 5;
this.drawRoot(this.x,this.y,this.branchLen,this.branchWidth);
}
Tree.prototype.drawRoot = function(x,y,branchLen,branchWidth){
var toX = x;
var toY = y-branchLen;
this.ctx.save();
this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
this.ctx.beginPath();
this.ctx.lineCap = "butt";
this.ctx.lineJoin="round";
this.ctx.lineWidth = branchWidth;
this.ctx.moveTo(x,y);
this.ctx.lineTo(toX,toY);
this.ctx.closePath();
this.ctx.stroke();
this.ctx.restore();
}
var atree = new Tree(canvas.width/2-4,canvas.height,100,8,8,canvas);
運(yùn)行代碼:
Step3.添加drawBranch方法,用來繪制樹枝
drawBranch同樣是根據(jù)初始與結(jié)束坐標(biāo)畫出一條直線代表樹枝。與樹干不同的是樹枝不再是垂直與地面而是與樹干保持一定的角度,而且樹枝的初始值是樹干的結(jié)束點(diǎn)(toX,toY)。所以在drawBranch中我們加入新參數(shù)angle用來表示樹枝與樹干的垂直夾角α,這樣就可以根據(jù)α算出toX與toY。請(qǐng)看圖。
這樣我們?cè)诋嬐陿涓珊笤俜謩e畫兩個(gè)不同角度的樹枝,一個(gè)是30°一個(gè)-30°。并將傳給樹枝的寬度branchWidth減小一個(gè)像素,使其與樹干粗細(xì)不同。
Tree.prototype.drawRoot = function(x,y,branchLen,branchWidth){
var toX = x;
var toY = y-branchLen;
this.ctx.save();
this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
this.ctx.beginPath();
this.ctx.lineCap = "butt";
this.ctx.lineJoin="round";
this.ctx.lineWidth = branchWidth;
this.ctx.moveTo(x,y);
this.ctx.lineTo(toX,toY);
this.ctx.closePath();
this.ctx.stroke();
this.ctx.restore();
this.drawBranch(toX,toY,branchLen,branchWidth-1,30);
this.drawBranch(toX,toY,branchLen,branchWidth-1,-30);
}
Tree.prototype.drawBranch = function(x,y,branchLen,branchWidth,angle){
var angle = angle || 0;
var radian = (90-angle)*(Math.PI/180);
var toX = x+Math.cos(radian)*branchLen;
var toY = y-Math.sin(radian)*branchLen;
this.ctx.save();
this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
this.ctx.beginPath();
this.ctx.lineCap = "butt";
this.ctx.lineJoin="round";
this.ctx.lineWidth = branchWidth;
this.ctx.moveTo(x,y);
this.ctx.lineTo(toX,toY);
this.ctx.closePath();
this.ctx.stroke();
this.ctx.restore();
}
運(yùn)行代碼:
Step4.修改drawBranch函數(shù),重復(fù)畫樹枝
在drawBranch函數(shù)的最后再次調(diào)用兩次drawBranch
this.drawBranch(toX,toY,branchLen,branchWidth-1,angle+30);
this.drawBranch(toX,toY,branchLen,branchWidth-1,angle-30);
使其調(diào)用自己完成遞歸,注意這里傳入的角度是在之前的角度的基礎(chǔ)上在增加或者減少30度。
為了使遞歸停下來我們需要一個(gè)停止條件,就是之前一直沒有用到的depth參數(shù)。我們?cè)诿看萎嬒乱粚又笆蛊錅p1表示已經(jīng)完成了一層樹枝的繪制,直至depth減小到0表示繪制完所有的層數(shù)。
function Tree(x,y,branchLen,branchWidth,depth,canvas){
this.canvas = canvas || document.getElementById('canvas');
this.ctx = this.canvas.getContext('2d');
this.x = x||0;
this.y = y||0;
this.branchLen = branchLen||0;
this.branchWidth = branchWidth||0;
var depth = depth || 5;
this.drawRoot(this.x,this.y,this.branchLen,this.branchWidth,depth);
}
Tree.prototype.drawRoot = function(x,y,branchLen,branchWidth,depth){
var toX = x;
var toY = y-branchLen;
var depth = depth||5;
this.ctx.save();
this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
this.ctx.beginPath();
this.ctx.lineCap = "butt";
this.ctx.lineJoin="round";
this.ctx.lineWidth = branchWidth;
this.ctx.moveTo(x,y);
this.ctx.lineTo(toX,toY);
this.ctx.closePath();
this.ctx.stroke();
this.ctx.restore();
depth--;
if(depth0){
this.drawBranch(toX,toY,branchLen,branchWidth-1,30,depth);
this.drawBranch(toX,toY,branchLen,branchWidth-1,-30,depth);
}
}
Tree.prototype.drawBranch = function(x,y,branchLen,branchWidth,angle,depth){
var angle = angle || 0;
var radian = (90-angle)*(Math.PI/180);
var toX = x+Math.cos(radian)*branchLen;
var toY = y-Math.sin(radian)*branchLen;
this.ctx.save();
this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
this.ctx.beginPath();
this.ctx.lineCap = "butt";
this.ctx.lineJoin="round";
this.ctx.lineWidth = branchWidth;
this.ctx.moveTo(x,y);
this.ctx.lineTo(toX,toY);
this.ctx.closePath();
this.ctx.stroke();
this.ctx.restore();
depth--;
if(depth0){
this.drawBranch(toX,toY,branchLen,branchWidth-1,angle+30,depth);
this.drawBranch(toX,toY,branchLen,branchWidth-1,angle-30,depth);
}
}
運(yùn)行代碼:
由于樹之間角度過大,而且所有樹枝長(zhǎng)度都相等,看起來并不像一棵樹。所以我們需要在Tree的構(gòu)造函數(shù)中加入幾個(gè)參數(shù)用來調(diào)整樹的姿態(tài)。
function Tree(x,y,branchLen,branchWidth,depth,canvas){
......
this.branchLenFactor = 0.8;
this.rootLenFactor = 1.2;
this.branchAngle = 20;
......
}
branchLenFactor:畫每一層樹枝的時(shí)候乘在branchLen上面,用來控制樹枝長(zhǎng)度。rootLenFactor:畫樹根的時(shí)候乘在branchLen上面,用來控制樹根長(zhǎng)度。branchAngle: 用來控制樹枝之間的角度
Tree.prototype.drawRoot = function(x,y,branchLen,branchWidth,depth){
var toX = x;
var toY = y-branchLen*this.rootLenFactor;
var depth = depth||5;
this.ctx.save();
this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
this.ctx.beginPath();
this.ctx.lineCap = "butt";
this.ctx.lineJoin="round";
this.ctx.lineWidth = branchWidth;
this.ctx.moveTo(x,y);
this.ctx.lineTo(toX,toY);
this.ctx.closePath();
this.ctx.stroke();
this.ctx.restore();
depth--;
if(depth0){
this.drawBranch(toX,toY,branchLen*this.branchLenFactor,branchWidth-1,this.branchAngle,depth);
this.drawBranch(toX,toY,branchLen*this.branchLenFactor,branchWidth-1,-this.branchAngle,depth);
}
}
Tree.prototype.drawBranch = function(x,y,branchLen,branchWidth,angle,depth){
var angle = angle || 0;
var radian = (90-angle)*(Math.PI/180);
var toX = x+Math.cos(radian)*branchLen;
var toY = y-Math.sin(radian)*branchLen;
this.ctx.save();
this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
this.ctx.beginPath();
this.ctx.lineCap = "butt";
this.ctx.lineJoin="round";
this.ctx.lineWidth = branchWidth;
this.ctx.moveTo(x,y);
this.ctx.lineTo(toX,toY);
this.ctx.closePath();
this.ctx.stroke();
this.ctx.restore();
depth--;
if(depth0){
this.drawBranch(toX,toY,branchLen*this.branchLenFactor,branchWidth-1,angle+this.branchAngle,depth);
this.drawBranch(toX,toY,branchLen*this.branchLenFactor,branchWidth-1,angle-this.branchAngle,depth);
}
}
運(yùn)行代碼:(查看效果)
用html5開發(fā)隨機(jī)生成的大樹,你應(yīng)該沒想到40+行代碼就可以搞定了吧~接下來就跟大家說說這棵大樹是如何在html5開發(fā)中實(shí)現(xiàn)的。
同樣必須要有html容器。新建Index.html,代碼如下:
、html
1 、head
2 、meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /
3 、titlecanvas tree
4 、/head
5 、body
6 、script type="text/javascript" src="tree.js"
7 、/body
8 、/html
接下來咱們開始tree.js:
、var canvas = document.createElement("canvas");
9 var ctx = canvas.getContext("2d");
10 canvas.width = 640;
11 canvas.height = 480;
12 document.body.appendChild(canvas);
代碼很好理解,創(chuàng)建一個(gè)canvas畫布,然后選擇為2d畫布,設(shè)置長(zhǎng)寬,最后將這個(gè)畫布添加到body標(biāo)簽下。
這個(gè)腳本最重要的函數(shù)在下面,大樹就是遞歸調(diào)用這個(gè)函數(shù)實(shí)現(xiàn)的,調(diào)用一次畫一條線段:
var drawTree = function (ctx, startX, startY, length, angle, depth, branchWidth){
13 var rand = Math.random,
14 newLength, newAngle, newDepth, maxBranch = 3,
15 endX, endY, maxAngle = 2 * Math.PI / 4,
16 subBraches;
17 ctx.beginPath();
18 ctx.moveTo(startX, startY);
19 endX = startX + length * Math.cos(angle);
20 endY = startY + length * Math.sin(angle);
21 ctx.lineCap = 'round';
22 ctx.lineWidth = branchWidth;
23 ctx.lineTo(endX, endY);
24 if (depth = 2){
25 ctx.strokeStyle = 'rgb(0,' + (((rand() * 64) + 128) 0) + ',0)';
26 } else {
27 ctx.strokeStyle = 'rgb(' + (((rand() * 64) + 64) 0) + ',50,25)';
28 }
29 ctx.stroke();
30 newDepth = depth - 1;
31 if (!newDepth)
32 return;
33 subBranches = (rand() * (maxBranch - 1)) + 1;
34 branchWidth *= 0.7;
35 for (var i = 0; i subBranches; i++){
36 newAngle = angle + rand() * maxAngle - maxAngle * 0.5;
37 newLength = length * (0.7 + rand() * 0.3);
38 drawTree(ctx, endX, endY, newLength, newAngle, newDepth, branchWidth);
39 }
40 }
接下來一點(diǎn)點(diǎn)解釋:
首先,解釋下各個(gè)變量的含義。ctx就是前面我們的2d畫布;startX是線段開始的橫坐標(biāo),同理startY是縱坐標(biāo);length是線段長(zhǎng)度;angle是角度;depth是深度,葉子深度為1,樹干為12(可自己設(shè)定);branchWidth就線段的粗細(xì)。有了這些信息,其實(shí)就描述了一個(gè)線段,通過這些信息我們才能畫一個(gè)線段。
接下來又很可恥地一大段定義:
var rand = Math.random,
41 newLength, newAngle, newDepth, maxBranch = 3,
42 endX, endY, maxAngle = 2 * Math.PI / 4,
43 subBraches;
rand其實(shí)就是隨機(jī)一個(gè)0~1之間的實(shí)數(shù),顧名思義,接下來這些new的就是下一節(jié)線段的各種參數(shù)。maxBranch就是最多有3個(gè)分叉,最大的角度 PI/2 即為,下一級(jí)調(diào)整角度在90%范圍內(nèi)。subBranches就是分叉的個(gè)數(shù)。
好了,重要可以畫了:
ctx.beginPath();
44 ctx.moveTo(startX, startY);
45 endX = startX + length * Math.cos(angle);
46 endY = startY + length * Math.sin(angle);
47 ctx.lineCap = 'round';
48 ctx.lineWidth = branchWidth;
49 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)。
if (depth = 2){
50 ctx.strokeStyle = 'rgb(0,' + (((rand() * 64) + 128) 0) + ',0)';
51 } else {
52 ctx.strokeStyle = 'rgb(' + (((rand() * 64) + 64) 0) + ',50,25)';
53 }
如果是已經(jīng)畫到了最后兩級(jí),即為葉子,那么就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)手畫!
ctx.stroke();
這個(gè)線段就畫好了,是時(shí)候準(zhǔn)備下它的分叉的時(shí)候了。
newDepth = depth - 1;
54 if (!newDepth)
55 return;
如果這個(gè)線段是最后一級(jí),就沒有分叉了,也是一個(gè)遞歸的終止條件。
subBranches = (rand() * (maxBranch - 1)) + 1;
56 branchWidth *= 0.7;
57 for (var i = 0; i subBranches; i++){
58 newAngle = angle + rand() * maxAngle - maxAngle * 0.5;
59 newLength = length * (0.7 + rand() * 0.3);
60 drawTree(ctx, endX, endY, newLength, newAngle, newDepth, branchWidth);
61 }
分叉數(shù)是1~3中的一個(gè)數(shù)。然后有多少個(gè)分叉,就畫幾條線段,newAngle為原角度調(diào)整90度之內(nèi),新長(zhǎng)度為原長(zhǎng)度的0.7~1.0之間。
最后畫出主干,這棵樹就可以開始畫了。
drawTree(ctx, 320, 470, 60, -Math.PI / 2, 12, 12);
大家可能注意到角度為負(fù),不符合傳統(tǒng)觀念。但你要知道,畫布的縱坐標(biāo)和傳統(tǒng)的坐標(biāo)軸正好是相反的。
好了,html5開發(fā)隨機(jī)生成的大樹代碼就這樣完成了,怎么樣,一點(diǎn)都難吧!
網(wǎng)站題目:html5樹,html畫樹
標(biāo)題鏈接:http://chinadenli.net/article19/dsespgh.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)、網(wǎng)站改版、定制網(wǎng)站、網(wǎng)站設(shè)計(jì)公司、品牌網(wǎng)站建設(shè)、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)