返回

用JS绘制雨滴,重现美妙的雨景

前端

JavaScript绘制雨滴

大家好,今天我们将一起用JavaScript和canvas来绘制动态的雨滴,并实现使雨滴爆炸的动画效果。

1. 画布设置

首先,我们需要创建一个画布并使用JavaScript来控制它。以下是如何在HTML中创建画布:

<canvas id="canvas"></canvas>

接下来,我们需要使用JavaScript来获取canvas元素并设置其属性。这里有一个简单的示例:

const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

2. 绘制雨滴

现在我们可以开始绘制雨滴了。以下是绘制单个雨滴的步骤:

  1. 创建一个新的路径。
  2. 将画笔移动到雨滴的顶部。
  3. 使用画笔绘制雨滴的形状。
  4. 闭合路径。
  5. 填充雨滴的颜色。

以下是如何用JavaScript来实现这些步骤的:

function drawRaindrop(x, y) {
  context.beginPath();
  context.moveTo(x, y);
  context.lineTo(x + 5, y + 10);
  context.lineTo(x + 10, y);
  context.closePath();
  context.fillStyle = '#000';
  context.fill();
}

3. 雨滴动画

接下来,我们需要让雨滴动起来。我们可以使用JavaScript的setInterval()方法来实现这一点。该方法会每隔一段时间调用一个函数,我们可以用它来不断更新雨滴的位置。以下是如何实现的:

setInterval(() => {
  // 清空画布
  context.clearRect(0, 0, canvas.width, canvas.height);

  // 绘制雨滴
  for (let i = 0; i < rainDrops.length; i++) {
    const raindrop = rainDrops[i];
    drawRaindrop(raindrop.x, raindrop.y);

    // 更新雨滴的位置
    raindrop.y += raindrop.speed;

    // 如果雨滴超出画布,则将其从数组中删除
    if (raindrop.y > canvas.height) {
      rainDrops.splice(i, 1);
    }
  }
}, 10);

4. 雨滴爆炸效果

最后,我们可以为雨滴添加爆炸效果。当雨滴与地面接触时,它会爆炸并溅起水花。以下是如何实现的:

function explodeRaindrop(raindrop) {
  // 创建一个新的路径
  context.beginPath();

  // 将画笔移动到雨滴的位置
  context.moveTo(raindrop.x, raindrop.y);

  // 绘制水花
  for (let i = 0; i < 10; i++) {
    const angle = Math.random() * Math.PI * 2;
    const distance = Math.random() * 10;

    const x = raindrop.x + Math.cos(angle) * distance;
    const y = raindrop.y + Math.sin(angle) * distance;

    context.lineTo(x, y);
  }

  // 闭合路径
  context.closePath();

  // 填充水花の色
  context.fillStyle = '#000';
  context.fill();
}

5. 完整代码

以下是如何将所有部分组合在一起的完整代码:

const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

const rainDrops = [];

function drawRaindrop(x, y) {
  context.beginPath();
  context.moveTo(x, y);
  context.lineTo(x + 5, y + 10);
  context.lineTo(x + 10, y);
  context.closePath();
  context.fillStyle = '#000';
  context.fill();
}

function explodeRaindrop(raindrop) {
  context.beginPath();
  context.moveTo(raindrop.x, raindrop.y);

  for (let i = 0; i < 10; i++) {
    const angle = Math.random() * Math.PI * 2;
    const distance = Math.random() * 10;

    const x = raindrop.x + Math.cos(angle) * distance;
    const y = raindrop.y + Math.sin(angle) * distance;

    context.lineTo(x, y);
  }

  context.closePath();
  context.fillStyle = '#000';
  context.fill();
}

setInterval(() => {
  context.clearRect(0, 0, canvas.width, canvas.height);

  for (let i = 0; i < rainDrops.length; i++) {
    const raindrop = rainDrops[i];
    drawRaindrop(raindrop.x, raindrop.y);

    raindrop.y += raindrop.speed;

    if (raindrop.y > canvas.height) {
      rainDrops.splice(i, 1);
      explodeRaindrop(raindrop);
    }
  }

  if (Math.random() < 0.05) {
    const x = Math.random() * canvas.width;
    const y = 0;
    const speed = Math.random() * 5 + 1;

    rainDrops.push({ x, y, speed });
  }
}, 10);

希望这篇文章对您有所帮助。如果您有任何问题,请随时留言。