上图就是用html5随机生成的大树 : ) 但是你应该没想到40+行代码就可以搞定了吧~接下来就跟大家说说这棵大树是如何实现的。

同样必须要有html容器。新建Index.html,代码如下:

canvas tree

接下来咱们开始tree.js:

varcanvas=document.createElement("canvas");

varctx=canvas.getContext("2d");

canvas.width=640;

canvas.height=480;

document.body.appendChild(canvas);

代码很好理解,创建一个canvas画布,然后选择为2d画布,设置长宽,***将这个画布添加到body标签下。

这个脚本最重要的函数在下面,大树就是递归调用这个函数实现的,调用一次画一条线段:

vardrawTree=function(ctx, startX, startY, length, angle, depth, branchWidth){

varrand=Math.random,

newLength, newAngle, newDepth,maxBranch=3,

endX, endY,maxAngle=2* Math.PI / 4,

subBraches;

ctx.beginPath();

ctx.moveTo(startX, startY);

endX=startX+ length * Math.cos(angle);

endY=startY+ length * Math.sin(angle);

ctx.lineCap='round';

ctx.lineWidth=branchWidth;

ctx.lineTo(endX, endY);

if (depth<= 2){

ctx.strokeStyle='rgb(0,'+ (((rand() * 64) + 128)>>0) + ',0)';

} else {

ctx.strokeStyle='rgb('+ (((rand() * 64) + 64)>>0) + ',50,25)';

}

ctx.stroke();

newDepth=depth- 1;

if (!newDepth)

return;

subBranches= (rand() * (maxBranch - 1)) + 1;

branchWidth *= 0.7;

for (vari=0; i

newAngle=angle+ rand() * maxAngle - maxAngle * 0.5;

newLength=length* (0.7 + rand() * 0.3);

drawTree(ctx, endX, endY, newLength, newAngle, newDepth, branchWidth);

}

}

接下来一点点解释:

首先,解释下各个变量的含义。ctx就是前面我们的2d画布;startX是线段开始的横坐标,同理startY是纵坐标;length是线段长度;angle是角度;depth是深度,叶子深度为1,树干为12(可自己设定);branchWidth就线段的粗细。有了这些信息,其实就描述了一个线段,通过这些信息我们才能画一个线段。

接下来又很可耻地一大段定义:

varrand=Math.random,

newLength, newAngle, newDepth,maxBranch=3,

endX, endY,maxAngle=2* Math.PI / 4,

subBraches;

rand其实就是随机一个0~1之间的实数,顾名思义,接下来这些new的就是下一节线段的各种参数。maxBranch就是最多有3个分叉,***的角度 PI/2 即为,下一级调整角度在90%范围内。subBranches就是分叉的个数。

好了,重要可以画了:

ctx.beginPath();

ctx.moveTo(startX, startY);

endX=startX+ length * Math.cos(angle);

endY=startY+ length * Math.sin(angle);

ctx.lineCap='round';

ctx.lineWidth=branchWidth;

ctx.lineTo(endX, endY);

beginPath()表示告诉浏览器“我要开始画了!”,把之前的记录放弃了,这点有点像ps。moveTo()把光标移动到(startX, startY),再计算终点坐标,endX,endY,有点像高中学的参数方程。然后告诉浏览器,lineCap要round,线段的两头要是圆形的。有多粗呢?等于branchWidth。线段一直画到(endX, endY)。

if (depth<= 2){

ctx.strokeStyle='rgb(0,'+ (((rand() * 64) + 128)>>0) + ',0)';

} else {

ctx.strokeStyle='rgb('+ (((rand() * 64) + 64)>>0) + ',50,25)';

}

如果是已经画到了***两级,即为叶子,那么就rgb就为(0, 128~192, 0)(rgb代表颜色,分别为红绿蓝,red green blue)。还没的话,就在(64~128, 50 ,25)中取。大家可能发现了,rgb必须为整数,但是rand()只能rand实数。大家其实也注意到了有个” >>  0″,js当中表示位运算,整体向右移动n位,0就是移动0位。其实它的作用和Math.floor()一样,但是速度更快。

动手画!

ctx.stroke();

这个线段就画好了,是时候准备下它的分叉的时候了。

newDepth=depth- 1;

if (!newDepth)

return;

如果这个线段是***一级,就没有分叉了,也是一个递归的终止条件。

subBranches= (rand() * (maxBranch - 1)) + 1;

branchWidth *= 0.7;

for (vari=0; i

newAngle=angle+ rand() * maxAngle - maxAngle * 0.5;

newLength=length* (0.7 + rand() * 0.3);

drawTree(ctx, endX, endY, newLength, newAngle, newDepth, branchWidth);

}

分叉数是1~3中的一个数。然后有多少个分叉,就画几条线段,newAngle为原角度调整90度之内,新长度为原长度的0.7~1.0之间。

***画出主干,这棵树就可以开始画了。

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

大家可能注意到角度为负,不符合传统观念。但你要知道,画布的纵坐标和传统的坐标轴正好是相反的。

剩下可以发挥的东西还很多,比如大家可以调整各种参数,使树的颜色、大小变化,或者用这种方法去做些其他的事~

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

