离谱!产品要求我用 JavaScript 画一颗【随机树】!

开发 前端
产品要的是一颗随机树,也就是树的茂盛程度、长度、枝干粗细都是随机的,那这确实没办法叫 UI 给图,毕竟 UI 不可能给我 10000 张树的图片吧?

用 JavaScript 画一棵树?

产品说要让前端用 JavaScript 画一棵树出来,但是这难道不能直接让 UI 给一张图片吗?

图片图片

后来一问才知道,产品要的是一颗随机树,也就是树的茂盛程度、长度、枝干粗细都是随机的,那这确实没办法叫 UI 给图,毕竟 UI 不可能给我 10000 张树的图片吧?

Canvas 画一颗随机树

接下来使用 Canvas 去画这棵随机树。

基础页面

我们需要在页面上写一个 canvas 标签,并设置好宽高,同时需要获取它的 Dom 节点、绘制上下文,以便后续的绘制。

图片图片

坐标调整

默认的 Canvas 坐标系是这样的。

图片图片

但是我们现在需要从中间去向上去画一棵树,所以坐标得调整成这样:

  • X 轴从最上面移动到最下面。
  • Y 轴的方向由往下调整成往上,并且从最左边移动到画布中间。

图片图片

这些操作可以使用 Canvas 的方法:

  • ctx.translate: 坐标系移动。
  • ctx.scale: 坐标系缩放。

图片图片

绘制一棵树的要素

绘制一棵树的要素是什么呢?其实就是树枝和果实,但是其实树枝才是第一要素,那么树枝又有哪些要素呢?无非就这几个点:

  • 起始点
  • 树枝长度、树枝粗细
  • 生长角度
  • 终点

开始绘制

所以我们可以写一个 drawBranch 来进行绘制,并且初始调用肯定是绘制树干,树干的参数如下:

  • 起始点:(0, 0)
  • 树枝长度、树枝粗细:这些可以自己自定义
  • 生长角度:90度
  • 终点:需要算

图片图片

这个终点应该怎么算呢?其实很简单,根据树枝长度、生长角度就可以算出来了,这是初高中的知识

图片图片

于是我们可以使用 Canvas 的绘制方法,去绘制线段,其实树枝就是一个一个的线段:

图片图片

到现在我绘制出了一个树干出来:

图片图片

但是我们是想让这棵树开枝散叶,所以需要继续递归继续去绘制更多的树枝出来。

递归绘制

其实往哪开枝散叶呢?无非就是往左或者往右。

图片图片

所以需要递归画左边和右边的树枝,并且子树枝肯定要比父树枝更短、比父树枝更细,比如我们可以定义一个比例:

  • 子树枝是父树枝长度的 0.8。
  • 子树枝是父树枝粗细的 0.75。

而子树枝的生长角度,其实可以随机,我们可以在 0° - 30° 之间随机选一个角度,于是增加了递归调用的代码:

图片图片

但是这个时候会发现,报错了,爆栈了,因为我们只递归开始,但却没有在某个时刻递归停止。

图片图片

我们可以自己定义一个停止规则(规则可以自己定义,这会决定你这棵树的茂盛程度):

  • 粗细小于 2 时马上停止
  • (粗细小于 10 时 + 随机数)决定是否停止

图片

现在可以看到我们已经大致绘制出一棵树了。

图片图片

不过还少了树的果实。

绘制果实

绘制果实很简单,只需要在绘制树枝结束的时候,去把果实绘制出来就行,其实果实就是一个个的白色实心圆:

图片图片

至此这棵树完整绘制完毕。

图片图片

绘制部分的代码如下:

图片 图片

责任编辑:武晓燕 来源: 前端之神
相关推荐

2021-05-12 19:19:44

字典树数据结构

2021-12-24 11:58:20

Shell脚本圣诞树编程语言

2017-02-24 19:32:39

微博数据Python

2017-02-23 10:50:32

Python微博数据

2020-06-30 15:38:17

戴尔

2009-06-10 18:15:36

电脑下乡家电下乡

2022-12-27 14:29:37

javascript动画

2013-09-29 11:08:10

Bay Trail平板电脑

2022-08-26 12:13:40

黑客网络攻击

2010-07-30 15:58:18

2009-04-21 18:04:04

双核Nehalemintel

2021-06-30 13:20:05

Windows 11芯片PC

2013-04-16 13:57:36

2014-07-30 16:19:13

敏捷华为

2021-03-15 14:17:38

射频芯片5G手机信号

2022-11-01 12:30:11

机器学习解码系统

2015-01-12 11:07:22

2015-05-18 16:12:32

信息化转型油气行业华为

2021-08-13 08:19:31

状态机设计模式

2021-01-21 21:14:53

人工智能AIOpenAI
点赞
收藏

51CTO技术栈公众号