You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
6.8 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1920, height=1080">
<title>TomorrowLAN Quad Stream Overlay - Gap Matrix Bar</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 1920px;
height: 1080px;
overflow: hidden;
background: transparent;
font-family: 'Segoe UI', 'Arial', sans-serif;
}
#matrix {
position: absolute;
top: 0;
left: 0;
z-index: 0;
clip-path: path(evenodd, "M0,0 H1920 V1080 H0Z M23,91 H787 Q795,91 795,99 V522 Q795,530 787,530 H23 Q15,530 15,522 V99 Q15,91 23,91Z M1133,91 H1897 Q1905,91 1905,99 V522 Q1905,530 1897,530 H1133 Q1125,530 1125,522 V99 Q1125,91 1133,91Z M23,626 H787 Q795,626 795,634 V1057 Q795,1065 787,1065 H23 Q15,1065 15,1057 V634 Q15,626 23,626Z M1133,626 H1897 Q1905,626 1905,634 V1057 Q1905,1065 1897,1065 H1133 Q1125,1065 1125,1057 V634 Q1125,626 1133,626Z");
}
.grid {
position: absolute;
top: 0;
left: 0;
width: 1920px;
height: 1080px;
display: grid;
grid-template-columns: 780px 780px;
grid-template-rows: 439px 439px;
gap: 96px 330px;
padding: 91px 15px 15px;
z-index: 1;
}
.panel {
position: relative;
border-radius: 8px;
background: transparent;
}
.border-anim {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: visible;
}
</style>
</head>
<body>
<svg style="position:absolute;width:0;height:0">
<defs>
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="8" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
</svg>
<canvas id="matrix" width="1920" height="1080"></canvas>
<div class="grid">
<div class="panel">
<svg class="border-anim" viewBox="0 0 780 439">
<rect x="1" y="1" width="778" height="437" rx="7" fill="none" stroke="#00d4ff" stroke-width="2"/>
<rect x="1" y="1" width="778" height="437" rx="7" fill="none" stroke="#80eaff" stroke-width="4" stroke-dasharray="200 2218" stroke-linecap="round" filter="url(#glow)">
<animate attributeName="stroke-dashoffset" from="0" to="-2418" dur="40s" repeatCount="indefinite"/>
</rect>
</svg>
</div>
<div class="panel">
<svg class="border-anim" viewBox="0 0 780 439">
<rect x="1" y="1" width="778" height="437" rx="7" fill="none" stroke="#00d4ff" stroke-width="2"/>
<rect x="1" y="1" width="778" height="437" rx="7" fill="none" stroke="#80eaff" stroke-width="4" stroke-dasharray="200 2218" stroke-linecap="round" filter="url(#glow)">
<animate attributeName="stroke-dashoffset" from="0" to="-2418" dur="40s" begin="-10s" repeatCount="indefinite"/>
</rect>
</svg>
</div>
<div class="panel">
<svg class="border-anim" viewBox="0 0 780 439">
<rect x="1" y="1" width="778" height="437" rx="7" fill="none" stroke="#00d4ff" stroke-width="2"/>
<rect x="1" y="1" width="778" height="437" rx="7" fill="none" stroke="#80eaff" stroke-width="4" stroke-dasharray="200 2218" stroke-linecap="round" filter="url(#glow)">
<animate attributeName="stroke-dashoffset" from="0" to="-2418" dur="40s" begin="-20s" repeatCount="indefinite"/>
</rect>
</svg>
</div>
<div class="panel">
<svg class="border-anim" viewBox="0 0 780 439">
<rect x="1" y="1" width="778" height="437" rx="7" fill="none" stroke="#00d4ff" stroke-width="2"/>
<rect x="1" y="1" width="778" height="437" rx="7" fill="none" stroke="#80eaff" stroke-width="4" stroke-dasharray="200 2218" stroke-linecap="round" filter="url(#glow)">
<animate attributeName="stroke-dashoffset" from="0" to="-2418" dur="40s" begin="-30s" repeatCount="indefinite"/>
</rect>
</svg>
</div>
</div>
<script>
const canvas = document.getElementById('matrix');
const ctx = canvas.getContext('2d');
const W = 1920;
const H = 1080;
const drops = [];
const speeds = [];
const chars = [];
const trailLens = [];
const colSizes = [];
const colX = [];
const colGlow = [];
// Place columns spaced by their character width so they don't overlap
let x = 0;
while (x < W) {
const i = colSizes.length;
colSizes[i] = 10 + Math.floor(Math.random() * 31);
colX[i] = x;
colGlow[i] = 0.05 + Math.random() * 0.45;
drops[i] = Math.random() * (H / colSizes[i]);
speeds[i] = 0.04 + Math.random() * 0.06;
trailLens[i] = 16 + Math.floor(Math.random() * 12);
const rows = Math.ceil(H / colSizes[i]) + 30;
chars[i] = [];
for (let j = 0; j < rows; j++) {
chars[i][j] = Math.random() > 0.5 ? '1' : '0';
}
x += colSizes[i] * 0.75;
}
const columns = colSizes.length;
function draw() {
ctx.fillStyle = 'rgba(10, 22, 40, 0.06)';
ctx.fillRect(0, 0, W, H);
for (let i = 0; i < columns; i++) {
const sz = colSizes[i];
const x = colX[i];
const y = drops[i] * sz;
const row = Math.floor(drops[i]);
const numRows = chars[i].length;
ctx.font = sz + 'px monospace';
const glowR = sz * 1.5;
const cx = x + sz * 0.35;
const g = colGlow[i];
const grad = ctx.createRadialGradient(cx, y, 0, cx, y, glowR);
grad.addColorStop(0, 'rgba(0, 212, 255, ' + g + ')');
grad.addColorStop(0.5, 'rgba(0, 212, 255, ' + (g * 0.3) + ')');
grad.addColorStop(1, 'rgba(0, 212, 255, 0)');
ctx.fillStyle = grad;
ctx.fillRect(cx - glowR, y - glowR, glowR * 2, glowR * 2);
const fadeRows = 6;
const fade = Math.min(1, Math.max(0, (drops[i] + fadeRows) / fadeRows));
const ci = ((row % numRows) + numRows) % numRows;
ctx.fillStyle = 'rgba(255, 255, 255, ' + fade + ')';
ctx.fillText(chars[i][ci], x, y);
const tl = trailLens[i];
for (let t = 1; t <= tl; t++) {
const ti = (((row - t) % numRows) + numRows) % numRows;
const baseAlpha = (1 - t / tl) * 0.6;
const trailFade = Math.min(1, fade + t / fadeRows);
ctx.fillStyle = 'rgba(0, 212, 255, ' + (baseAlpha * trailFade) + ')';
ctx.fillText(chars[i][ti], x, y - sz * t);
}
if (Math.random() < 0.002) {
const ri = Math.floor(Math.random() * numRows);
chars[i][ri] = Math.random() > 0.5 ? '1' : '0';
}
drops[i] += speeds[i];
if (y > H + sz * 2) {
drops[i] = Math.random() * -20;
speeds[i] = 0.04 + Math.random() * 0.06;
trailLens[i] = 16 + Math.floor(Math.random() * 12);
colSizes[i] = 10 + Math.floor(Math.random() * 31);
colGlow[i] = 0.05 + Math.random() * 0.45;
}
}
requestAnimationFrame(draw);
}
// Fill initial background
ctx.fillStyle = '#0a1628';
ctx.fillRect(0, 0, W, H);
draw();
</script>
</body>
</html>