Cavas应用之生成随机“树”

本文详细介绍了如何利用HTML5的CanvasAPI和JavaScript实现随机树的生成,涉及递归、动画绘制和存储绘制命令等技术,展示了从HTML结构、CSS样式到JavaScript逻辑的完整过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开篇

本文旨在使用cavas实现一棵随机“树”。功能并不复杂,单纯是考验对cavas的应用。

效果展示

使用cavas生成随机“树”

效果展示图片

思路分析

生成树的关键点只有以下几个:

  1. 生成树干
  2. 在树干的基础上生成树枝(此处应该使用递归的方式生成树干,但要注意对退出条件的判定)
  3. 要逐步生成树枝,需要使用animate,并控制绘制命令的执行

代码实现

HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>
  <canvas></canvas>
  <script src="./script.js"></script>
</body>
</html>

CSS文件

*,
html {
  margin: 0;
  padding: 0;
}

body {
  max-height: 100%;
  width: 100%;
}

canvas {
  height: 70vh;
  width: 100%;
  background-color: lightgoldenrodyellow;
}

js文件

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth * devicePixelRatio;
canvas.height = window.innerHeight * devicePixelRatio;

// 跳转坐标原点至页面底部中间的位置
ctx.translate(canvas.width / 2, canvas.height);
ctx.scale(1, -1);

// 存储绘制命令而不是立即执行它们
let drawCommands = [];

function drawBranch(v0, length, thick, dir) {
  if (thick < 10 && Math.random() < 0.3) {
    return;
  }

  // 将函数和参数添加到命令列表中而不是立即执行
  drawCommands.push({ fn: 'line', v0: v0, length: length, thick: thick, dir: dir });

  if (thick < 2) {
    // 生成花朵的绘制命令
    drawCommands.push({ fn: 'flower', v0: v0 });
    return;
  }

  const v1 = [
    v0[0] + length * Math.cos((dir * Math.PI) / 180),
    v0[1] + length * Math.sin((dir * Math.PI) / 180)
  ];

  // 递归调用绘制树枝的命令
  drawBranch(v1, length * 0.8, thick * 0.8, dir + Math.random() * 30);
  drawBranch(v1, length * 0.8, thick * 0.8, dir - Math.random() * 30);
}

// 执行绘制命令
function executeCommand(command) {
  if (command.fn === 'line') {
    ctx.beginPath();
    ctx.moveTo(...command.v0);
    const v1 = [
      command.v0[0] + command.length * Math.cos((command.dir * Math.PI) / 180),
      command.v0[1] + command.length * Math.sin((command.dir * Math.PI) / 180)
    ];
    ctx.lineTo(...v1);
    ctx.lineWidth = command.thick;
    ctx.strokeStyle = '#333';
    ctx.lineCap = 'round';
    ctx.stroke();
  } else if (command.fn === 'flower') {
    ctx.beginPath();
    ctx.arc(...command.v0, 10, 0, 2 * Math.PI);
    ctx.fillStyle = 'pink';
    ctx.fill();
  }
}

// 动画绘制
function animate() {
  // 如果有待执行的命令,则执行一个并请求下一帧
  if (drawCommands.length > 0) {
    executeCommand(drawCommands.shift());
    requestAnimationFrame(animate);
  }
}

// 开始绘制树干,这将填充绘制命令数组
drawBranch([0, 0], 200, 30, 90);

// 开始动画
animate();

上面便是使用cavas实现随机树的全部逻辑,希望对您有所帮助。
感谢阅读w

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值