unified: Phantom Protocol 2025 complete archive integration

This commit is contained in:
NW
2026-05-18 17:28:53 +01:00
commit b680c5aeca
553 changed files with 112091 additions and 0 deletions

237
website/js/background.js Normal file
View File

@@ -0,0 +1,237 @@
/* ==========================================
Phantom Protocol - Advanced Background Animation
DHT Network visualization with nodes and connections
Based on Hero section animation
© NeroWorld AI, 2025
========================================== */
(function() {
'use strict';
// Конфигурация
const config = {
nodeCount: 60, // Количество узлов DHT
connectionDistance: 180, // Расстояние для связей
nodeSpeedMin: 0.2, // Минимальная скорость
nodeSpeedMax: 0.8, // Максимальная скорость
nodeRadiusMin: 1.5, // Минимальный размер узла
nodeRadiusMax: 3, // Максимальный размер узла
colors: {
node: 'rgba(0, 240, 255, ', // Цвет узлов (cyan) + opacity
connection: 'rgba(122, 62, 255, ', // Цвет связей (purple) + opacity
glow: 'rgba(0, 240, 255, 0.5)' // Цвет свечения
}
};
// Класс узла DHT сети
class DHTNode {
constructor(canvas) {
this.canvas = canvas;
this.reset();
}
reset() {
this.x = Math.random() * this.canvas.width;
this.y = Math.random() * this.canvas.height;
this.vx = (Math.random() - 0.5) * (config.nodeSpeedMin + Math.random() * (config.nodeSpeedMax - config.nodeSpeedMin));
this.vy = (Math.random() - 0.5) * (config.nodeSpeedMin + Math.random() * (config.nodeSpeedMax - config.nodeSpeedMin));
this.radius = config.nodeRadiusMin + Math.random() * (config.nodeRadiusMax - config.nodeRadiusMin);
this.opacity = Math.random() * 0.5 + 0.5; // 0.5 - 1.0
}
update() {
this.x += this.vx;
this.y += this.vy;
// Отскок от границ
if (this.x < 0 || this.x > this.canvas.width) {
this.vx *= -1;
this.x = Math.max(0, Math.min(this.canvas.width, this.x));
}
if (this.y < 0 || this.y > this.canvas.height) {
this.vy *= -1;
this.y = Math.max(0, Math.min(this.canvas.height, this.y));
}
}
draw(ctx) {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = config.colors.node + this.opacity + ')';
ctx.fill();
// Добавляем свечение для больших узлов
if (this.radius > 2) {
ctx.shadowBlur = 15;
ctx.shadowColor = config.colors.glow;
ctx.fill();
ctx.shadowBlur = 0;
}
}
}
// Класс анимации DHT сети
class DHTNetworkAnimation {
constructor(canvasId) {
this.canvas = document.getElementById(canvasId);
if (!this.canvas) {
console.warn('Canvas element not found:', canvasId);
return;
}
this.ctx = this.canvas.getContext('2d');
this.nodes = [];
this.animationId = null;
this.resizeTimeout = null;
this.init();
}
init() {
// Установка размера canvas
this.resize();
// Создание узлов DHT
for (let i = 0; i < config.nodeCount; i++) {
this.nodes.push(new DHTNode(this.canvas));
}
// Обработчик изменения размера окна с throttling
window.addEventListener('resize', () => {
if (this.resizeTimeout) clearTimeout(this.resizeTimeout);
this.resizeTimeout = setTimeout(() => this.resize(), 150);
});
// Запуск анимации
this.animate();
}
resize() {
if (!this.canvas) return;
const newWidth = window.innerWidth;
const newHeight = Math.max(
document.documentElement.scrollHeight,
document.body.scrollHeight,
document.documentElement.clientHeight,
window.innerHeight
);
// Обновляем только если размер изменился
if (this.canvas.width !== newWidth || this.canvas.height !== newHeight) {
this.canvas.width = newWidth;
this.canvas.height = newHeight;
// Переинициализируем узлы при большом изменении размера
if (Math.abs(this.canvas.width - newWidth) > 100) {
this.nodes.forEach(node => node.reset());
}
}
}
drawConnections() {
const { connectionDistance, colors } = config;
for (let i = 0; i < this.nodes.length; i++) {
for (let j = i + 1; j < this.nodes.length; j++) {
const dx = this.nodes[i].x - this.nodes[j].x;
const dy = this.nodes[i].y - this.nodes[j].y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < connectionDistance) {
// Opacity зависит от расстояния (ближе = ярче)
const opacity = (1 - distance / connectionDistance) * 0.4;
this.ctx.beginPath();
this.ctx.moveTo(this.nodes[i].x, this.nodes[i].y);
this.ctx.lineTo(this.nodes[j].x, this.nodes[j].y);
this.ctx.strokeStyle = colors.connection + opacity + ')';
this.ctx.lineWidth = 1;
this.ctx.stroke();
}
}
}
}
animate() {
if (!this.canvas || !this.ctx) return;
// Очистка canvas
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
// Рисуем связи первыми (за узлами)
this.drawConnections();
// Обновление и отрисовка узлов
this.nodes.forEach(node => {
node.update();
node.draw(this.ctx);
});
// Следующий кадр
this.animationId = requestAnimationFrame(() => this.animate());
}
destroy() {
if (this.animationId) {
cancelAnimationFrame(this.animationId);
this.animationId = null;
}
if (this.resizeTimeout) {
clearTimeout(this.resizeTimeout);
}
this.nodes = [];
}
}
// Автоматическая инициализация при загрузке
function initBackground() {
// Проверяем что DOM загружен
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', startAnimation);
} else {
startAnimation();
}
function startAnimation() {
// Ждем полной загрузки страницы
if (document.readyState === 'complete') {
createAnimation();
} else {
window.addEventListener('load', createAnimation);
}
}
function createAnimation() {
setTimeout(() => {
// Создаем анимацию
window.phantomBackground = new DHTNetworkAnimation('phantomBackground');
// Отслеживание изменений DOM (с throttling)
if (window.phantomBackground) {
let mutationTimeout;
const observer = new MutationObserver(() => {
if (mutationTimeout) clearTimeout(mutationTimeout);
mutationTimeout = setTimeout(() => {
if (window.phantomBackground && typeof window.phantomBackground.resize === 'function') {
window.phantomBackground.resize();
}
}, 1000); // Задержка 1 секунда для стабильности
});
// Наблюдаем за изменениями структуры страницы
observer.observe(document.body, {
childList: true,
subtree: false
});
}
console.log('✨ DHT Network Background initialized');
}, 100);
}
}
// Запуск
initBackground();
})();