【编辑推荐】

【责任编辑:张伟 TEL:(010)68476606】

点赞 0

html如何绘制树结构图,HTML 5 Canvas 递归画树相关推荐

  1. php递归实现层级树状展开,PHP递归实现层级树状展开,php递归层级树状_PHP教程...

    PHP递归实现层级树状展开,php递归层级树状 本文实例为大家分享了PHP递归实现层级树状展开的主要代码,供大家参考,具体内容如下 效果图: 实现代码: $arr['id'], 'fid' => ...

  2. HTML菊花图案绘制,用HTML5中的canvas元素画菊花

    用html5中的canvas画出的三种菊花,书上看到的例子,拿来当联系玩. 使用Canvas元素绘制美丽的花朵 var context; var A,n; function btn_onclick() ...

  3. python绘制立体扇形_认识canvas(画扇形 动态画圆弧(requestAnimationFrame结合settimeout做的动画)、画表盘)...

    最近做的两个项目都是关于canvas的,做完整理一下,方便下一次使用,在vue里写的小demo, 功能:画扇形 动态画圆弧(requestAnimationFrame结合settimeout做的动画) ...

  4. 递归画树(Qt实现)

    1.       问题描述 用递归算法绘制一棵树 2.       解决思路 用二叉树的数据结构来描述树的结构,首先创建一个二叉树,创建时要初始化节点的一些信息,伪代码如下: If  current ...

  5. java非递归遍历file树_Java语言实现非递归实现树的前中后序遍历总结

    前言 三种遍历的递归写法都很好写,所以总结一下非递归写法. 先贴一张图复习一下三种遍历方式就进入正文啦~ [注:本文所有代码实现中树的结点定义如下: public class Node { int v ...

  6. canvas 画点_css+canvas 随便画一个星空

    今天躺在床上刷抖音的时候,看见了一个马克笔随便画星空的视频,很有意思. 先看效果: 开始需求分析: 1.渐变色的背景 2.画一颗树和一些草 3.水面的倒影 4.随便画点星星 5.画一颗流星 1.渐变色 ...

  7. c语言括号表示法画树怎么画,树的画法分类讲解

    先看看树叶的分类,大概分为:点叶.针叶.双勾夹叶等,这些都是根据树叶的外型概括而形成. 1.点叶 在画点叶时,我们用笔接近于书法的三点水.直点.斜点等写法,绘画是要注意区分干湿.浓淡,一般有介字.个字 ...

  8. java绘制(可视化)树结构图

    以JPanel组件为画板,继承JPanel类并重写paint(Graphics g)函数,在函数中使用画笔g绘制树结构图. 实例代码--3个java源文件:Main.java.DrawNode.jav ...

  9. python绘制基因结构图_从 gff 到 gggenes 绘制基因结构图

    gffutils 是一个用来解析 gff 文件的 Python 包,可以十分方便地获取 gff 文件中的相关信息.gggenes 是 ggplot2 的扩展包,用于绘制基因结构图.多物种基因比较图的很 ...

  10. python自动轨迹绘制七边形_前端系列——canvas实现按住鼠标移动绘制出轨迹

    概要 工作以来,写过vue.react.正则.算法.小程序等知识,唯独没有写过canvas,因为实在不会啊! 2018年,给自己设定一个小目标:学会canvas,达到的效果是能用canvas实现一些c ...

最新文章

  1. python怎么重启内核_解决jupyter运行pyqt代码内核重启的问题
  2. Scala 递归学习的例子
  3. python能够做什么软件-Python能做什么
  4. Firefox 网络调试工具
  5. java pdf 水印_Java 在PDF中添加水印——文本/图片水印
  6. Oracle任务调度的高级选项
  7. DP(优化) UVALive 6073 Math Magic
  8. proe2001安装指南
  9. 书店售书最低价格问题
  10. 18张动图,向你展示难得一见的瞬间
  11. [C++] 哈希计数
  12. python宽度优先搜索算法并输出路径
  13. 堆区和方法区的小认识
  14. ie11 java8 nc_用命令卸载Win8 IE9/IE10/IE11浏览器
  15. js判断设备是PC端还是移动端
  16. 一个心理医生和一个心理不正常的小孩的冷笑话
  17. Crafted Item - 合成装备
  18. Android 点击空白位置并且隐藏软键盘
  19. 实验:树莓派通过网线连接笔记本实现网络共享
  20. Gradle报错:Could not find ××× ,‘dependencies.× .× ‘ for × must specify an absolute path but is ${env.

热门文章

  1. VM296:1 Uncaught SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse (anonymous)
  2. 3ds Max 实验十 熟悉材质编辑器
  3. vue+css实现选择框内打勾效果
  4. hosts文件位置在哪
  5. oracle建表复制表结构,ORACLE复制表结构
  6. MTK开发入门基础教程
  7. 关于收发邮件中的一些概念解释(收件人 抄送人 密送人 回复 回复全部)
  8. 如何使用Xcode的Targets来管理开发和生产版本的构建( 还不懂,复制过来后面再看)
  9. c语言编程解百马百瓦古题,java编程题90道.doc
  10. .net 对网络文件下载