Vertical Bars Noise
A canvas-based reactive background with noise-driven horizontal bars that animate, scatter, and ripple in response to mouse movement and clicks.
Generated using Grepped's AI UI component generator — created from scratch, not pulled from a library.
canvasnoisebarsinteractivebackgroundreactive
Live Preview — customize or regenerate this in the workspace
Loading preview…
Design Intent
Noise-driven bars arranged in horizontal rows that scatter and ripple with mouse interaction.
CSS
css
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; overflow: hidden; background: #F0EEE6; }
canvas { display: block; width: 100%; height: 100%; }HTML
html
<canvas id="c"></canvas>Full Source
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; overflow: hidden; background: #F0EEE6; }
canvas { display: block; width: 100%; height: 100%; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
var BG = '#F0EEE6';
var LC = '#444444';
var BC = '#000000';
var LW = 1;
var SPEED = 0.0005;
var REMOVE_WAVE = true;
function hexRgb(h) {
var c = h.charAt(0) === '#' ? h.slice(1) : h;
return { r: parseInt(c.slice(0,2),16), g: parseInt(c.slice(2,4),16), b: parseInt(c.slice(4,6),16) };
}
var canvas = document.getElementById('c');
var time = 0;
var mouse = { x: 0, y: 0, down: false };
var ripples = [];
function resize() {
var dpr = window.devicePixelRatio || 1;
canvas.width = innerWidth * dpr;
canvas.height = innerHeight * dpr;
canvas.style.width = innerWidth + 'px';
canvas.style.height = innerHeight + 'px';
canvas.getContext('2d').scale(dpr, dpr);
}
function noise(x, y, t) {
var n = Math.sin(x*0.01+t)*Math.cos(y*0.01+t) + Math.sin(x*0.015-t)*Math.cos(y*0.005+t);
return (n+1)/2;
}
function mouseFx(x, y) {
var d = Math.sqrt((x-mouse.x)*(x-mouse.x)+(y-mouse.y)*(y-mouse.y));
return Math.max(0, 1-d/200);
}
function rippleFx(x, y, now) {
var tot = 0;
for (var k=0; k<ripples.length; k++) {
var r = ripples[k];
var age = now - r.t;
if (age < 2000) {
var dx = x-r.x, dy = y-r.y;
var dist = Math.sqrt(dx*dx+dy*dy);
var rad = age/2000*300, w = 50;
if (Math.abs(dist-rad) < w) tot += (1-age/2000)*r.i*(1-Math.abs(dist-rad)/w);
}
}
return Math.min(tot, 2);
}
function draw() {
var ctx = canvas.getContext('2d');
time += SPEED;
var now = Date.now();
var W = canvas.clientWidth, H = canvas.clientHeight;
var nLines = Math.floor(H/11);
var sp = H/nLines;
var lc = hexRgb(LC), bc = hexRgb(BC);
ctx.fillStyle = BG;
ctx.fillRect(0, 0, W, H);
for (var i=0; i<nLines; i++) {
var y = i*sp + sp/2;
var mfy = mouseFx(W/2, y);
var alpha = Math.max(0.3, 0.3+mfy*0.7);
ctx.beginPath();
ctx.strokeStyle = 'rgba('+lc.r+','+lc.g+','+lc.b+','+alpha+')';
ctx.lineWidth = LW + mfy*2;
ctx.moveTo(0, y); ctx.lineTo(W, y); ctx.stroke();
for (var x=0; x<W; x+=8) {
var nv = noise(x, y, time);
var mf = mouseFx(x, y);
var rf = rippleFx(x, y, now);
var inf = mf+rf;
var thr = Math.max(0.2, 0.5-mf*0.2-Math.abs(rf)*0.1);
if (nv > thr) {
var bw = 3+nv*10+inf*5;
var bh = 2+nv*3+inf*3;
var ax = x + Math.sin(time+y*0.0375)*20*nv
+ (mouse.down ? Math.sin(time*3+x*0.01)*10*mf : 0)
+ rf*Math.sin(time*2+x*0.02)*15;
var inten = Math.min(1, Math.max(0.7, 0.7+inf*0.3));
ctx.fillStyle = 'rgba('+bc.r+','+bc.g+','+bc.b+','+inten+')';
ctx.fillRect(ax-bw/2, y-bh/2, bw, bh);
}
}
}
if (!REMOVE_WAVE) {
var now2 = Date.now();
for (var k=0; k<ripples.length; k++) {
var r2 = ripples[k];
var age2 = now2 - r2.t;
if (age2 < 2000) {
var p2 = age2/2000;
ctx.beginPath();
ctx.strokeStyle = 'rgba(100,100,100,'+(1-p2)*0.3*r2.i+')';
ctx.lineWidth = 2;
ctx.arc(r2.x, r2.y, p2*300, 0, Math.PI*2);
ctx.stroke();
}
}
}
requestAnimationFrame(draw);
}
resize();
window.addEventListener('resize', resize);
canvas.addEventListener('mousemove', function(e) {
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX-rect.left; mouse.y = e.clientY-rect.top;
});
canvas.addEventListener('mousedown', function(e) {
mouse.down = true;
var rect = canvas.getBoundingClientRect();
ripples.push({ x: e.clientX-rect.left, y: e.clientY-rect.top, t: Date.now(), i: 1.5 });
var now = Date.now();
ripples = ripples.filter(function(r){ return now-r.t < 2000; });
});
canvas.addEventListener('mouseup', function(){ mouse.down = false; });
draw();
</script>
</body>
</html>