分形是通过重复数学方程式创建的无尽图案。我们将使用纯 JS 和 HTML5 Canvas API 绘制一个最著名的分形。分形是通过重复数学方程式创建的无尽图案。我们将使用纯 JS 和 HTML5 Canvas API 绘制一个最著名的分形。

使用JavaScript和HTML5编码分形树

\ 分形,那些神秘的图形,它们无处不在,但未经训练的眼睛却看不见。今天我们将使用纯 JavaScript 和 HTML5 Canvas API 绘制一个最著名的分形。让我们开始编码吧!

你将学到什么

  • 什么是分形树?
  • 用纯 JavaScript 编写分形树
  • 超越分形树

什么是分形树?

要定义分形树,首先,我们当然必须知道分形的定义。

分形是通过重复数学方程创建的无尽图案,在任何尺度、任何缩放级别上,看起来大致相同。换句话说,一个几何对象,其基本结构,粗糙或碎片化,在不同尺度上重复自身。

所以如果我们分割一个分形,我们会看到整体的缩小版本。

创造"分形"一词的贝努瓦·曼德布罗特在1975年说:

\

\ 很清楚,对吧?

这里有一些例子:

动画冯·科赫曲线

\ 动画谢尔宾斯基地毯

现在,什么是分形树?

想象一个分支,然后从它延伸出分支,然后每个分支又延伸出两个分支,如此继续……这就是分形树的样子。

它的形式来源于谢尔宾斯基三角形(或谢尔宾斯基垫片)。

如你所见,当改变分支之间的角度时,一个变成了另一个:

从谢尔宾斯基三角形到分形

今天,我们将得到一个类似于该 GIF 最终形态的图形。

用纯 JavaScript 编写分形树

首先,这是最终成品(你可以在过程中调整它):

最终分形树

现在让我们一步步地绘制它。

首先,我们用一个合理尺寸的画布和一个包含所有 JS 代码的脚本标签初始化我们的 index.html 文件。

<!doctype html> <html lang="en">   <head>     <meta charset="UTF-8" />   </head>   <body>     <canvas id="my_canvas" width="1000" height="800"></canvas>     <script></script>   </body> </html> 

然后,我们开始编写 JavaScript。

我们通过 myCanvas 变量访问画布元素,并用 ctx(上下文)变量创建 2D 渲染上下文,从而在 JS 中初始化我们的画布元素。

<!doctype html> <html lang="en">   <head>     <meta charset="UTF-8" />   </head>   <body>     <canvas id="my_canvas" width="1000" height="800"></canvas>     <script>       var myCanvas = document.getElementById("my_canvas");       var ctx = myCanvas.getContext("2d");     </script>   </body> </html> 

是的,getContext 方法添加了允许你绘图的属性和方法,在这种情况下是 2D 绘图。

现在是时候思考了。我们如何定义绘制分形树的算法呢?嗯... 🤔

让我们看看,我们知道分支会变得越来越小。而且每个分支末端都会有两个分支延伸出来,一个向左,一个向右。

换句话说,当一个分支足够长时,在它上面附加两个更小的分支。重复这个过程。

这听起来好像我们应该在某处使用递归语句,不是吗?

回到代码,我们现在定义我们的函数 fractalTree,它应该至少接受四个参数:分支起始的 X 和 Y 坐标,分支的长度,以及它的角度。

在我们的函数内部,我们用 beginPath() 方法开始绘图,然后用 save() 方法保存画布的状态。

<!doctype html> <html lang="en">   <head>     <meta charset="UTF-8" />   </head>   <body>     <canvas id="my_canvas" width="1000" height="800"></canvas>     <script>       var myCanvas = document.getElementById("my_canvas");       var ctx = myCanvas.getContext("2d");       function draw(startX, startY, len, angle) {           ctx.beginPath();           ctx.save();       }     </script>   </body> </html> 

beginPath 方法通常在你开始一个具有固定样式的新线条或图形时使用,比如整条线具有相同的颜色,或相同的宽度。save 方法通过将当前状态推入堆栈来保存画布的整个状态。

现在我们将通过绘制一条线(分支),旋转画布,绘制下一个分支,依此类推来绘制我们的分形树。它是这样的(我将在代码示例下面解释每个方法):

