我需要帮助来应用正在褪色的水效果,如下图所示。在图像中,白色颗粒逐渐褪色为蓝色模糊效果。这就是我正在努力实现的目标。
我相信通过快速模糊或单纯形噪声,我们应该能够实现这一目标,但不确定如何继续。
(点击放大)
在 HTML5 画布中实现了带有碎片的瀑布。
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>
// 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);