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
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 - Animated Matrix</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,15 H942 Q950,15 950,23 V522 Q950,530 942,530 H23 Q15,530 15,522 V23 Q15,15 23,15Z M978,15 H1897 Q1905,15 1905,23 V522 Q1905,530 1897,530 H978 Q970,530 970,522 V23 Q970,15 978,15Z M23,550 H942 Q950,550 950,558 V1057 Q950,1065 942,1065 H23 Q15,1065 15,1057 V558 Q15,550 23,550Z M978,550 H1897 Q1905,550 1905,558 V1057 Q1905,1065 1897,1065 H978 Q970,1065 970,1057 V558 Q970,550 978,550Z");
|
|
}
|
|
|
|
.grid {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 1920px;
|
|
height: 1080px;
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
grid-template-rows: 1fr 1fr;
|
|
gap: 20px;
|
|
padding: 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 935 515">
|
|
<rect x="1" y="1" width="933" height="513" rx="7" fill="none" stroke="#00d4ff" stroke-width="2"/>
|
|
<rect x="1" y="1" width="933" height="513" rx="7" fill="none" stroke="#80eaff" stroke-width="4" stroke-dasharray="200 2680" stroke-linecap="round" filter="url(#glow)">
|
|
<animate attributeName="stroke-dashoffset" from="0" to="-2880" dur="40s" repeatCount="indefinite"/>
|
|
</rect>
|
|
</svg>
|
|
</div>
|
|
<div class="panel">
|
|
<svg class="border-anim" viewBox="0 0 935 515">
|
|
<rect x="1" y="1" width="933" height="513" rx="7" fill="none" stroke="#00d4ff" stroke-width="2"/>
|
|
<rect x="1" y="1" width="933" height="513" rx="7" fill="none" stroke="#80eaff" stroke-width="4" stroke-dasharray="200 2680" stroke-linecap="round" filter="url(#glow)">
|
|
<animate attributeName="stroke-dashoffset" from="0" to="-2880" dur="40s" begin="-10s" repeatCount="indefinite"/>
|
|
</rect>
|
|
</svg>
|
|
</div>
|
|
<div class="panel">
|
|
<svg class="border-anim" viewBox="0 0 935 515">
|
|
<rect x="1" y="1" width="933" height="513" rx="7" fill="none" stroke="#00d4ff" stroke-width="2"/>
|
|
<rect x="1" y="1" width="933" height="513" rx="7" fill="none" stroke="#80eaff" stroke-width="4" stroke-dasharray="200 2680" stroke-linecap="round" filter="url(#glow)">
|
|
<animate attributeName="stroke-dashoffset" from="0" to="-2880" dur="40s" begin="-20s" repeatCount="indefinite"/>
|
|
</rect>
|
|
</svg>
|
|
</div>
|
|
<div class="panel">
|
|
<svg class="border-anim" viewBox="0 0 935 515">
|
|
<rect x="1" y="1" width="933" height="513" rx="7" fill="none" stroke="#00d4ff" stroke-width="2"/>
|
|
<rect x="1" y="1" width="933" height="513" rx="7" fill="none" stroke="#80eaff" stroke-width="4" stroke-dasharray="200 2680" stroke-linecap="round" filter="url(#glow)">
|
|
<animate attributeName="stroke-dashoffset" from="0" to="-2880" 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>
|