<!doctype html> <html lang="en">   <head>     <meta charset="UTF-8" />   </head>   <body>     <canvas id="my_canvas" width="1000" height="800"></canvas>     <script>       var myCanvas = document.getElementById("my_canvas");       var ctx = myCanvas.getContext("2d");       function draw(startX, startY, len, angle) {           ctx.beginPath();           ctx.save();            ctx.translate(startX, startY);           ctx.rotate(angle * Math.PI/180);           ctx.moveTo(0, 0);           ctx.lineTo(0, -len);           ctx.stroke();            if(len < 10) {               ctx.restore();               return;           }            draw(0, -len, len*0.8, -15);           draw(0, -len, len*0.8, +15);            ctx.restore();       }       draw(400, 600, 120, 0)     </script>   </body> </html> 

所以我们首先添加三个方法,translate、rotate 和 moveTo,它们"移动"画布、它的原点和我们的"铅笔",这样我们就可以以我们想要的角度绘制分支。就像我们在绘制一个分支,然后居中这个分支(通过移动整个画布),然后从我们前一个分支的末端绘制一个新分支。

if 语句之前的最后两个方法是 lineTo 和 stroke;第一个向当前路径添加一条直线,第二个渲染它。你可以这样想:lineTo 下达命令,stroke 执行它。

现在我们有一个 if 语句,它告诉何时停止递归,何时停止绘制。restore 方法,正如 MDN 文档中所述,"通过弹出绘图状态堆栈中的顶部条目来恢复最近保存的画布状态"。

在 if 语句之后,我们有递归调用和另一个对 restore 方法的调用。然后是对我们刚刚完成的函数的调用。

现在在你的浏览器中运行代码。你最终会看到一棵分形树!

分形树第一次迭代

很棒,对吧?现在让我们让它变得更好。

我们将向我们的 draw 函数添加一个新参数,branchWidth,使我们的分形树更加逼真。

<!doctype html> <html lang="en">   <head>     <meta charset="UTF-8" />   </head>   <body>     <canvas id="my_canvas" width="1000" height="800"></canvas>     <script>       var myCanvas = document.getElementById("my_canvas");       var ctx = myCanvas.getContext("2d");       function draw(startX, startY, len, angle, branchWidth) {           ctx.lineWidth = branchWidth;            ctx.beginPath();           ctx.save();            ctx.translate(startX, startY);           ctx.rotate(angle * Math.PI/180);           ctx.moveTo(0, 0);           ctx.lineTo(0, -len);           ctx.stroke();            if(len < 10) {               ctx.restore();               return;           }            draw(0, -len, len*0.8, angle-15, branchWidth*0.8);           draw(0, -len, len*0.8, angle+15, branchWidth*0.8);            ctx.restore();       }       draw(400, 600, 120, 0, 10)     </script>   </body> </html> 

所以在每次迭代中,我们都使每个分支变得更细。我还更改了递归调用中的角度参数,使树更"开放"。

现在,让我们添加一些颜色!还有阴影,为什么不呢。

<!doctype html> <html lang="en">   <head>     <meta charset="UTF-8" />   </head>   <body>     <canvas id="my_canvas" width="1000" height="800"></canvas>     <script>       var myCanvas = document.getElementById("my_canvas");       var ctx = myCanvas.getContext("2d");       function draw(startX, startY, len, angle, branchWidth) {           ctx.lineWidth = branchWidth;            ctx.beginPath();           ctx.save();            ctx.strokeStyle = "green";           ctx.fillStyle = "green";            ctx.translate(startX, startY);           ctx.rotate(angle * Math.PI/180);           ctx.moveTo(0, 0);           ctx.lineTo(0, -len);           ctx.stroke();            ctx.shadowBlur = 15;           ctx.shadowColor = "rgba(0,0,0,0.8)";            if(len < 10) {               ctx.restore();               return;           }            draw(0, -len, len*0.8, angle-15, branchWidth*0.8);           draw(0, -len, len*0.8, angle+15, branchWidth*0.8);            ctx.restore();       }       draw(400, 600, 120, 0, 10)     </script>   </body> </html> 

两种颜色方法都是不言自明的(strokeStyle 和 fillStyle)。还有阴影相关的,shadowBlur 和 shadowColor。

就是这样!保存文件并用浏览器打开它,查看最终产品。

