ProjectGenesis's picture
Promote version b1b47f7 to main
0026c76 verified
document.addEventListener('DOMContentLoaded', function() {
// Add SVG gradients for countdown circles
const svgDefs = `
<svg width="0" height="0" style="position:absolute;">
<defs>
<linearGradient id="days-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#0ff0fc" />
<stop offset="100%" stop-color="#00c6fb" />
</linearGradient>
<linearGradient id="hours-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#ff00ff" />
<stop offset="100%" stop-color="#ff1493" />
</linearGradient>
</defs>
</svg>
`;
document.body.insertAdjacentHTML('afterbegin', svgDefs);
// Remove any existing particle networks
const cosmicWeb = document.querySelector('.cosmic-web');
while (cosmicWeb.firstChild) {
cosmicWeb.removeChild(cosmicWeb.firstChild);
}
// Set the date we're counting down to (Q1 2026)
const countDownDate = new Date("Jan 1, 2026 00:00:00").getTime();
// Update the countdown every 1 second
const countdownFunction = setInterval(function() {
// Get today's date and time
const now = new Date().getTime();
// Find the distance between now and the countdown date
const distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Display the result
document.getElementById("days").innerHTML = days.toString().padStart(2, '0');
document.getElementById("hours").innerHTML = hours.toString().padStart(2, '0');
document.getElementById("minutes").innerHTML = minutes.toString().padStart(2, '0');
document.getElementById("seconds").innerHTML = seconds.toString().padStart(2, '0');
// Update circle progress
const dayProgress = 283 - (283 * (days / 365));
const hourProgress = 283 - (283 * (hours / 24));
const minuteProgress = 283 - (283 * (minutes / 60));
const secondProgress = 283 - (283 * (seconds / 60));
document.querySelector('.days-progress').style.strokeDashoffset = dayProgress;
document.querySelector('.hours-progress').style.strokeDashoffset = hourProgress;
document.querySelector('.minutes-progress').style.strokeDashoffset = minuteProgress;
document.querySelector('.seconds-progress').style.strokeDashoffset = secondProgress;
// If the countdown is finished, clear it
if (distance < 0) {
clearInterval(countdownFunction);
document.getElementById("days").innerHTML = "00";
document.getElementById("hours").innerHTML = "00";
document.getElementById("minutes").innerHTML = "00";
document.getElementById("seconds").innerHTML = "00";
}
}, 1000);
// Create particle network
createParticleNetwork();
// Animate Facebook popup after delay
setTimeout(() => {
document.querySelector('.facebook-popup').style.display = 'block';
}, 2000);
});
class ParticleNetwork {
constructor(container) {
this.container = container;
this.canvas = document.createElement('canvas');
this.ctx = this.canvas.getContext('2d');
this.particles = [];
this.particleCount = window.innerWidth < 768 ? 80 : 150;
this.mouse = { x: null, y: null, radius: 150 };
this.interactionRadius = 150;
this.container.appendChild(this.canvas);
this.setupCanvas();
this.createParticles();
this.animate();
this.bindEvents();
}
setupCanvas() {
this.canvas.style.position = 'absolute';
this.canvas.style.top = '0';
this.canvas.style.left = '0';
this.canvas.style.zIndex = '1';
this.canvas.width = this.container.offsetWidth;
this.canvas.height = this.container.offsetHeight;
}
createParticles() {
const colorOptions = [
'rgba(15, 240, 252, 0.7)', // Neon blue
'rgba(255, 0, 255, 0.7)', // Neon magenta
'rgba(255, 255, 255, 0.5)' // White
];
for (let i = 0; i < this.particleCount; i++) {
const size = Math.random() * 3 + 1;
const speedFactor = 0.2 + Math.random() * 0.3;
this.particles.push({
x: Math.random() * this.canvas.width,
y: Math.random() * this.canvas.height,
size: size,
baseSize: size,
speedX: (Math.random() - 0.5) * speedFactor,
speedY: (Math.random() - 0.5) * speedFactor,
color: colorOptions[Math.floor(Math.random() * colorOptions.length)],
originalColor: colorOptions[Math.floor(Math.random() * colorOptions.length)],
glowIntensity: Math.random() * 0.5 + 0.5
});
}
}
animate() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
// Update and draw particles
for (let i = 0; i < this.particles.length; i++) {
const p = this.particles[i];
// Update position with boundary check
p.x += p.speedX;
p.y += p.speedY;
// Bounce off edges with slight randomness
if (p.x < 0 || p.x > this.canvas.width) {
p.speedX *= -1 * (0.9 + Math.random() * 0.1);
p.x = p.x < 0 ? 0 : this.canvas.width;
}
if (p.y < 0 || p.y > this.canvas.height) {
p.speedY *= -1 * (0.9 + Math.random() * 0.1);
p.y = p.y < 0 ? 0 : this.canvas.height;
}
// Mouse interaction
if (this.mouse.x !== null && this.mouse.y !== null) {
const dx = this.mouse.x - p.x;
const dy = this.mouse.y - p.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < this.interactionRadius) {
const angle = Math.atan2(dy, dx);
const force = (this.interactionRadius - distance) / this.interactionRadius;
// Repel particles from mouse
p.x -= Math.cos(angle) * force * 2;
p.y -= Math.sin(angle) * force * 2;
// Increase size and glow when near mouse
p.size = p.baseSize * (1 + force * 2);
p.color = `rgba(${this.hexToRgb(p.originalColor)}, ${0.5 + force * 0.5})`;
} else {
p.size = p.baseSize;
p.color = p.originalColor;
}
} else {
p.size = p.baseSize;
p.color = p.originalColor;
}
// Draw particle with glow effect
this.ctx.beginPath();
this.ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
const gradient = this.ctx.createRadialGradient(
p.x, p.y, 0,
p.x, p.y, p.size * 3
);
gradient.addColorStop(0, p.color);
gradient.addColorStop(1, 'rgba(0,0,0,0)');
this.ctx.fillStyle = gradient;
this.ctx.fill();
}
// Draw connections between particles
this.drawConnections();
requestAnimationFrame(() => this.animate());
}
hexToRgb(hex) {
const result = /^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/.exec(hex);
return result ? `${result[1]}, ${result[2]}, ${result[3]}` : '255,255,255';
}
drawConnections() {
for (let i = 0; i < this.particles.length; i++) {
for (let j = i + 1; j < this.particles.length; j++) {
const p1 = this.particles[i];
const p2 = this.particles[j];
const dx = p1.x - p2.x;
const dy = p1.y - p2.y;
const distance = Math.sqrt(dx * dx + dy * dy);
const maxDistance = 150;
if (distance < maxDistance) {
const opacity = 1 - (distance / maxDistance);
this.ctx.beginPath();
// Gradient for connection line
const gradient = this.ctx.createLinearGradient(p1.x, p1.y, p2.x, p2.y);
gradient.addColorStop(0, p1.color);
gradient.addColorStop(1, p2.color);
this.ctx.strokeStyle = gradient;
this.ctx.lineWidth = opacity * 1.5;
this.ctx.moveTo(p1.x, p1.y);
this.ctx.lineTo(p2.x, p2.y);
this.ctx.stroke();
}
}
}
}
bindEvents() {
window.addEventListener('resize', () => {
this.canvas.width = this.container.offsetWidth;
this.canvas.height = this.container.offsetHeight;
});
window.addEventListener('mousemove', (e) => {
const rect = this.canvas.getBoundingClientRect();
this.mouse.x = e.clientX - rect.left;
this.mouse.y = e.clientY - rect.top;
});
window.addEventListener('mouseout', () => {
this.mouse.x = null;
this.mouse.y = null;
});
// Touch support
window.addEventListener('touchmove', (e) => {
e.preventDefault();
const rect = this.canvas.getBoundingClientRect();
this.mouse.x = e.touches[0].clientX - rect.left;
this.mouse.y = e.touches[0].clientY - rect.top;
});
window.addEventListener('touchend', () => {
this.mouse.x = null;
this.mouse.y = null;
});
}
}
function createParticleNetwork() {
const container = document.querySelector('.cosmic-web');
// Remove any existing canvas
const existingCanvas = container.querySelector('canvas');
if (existingCanvas) {
existingCanvas.remove();
}
new ParticleNetwork(container);
}