let width, height;
function resize() {
width = canvas.clientWidth;
height = canvas.clientHeight;
canvas.width = width * window.devicePixelRatio;
canvas.height = height * window.devicePixelRatio;
ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
}
window.addEventListener('resize', resize);
resize();
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*()_+-=[]{}|;:,./<>?';
const fontSize = 16;
const columns = Math.floor(width / fontSize);
const drops = Array(columns).fill(0);
const speeds = Array(columns).fill(0).map(() => Math.random() * 2 + 2); // Vary speed for viscosity
const viscosities = Array(columns).fill(0).map(() => Math.random() * 0.5 + 0.5); // Slow down factor
const splashes = [];
const ripples = [];
// For metallic chrome and green mercury
const greenGlow = 'rgba(0, 255, 100, 0.8)';
const chromeColor = 'rgba(200, 200, 200, 0.7)';
const bgImage = new Image();
bgImage.src = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4gPGxpbmVhckdyYWRpZW50IGlkPSJnIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj4gPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMCIvPiA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iIzAwMCIvPiA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAiLz4gPC9saW5lYXJHcmFkaWVudD4gPHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNnKSIvPiA8Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAzMzAwIiBzdHJva2Utd2lkdGg9IjIiLz4gPC9zdmc+'; // Simple distorted bg
function draw() {
ctx.globalAlpha = 0.05;
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, width, height);
ctx.globalAlpha = 1;
// Draw distorted background with ripples
ripples.forEach((ripple, i) => {
ctx.beginPath();
ctx.arc(ripple.x, ripple.y, ripple.radius, 0, Math.PI * 2);
ctx.strokeStyle = `rgba(0, 255, 100, ${ripple.alpha})`;
ctx.lineWidth = 2;
ctx.stroke();
ripple.radius += 1;
ripple.alpha -= 0.01;
if (ripple.alpha <= 0) ripples.splice(i, 1);
});
ctx.font = `${fontSize}px monospace`;
drops.forEach((y, i) => {
const text = chars[Math.floor(Math.random() * chars.length)];
const color = Math.random() > 0.5 ? greenGlow : chromeColor;
ctx.fillStyle = color;
// Viscous effect: stretch and drip
const dripHeight = y * fontSize * viscosities[i];
ctx.fillText(text, i * fontSize, dripHeight);
// Metallic reflection simulation (simple gradient)
ctx.fillStyle = 'rgba(255,255,255,0.2)';
ctx.fillText(text, i * fontSize + 1, dripHeight + 1);
if (dripHeight > height && Math.random() > 0.975) {
drops[i] = 0; // Reset drop
// Splash effect
splashes.push({x: i * fontSize, y: height, size: 10, alpha: 1, vx: (Math.random() - 0.5) * 2, vy: -Math.random() * 5});
// Ripple
ripples.push({x: i * fontSize, y: height, radius: 5, alpha: 0.5});
} else {
drops[i] += speeds[i] * viscosities[i]; // Slow, viscous fall
}
});
// Draw splashes (like heavy syrup splashing)
splashes.forEach((splash, i) => {
ctx.beginPath();
ctx.arc(splash.x, splash.y, splash.size, 0, Math.PI * 2);
ctx.fillStyle = `rgba(0, 255, 100, ${splash.alpha})`;
ctx.fill();
splash.x += splash.vx;
splash.y += splash.vy;
splash.vy += 0.5; // Gravity
splash.alpha -= 0.02;
splash.size *= 0.98; // Shrink
if (splash.alpha <= 0 || splash.y > height) splashes.splice(i, 1);
});
// Hypnotic flow: occasional glow pulses
if (Math.random() < 0.1) {
ctx.shadowBlur = 20;
ctx.shadowColor = 'lime';
} else {
ctx.shadowBlur = 0;
}
}
setInterval(draw, 50); // Slower for viscous feel
</script>
let width, height;
function resize() {
width = canvas.clientWidth;
height = canvas.clientHeight;
canvas.width = width * window.devicePixelRatio;
canvas.height = height * window.devicePixelRatio;
ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
}
window.addEventListener('resize', resize);
resize();
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*()_+-=[]{}|;:,./<>?';
const fontSize = 16;
const columns = Math.floor(width / fontSize);
const drops = Array(columns).fill(0);
const speeds = Array(columns).fill(0).map(() => Math.random() * 2 + 2); // Vary speed for viscosity
const viscosities = Array(columns).fill(0).map(() => Math.random() * 0.5 + 0.5); // Slow down factor
const splashes = [];
const ripples = [];
// For metallic chrome and green mercury
const greenGlow = 'rgba(0, 255, 100, 0.8)';
const chromeColor = 'rgba(200, 200, 200, 0.7)';
const bgImage = new Image();
bgImage.src = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4gPGxpbmVhckdyYWRpZW50IGlkPSJnIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj4gPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMCIvPiA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iIzAwMCIvPiA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAiLz4gPC9saW5lYXJHcmFkaWVudD4gPHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNnKSIvPiA8Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAzMzAwIiBzdHJva2Utd2lkdGg9IjIiLz4gPC9zdmc+'; // Simple distorted bg
function draw() {
ctx.globalAlpha = 0.05;
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, width, height);
ctx.globalAlpha = 1;
// Draw distorted background with ripples
ripples.forEach((ripple, i) => {
ctx.beginPath();
ctx.arc(ripple.x, ripple.y, ripple.radius, 0, Math.PI * 2);
ctx.strokeStyle = `rgba(0, 255, 100, ${ripple.alpha})`;
ctx.lineWidth = 2;
ctx.stroke();
ripple.radius += 1;
ripple.alpha -= 0.01;
if (ripple.alpha <= 0) ripples.splice(i, 1);
});
ctx.font = `${fontSize}px monospace`;
drops.forEach((y, i) => {
const text = chars[Math.floor(Math.random() * chars.length)];
const color = Math.random() > 0.5 ? greenGlow : chromeColor;
ctx.fillStyle = color;
// Viscous effect: stretch and drip
const dripHeight = y * fontSize * viscosities[i];
ctx.fillText(text, i * fontSize, dripHeight);
// Metallic reflection simulation (simple gradient)
ctx.fillStyle = 'rgba(255,255,255,0.2)';
ctx.fillText(text, i * fontSize + 1, dripHeight + 1);
if (dripHeight > height && Math.random() > 0.975) {
drops[i] = 0; // Reset drop
// Splash effect
splashes.push({x: i * fontSize, y: height, size: 10, alpha: 1, vx: (Math.random() - 0.5) * 2, vy: -Math.random() * 5});
// Ripple
ripples.push({x: i * fontSize, y: height, radius: 5, alpha: 0.5});
} else {
drops[i] += speeds[i] * viscosities[i]; // Slow, viscous fall
}
});
// Draw splashes (like heavy syrup splashing)
splashes.forEach((splash, i) => {
ctx.beginPath();
ctx.arc(splash.x, splash.y, splash.size, 0, Math.PI * 2);
ctx.fillStyle = `rgba(0, 255, 100, ${splash.alpha})`;
ctx.fill();
splash.x += splash.vx;
splash.y += splash.vy;
splash.vy += 0.5; // Gravity
splash.alpha -= 0.02;
splash.size *= 0.98; // Shrink
if (splash.alpha <= 0 || splash.y > height) splashes.splice(i, 1);
});
// Hypnotic flow: occasional glow pulses
if (Math.random() < 0.1) {
ctx.shadowBlur = 20;
ctx.shadowColor = 'lime';
} else {
ctx.shadowBlur = 0;
}
}
setInterval(draw, 50); // Slower for viscous feel
</script>