
(function() {
‘use strict’;
// Feature detection
if (!window.requestAnimationFrame || !window.HTMLCanvasElement) {
document.body.innerHTML = ‘
‘;
return;
}
// Add no-js class for fallbacks
document.documentElement.className = document.documentElement.className.replace(‘no-js’, ”);
// Particle Net
const canvas = document.getElementById(“canvas”);
if (!canvas.getContext) return;
const ctx = canvas.getContext(“2d”);
let animationFrameId;
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
resizeCanvas();
const particles = [];
const particleCount = Math.min(120, Math.floor(window.innerWidth * window.innerHeight / 10000));
function initParticles() {
particles.length = 0;
for (let i = 0; i < particleCount; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
vx: (Math.random() – 0.5) * 0.8,
vy: (Math.random() – 0.5) * 0.8,
radius: 1.2
});
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < particleCount; i++) {
let p = particles[i];
p.x += p.vx;
p.y += p.vy;
// Bounce off walls
if (p.x canvas.width) p.vx *= -1;
if (p.y canvas.height) p.vy *= -1;
// Keep particles within bounds
p.x = Math.max(0, Math.min(canvas.width, p.x));
p.y = Math.max(0, Math.min(canvas.height, p.y));
// Draw particle
ctx.beginPath();
ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2);
ctx.fillStyle = “#ff3333″;
ctx.fill();
// Draw connections
for (let j = i + 1; j < particleCount; j++) {
let q = particles[j];
let dx = p.x – q.x;
let dy = p.y – q.y;
let dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 100) {
ctx.beginPath();
ctx.moveTo(p.x, p.y);
ctx.lineTo(q.x, q.y);
ctx.strokeStyle = "rgba(153, 0, 0, " + (0.6 – dist/200) + ")";
ctx.lineWidth = 0.8;
ctx.stroke();
}
}
}
animationFrameId = requestAnimationFrame(draw);
}
// Scramble Text Class
class TextScramble {
constructor(el) {
this.el = el;
this.chars = '!@#$%^&*()_+=-{}[]|:;,.?/~’;
this.update = this.update.bind(this);
this.frame = 0;
this.frameRequest = null;
this.queue = [];
this.resolve = null;
}
setText(newText) {
const oldText = this.el.textContent || ”;
const length = Math.max(oldText.length, newText.length);
const promise = new Promise(resolve => this.resolve = resolve);
this.queue = [];
for (let i = 0; i < length; i++) {
const from = oldText[i] || '';
const to = newText[i] || '';
const start = Math.floor(Math.random() * 40);
const end = start + Math.floor(Math.random() * 40);
this.queue.push({ from, to, start, end });
}
cancelAnimationFrame(this.frameRequest);
this.frame = 0;
this.update();
return promise;
}
update() {
let output = '';
let complete = 0;
for (let i = 0, n = this.queue.length; i = end) {
complete++;
output += to;
} else if (this.frame >= start) {
if (!char || Math.random() < 0.28) {
char = this.randomChar();
this.queue[i].char = char;
}
output += `${char}`;
} else {
output += from;
}
}
this.el.innerHTML = output;
if (complete === this.queue.length) {
if (this.resolve) this.resolve();
} else {
this.frameRequest = requestAnimationFrame(this.update);
this.frame++;
}
}
randomChar() {
return this.chars[Math.floor(Math.random() * this.chars.length)];
}
}
// Phrases for text scramble
const phrases = [
‘SITE HAS BEEN SEIZED’,
‘IndoClaySec’,
];
// Initialize text scramble
const el = document.querySelector(‘.text’);
let fx;
if (el) {
fx = new TextScramble(el);
let counter = 0;
const next = () => {
if (fx) {
fx.setText(phrases[counter]).then(() => {
setTimeout(next, 2500);
});
counter = (counter + 1) % phrases.length;
}
};
next();
}
// Music handling with user interaction
let musicPlayed = false;
const bgMusic = document.getElementById(‘bg-music’);
function playMusic() {
if (!musicPlayed && bgMusic) {
bgMusic.volume = 0.5;
bgMusic.play().then(() => {
musicPlayed = true;
}).catch(err => {
console.log(“Audio play failed, requires user interaction”);
});
}
}
// Add click/touch event for music
document.addEventListener(‘click’, playMusic);
document.addEventListener(‘touchstart’, playMusic, { once: true });
// Handle window resize
let resizeTimeout;
window.addEventListener(‘resize’, function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function() {
resizeCanvas();
initParticles();
}, 250);
});
// Initialize everything
initParticles();
draw();
// Clean up animation on page hide
document.addEventListener(‘visibilitychange’, function() {
if (document.hidden) {
cancelAnimationFrame(animationFrameId);
if (bgMusic) bgMusic.pause();
} else {
if (!document.hidden) {
animationFrameId = requestAnimationFrame(draw);
}
}
});
})();