现在我鼓励你玩转代码!改变 shadowColor,fillStyle,制作更短或更长的分形树,改变角度,或尝试添加叶子,这应该很有挑战性 😉

超越分形树

正如我在这篇文章开头所展示的,有不同的分形。用 Canvas API 制作所有这些可能不容易,但应该是可能的。我用 C 编程语言制作了其中一些,我也玩过 p5.js。

p5.js 是一个由艺术家为艺术家制作的开源 JavaScript 库,基于 Processing 语言。你可以绘制或动画任何可以想象的东西。如果你对用代码创作艺术感兴趣,这是必不可少的。他们有一个很棒

市场机遇
Treehouse 图标
Treehouse实时价格 (TREE)
$0.1079
$0.1079$0.1079
-2.08%
USD
Treehouse (TREE) 实时价格图表
免责声明: 本网站转载的文章均来源于公开平台,仅供参考。这些文章不代表 MEXC 的观点或意见。所有版权归原作者所有。如果您认为任何转载文章侵犯了第三方权利,请联系 service@support.mexc.com 以便将其删除。MEXC 不对转载文章的及时性、准确性或完整性作出任何陈述或保证,并且不对基于此类内容所采取的任何行动或决定承担责任。转载材料仅供参考,不构成任何商业、金融、法律和/或税务决策的建议、认可或依据。

您可能也会喜欢

长路说币:12.17以太坊进入区间震荡期,未来走势该何去何从?

长路说币:12.17以太坊进入区间震荡期,未来走势该何去何从?

长路说币:12.17以太坊进入区间震荡期,未来走势该何去何从?
分享
Jinsehot2025/12/17 12:36
另一家纳斯达克上市公司宣布大规模购买比特币(BTC)!成为第14大公司!- 他们还将投资与特朗普相关的山寨币!

另一家纳斯达克上市公司宣布大规模购买比特币(BTC)!成为第14大公司!- 他们还将投资与特朗普相关的山寨币!

另一家纳斯达克上市公司宣布大规模购买比特币(BTC)!成为第14大公司!- 他们还将投资与特朗普相关的山寨币!这篇文章发表在BitcoinEthereumNews.com上。随着持有比特币(BTC)国库的公司数量日益增加,另一家纳斯达克上市公司宣布购买BTC。据此,直播和电子商务公司GD Culture Group宣布达成7.875亿美元的比特币购买协议。根据官方声明,GD Culture Group宣布他们已与注册在英属维尔京群岛的Pallas Capital Holding签订股权协议,收购价值8.75亿美元的资产,包括7,500个比特币。GD Culture将发行约3,920万股普通股,以换取Pallas Capital的所有资产,包括价值8.754亿美元的比特币。GD Culture首席执行官王晓健表示,这项收购交易将直接支持公司建立强大且多元化的加密资产储备的计划,同时利用比特币作为储备资产和价值存储的机构接受度不断提高的优势。通过此次收购,GD Culture预计将成为第14大公开交易的比特币持有公司。采用比特币国库策略的公司数量显著增加,到2025年将超过190家。在宣布交易后,GD Culture股价立即下跌28.16%至6.99美元,创下一年来最大跌幅。您可能还记得,GD Culture在5月份宣布将创建一个加密货币储备。在这一点上,该公司宣布他们计划通过发行高达3亿美元的股票来投资比特币和唐纳德·特朗普总统的官方迷因币TRUMP代币。*这不是投资建议。立即关注我们的Telegram和Twitter账户,获取独家新闻、分析和链上数据!来源:https://en.bitcoinsistemi.com/another-nasdaq-listed-company-announces-massive-bitcoin-btc-purchase-becomes-14th-largest-company-theyll-also-invest-in-trump-linked-altcoin/
分享
BitcoinEthereumNews2025/09/18 04:06
币安将于12月17日进行系统升级及UTF-8编码测试,不影响正常交易

币安将于12月17日进行系统升级及UTF-8编码测试,不影响正常交易

深潮 TechFlow 消息,12 月 17 日,据官方公告,币安宣布将于12月17日对现货交易平台进行系统升级及UTF-8编码测试。官方强调,本次升级不会影响现货交易或任何相关功能。测试期间,用户可能会看到一些测试代币和测试交易对出现,这属于正常测试现象。币安特别提醒用户,任何链上创建的、名称相同或相似的代币均非币安
分享
Tech Flow2025/12/17 12:07