javascript中的瀑布效果

问题描述 投票:0回答:1

我需要帮助来应用正在褪色的水效果,如下图所示。在图像中,白色颗粒逐渐褪色为蓝色模糊效果。这就是我正在努力实现的目标。

我相信通过快速模糊或单纯形噪声,我们应该能够实现这一目标,但不确定如何继续。

(点击放大)

Water fall

在 HTML5 画布中实现了带有碎片的瀑布。

CodePen 源码

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

// Set canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

const particles = [];
const splinters = [];
const gravity = 0.1; // Gravity constant
const fountainX = canvas.width / 2;
const fountainY = canvas.height / 2;

// Mouse position
let mouseX = fountainX;
let mouseY = fountainY;

// Particle class
class Particle {
  constructor(x, y, angle, isSplinter = false) {
    this.x = x;
    this.y = y;
    const speed = Math.random() * 3 + 2; // Random speed
    const spread = Math.random() * 0.4 - 0.2; // Randomize direction slightly
    this.vx = isSplinter ?
      (Math.random() * 2 - 1) * 3 :
      Math.cos(angle + spread) * speed;
    this.vy = isSplinter ?
      Math.random() * -3 :
      Math.sin(angle + spread) * speed;
    this.alpha = isSplinter ? 1 : 1; // Opacity
    this.radius = isSplinter ? Math.random() : Math.random() + 1; // Size
    this.isSplinter = isSplinter;
  }

  update() {
    this.x += this.vx;
    this.y += this.vy;
    this.vy += gravity; // Apply gravity
    this.alpha -= this.isSplinter ? 0.02 : 0.005; // Fade out

    // Check if main particles reach the bottom of the canvas
    if (!this.isSplinter && this.y >= canvas.height) {
      this.createSplinters(); // Create splinters on impact
      this.alpha = 0; // Make particle invisible
    }
  }

  createSplinters() {
    for (let i = 0; i < 10; i++) {
      splinters.push(new Particle(this.x, canvas.height, 0, true));
    }
  }

  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
    ctx.fillStyle = `hsla(199, 100%, 67%, ${this.alpha})`; // Blue shade with opacity
    ctx.fill();
  }

  isAlive() {
    return this.alpha > 0; // Check if particle is still visible
  }
}

// Create particles over time
function emitParticles() {
  const angle = Math.atan2(mouseY - fountainY, mouseX - fountainX);
  for (let i = 0; i < 5; i++) { // Emit a few particles per frame
    particles.push(new Particle(fountainX, fountainY, angle));
  }
}

// Animation loop
function animate() {
  ctx.fillStyle = 'rgba(0, 0, 0, 0.2)'; // Trail effect
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  emitParticles(); // Emit new particles continuously

  // Update and draw particles
  particles.forEach((particle, index) => {
    particle.update();
    if (!particle.isAlive()) {
      particles.splice(index, 1); // Remove dead particles
    } else {
      particle.draw();
    }
  });

  // Update and draw splinters
  splinters.forEach((splinter, index) => {
    splinter.update();
    if (!splinter.isAlive()) {
      splinters.splice(index, 1); // Remove dead splinters
    } else {
      splinter.draw();
    }
  });

  requestAnimationFrame(animate);
}

// Update mouse position on move
canvas.addEventListener('mousemove', (event) => {
  mouseX = event.clientX;
  mouseY = event.clientY;
});

// Initialize animation
animate();
canvas {
  display: block;
  margin: 0 auto;
  background: #000;
  /* Black background */
}
<canvas id="fountainCanvas"></canvas>

javascript html5-canvas effect
1个回答
0
投票

// script.js

const container = document.getElementById("waterfall-container");

function createFallingElement() {
    // Create a new div element
    const waterfallItem = document.createElement("div");
    waterfallItem.classList.add("waterfall-item");

    // Set a random horizontal position
    const randomX = Math.random() * window.innerWidth;
    waterfallItem.style.left = `${randomX}px`;

    // Append the element to the container
    container.appendChild(waterfallItem);

    // Remove the element after animation ends to avoid clutter
    waterfallItem.addEventListener("animationend", () => {
        container.removeChild(waterfallItem);
    });
}

// Create new falling elements every 200ms
setInterval(createFallingElement, 200);

© www.soinside.com 2019 - 2024. All rights reserved.