littleshop/publish/littleshop-hotfix/wwwroot/js/holographic-effects.js

537 lines
18 KiB
JavaScript

// 🤖 Holographic Tech Robot Effects System 🤖
// Advanced pixel-perfect holographic animations and tech aesthetics
class HolographicEffectsSystem {
constructor() {
this.isInitialized = false;
this.effectsActive = true;
this.dataStreams = [];
this.glitchElements = [];
this.init();
}
init() {
if (this.isInitialized) return;
console.log('🤖 Initializing Holographic Effects System...');
// Initialize effects when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => this.setupEffects());
} else {
this.setupEffects();
}
this.isInitialized = true;
}
setupEffects() {
// this.createDataStreamBackground(); // Removed
// this.setupHolographicBorders(); // Removed
this.initializeGlitchEffects();
this.createParticleSystem();
this.setupTechScanlines();
this.initializeRobotAnimations();
// this.setupInteractiveHovers(); // Removed
}
// Create animated data streams in background
createDataStreamBackground() {
const dataStreamContainer = document.createElement('div');
dataStreamContainer.className = 'data-stream-container';
dataStreamContainer.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
pointer-events: none;
z-index: -1;
overflow: hidden;
`;
// Create multiple data streams
for (let i = 0; i < 8; i++) {
setTimeout(() => {
this.createDataStream(dataStreamContainer, i);
}, i * 500);
}
document.body.appendChild(dataStreamContainer);
}
createDataStream(container, index) {
const stream = document.createElement('div');
stream.className = 'data-stream';
const left = Math.random() * 100;
const animationDuration = 3 + Math.random() * 4;
const delay = Math.random() * 2;
stream.style.cssText = `
position: absolute;
left: ${left}%;
width: 2px;
height: 100px;
background: linear-gradient(to bottom,
transparent 0%,
rgba(0, 255, 255, 0.8) 20%,
rgba(138, 43, 226, 0.6) 80%,
transparent 100%);
animation: dataStreamFlow ${animationDuration}s linear infinite;
animation-delay: ${delay}s;
box-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
`;
// Add random tech symbols
const symbols = ['01', '10', '11', '00', 'Ω', '∆', '∇', '◊', '◈'];
const symbol = document.createElement('span');
symbol.textContent = symbols[Math.floor(Math.random() * symbols.length)];
symbol.style.cssText = `
position: absolute;
top: 10px;
left: -5px;
color: rgba(0, 255, 255, 0.8);
font-size: 8px;
font-family: 'Courier New', monospace;
text-shadow: 0 0 5px rgba(0, 255, 255, 0.8);
`;
stream.appendChild(symbol);
container.appendChild(stream);
// Remove and recreate after animation
setTimeout(() => {
if (stream.parentNode) {
stream.parentNode.removeChild(stream);
}
if (this.effectsActive) {
this.createDataStream(container, index);
}
}, (animationDuration + delay) * 1000);
}
// Setup holographic borders for cards
setupHolographicBorders() {
const style = document.createElement('style');
style.textContent = `
@keyframes dataStreamFlow {
0% {
transform: translateY(-100px);
opacity: 0;
}
10% { opacity: 1; }
90% { opacity: 1; }
100% {
transform: translateY(calc(100vh + 100px));
opacity: 0;
}
}
@keyframes holographicBorderShift {
0% { border-image-source: linear-gradient(45deg, #8A2BE2, #9932CC, #DA70D6, #FF00FF); }
25% { border-image-source: linear-gradient(90deg, #00FFFF, #8A2BE2, #9932CC, #DA70D6); }
50% { border-image-source: linear-gradient(135deg, #FF00FF, #00FFFF, #8A2BE2, #9932CC); }
75% { border-image-source: linear-gradient(180deg, #DA70D6, #FF00FF, #00FFFF, #8A2BE2); }
100% { border-image-source: linear-gradient(45deg, #8A2BE2, #9932CC, #DA70D6, #FF00FF); }
}
`;
document.head.appendChild(style);
// Apply to cards
setTimeout(() => {
const cards = document.querySelectorAll('.rz-card, .card, .mobile-card');
cards.forEach(card => {
card.style.borderImage = 'linear-gradient(45deg, #8A2BE2, #9932CC, #DA70D6, #FF00FF) 1';
card.style.animation = 'holographicBorderShift 4s ease-in-out infinite';
});
}, 100);
}
// Initialize glitch effects on hover
initializeGlitchEffects() {
const glitchStyle = document.createElement('style');
glitchStyle.textContent = `
.tech-glitch {
position: relative;
}
.tech-glitch::before,
.tech-glitch::after {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 0.3s;
}
.tech-glitch::before {
color: #FF00FF;
animation: glitch1 0.5s infinite;
clip: rect(0, 900px, 0, 0);
}
.tech-glitch::after {
color: #00FFFF;
animation: glitch2 0.5s infinite;
clip: rect(0, 900px, 0, 0);
}
.tech-glitch:hover::before,
.tech-glitch:hover::after {
opacity: 0.8;
}
@keyframes glitch1 {
0% { clip: rect(42px, 9999px, 44px, 0); }
20% { clip: rect(12px, 9999px, 59px, 0); }
40% { clip: rect(63px, 9999px, 34px, 0); }
60% { clip: rect(18px, 9999px, 76px, 0); }
80% { clip: rect(54px, 9999px, 91px, 0); }
100% { clip: rect(25px, 9999px, 38px, 0); }
}
@keyframes glitch2 {
0% { clip: rect(65px, 9999px, 23px, 0); }
20% { clip: rect(87px, 9999px, 45px, 0); }
40% { clip: rect(29px, 9999px, 78px, 0); }
60% { clip: rect(52px, 9999px, 31px, 0); }
80% { clip: rect(15px, 9999px, 89px, 0); }
100% { clip: rect(73px, 9999px, 16px, 0); }
}
`;
document.head.appendChild(glitchStyle);
// Apply to headings
setTimeout(() => {
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
headings.forEach(heading => {
heading.classList.add('tech-glitch');
heading.setAttribute('data-text', heading.textContent);
});
}, 200);
}
// Create particle system
createParticleSystem() {
const particleContainer = document.createElement('div');
particleContainer.className = 'particle-system';
particleContainer.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
pointer-events: none;
z-index: -2;
overflow: hidden;
`;
// Create floating particles
for (let i = 0; i < 20; i++) {
setTimeout(() => {
this.createParticle(particleContainer);
}, i * 100);
}
document.body.appendChild(particleContainer);
}
createParticle(container) {
const particle = document.createElement('div');
const size = Math.random() * 3 + 1;
const x = Math.random() * window.innerWidth;
const y = Math.random() * window.innerHeight;
const duration = Math.random() * 20 + 10;
particle.style.cssText = `
position: absolute;
width: ${size}px;
height: ${size}px;
background: radial-gradient(circle, rgba(138, 43, 226, 0.8) 0%, transparent 70%);
left: ${x}px;
top: ${y}px;
border-radius: 50%;
animation: particleFloat ${duration}s linear infinite;
box-shadow: 0 0 ${size * 3}px rgba(138, 43, 226, 0.6);
`;
const floatDistance = Math.random() * 100 + 50;
const angle = Math.random() * 360;
particle.style.setProperty('--float-x', `${Math.cos(angle * Math.PI / 180) * floatDistance}px`);
particle.style.setProperty('--float-y', `${Math.sin(angle * Math.PI / 180) * floatDistance}px`);
container.appendChild(particle);
// Remove after animation
setTimeout(() => {
if (particle.parentNode) {
particle.parentNode.removeChild(particle);
}
if (this.effectsActive) {
this.createParticle(container);
}
}, duration * 1000);
}
// Setup tech scanlines
setupTechScanlines() {
const scanlineStyle = document.createElement('style');
scanlineStyle.textContent = `
@keyframes particleFloat {
0%, 100% {
transform: translate(0, 0) scale(1);
opacity: 0.3;
}
50% {
transform: translate(var(--float-x), var(--float-y)) scale(1.5);
opacity: 0.8;
}
}
.tech-scanlines::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0, 255, 255, 0.03) 2px,
rgba(0, 255, 255, 0.03) 4px
);
pointer-events: none;
animation: scanlineMove 2s linear infinite;
}
@keyframes scanlineMove {
0% { transform: translateY(0); }
100% { transform: translateY(4px); }
}
`;
document.head.appendChild(scanlineStyle);
// Apply to main containers
setTimeout(() => {
const containers = document.querySelectorAll('.container, .container-fluid, .main-content');
containers.forEach(container => {
container.classList.add('tech-scanlines');
container.style.position = 'relative';
});
}, 300);
}
// Initialize robot-style animations
initializeRobotAnimations() {
const robotStyle = document.createElement('style');
robotStyle.textContent = `
.robot-pulse {
animation: robotPulse 3s ease-in-out infinite;
}
.robot-scan {
position: relative;
overflow: hidden;
}
.robot-scan::after {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: linear-gradient(45deg,
transparent 40%,
rgba(0, 255, 255, 0.1) 50%,
transparent 60%);
animation: robotScan 4s ease-in-out infinite;
}
@keyframes robotPulse {
0%, 100% {
transform: scale(1);
box-shadow: 0 0 20px rgba(138, 43, 226, 0.3);
}
50% {
transform: scale(1.02);
box-shadow: 0 0 40px rgba(138, 43, 226, 0.8);
}
}
@keyframes robotScan {
0% { transform: translate(-100%, -100%) rotate(0deg); }
100% { transform: translate(100%, 100%) rotate(360deg); }
}
.tech-loading {
position: relative;
}
.tech-loading::before {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg, #8A2BE2, #00FFFF, #8A2BE2);
background-size: 200% 200%;
border-radius: inherit;
z-index: -1;
animation: techLoadingPulse 2s ease-in-out infinite;
}
@keyframes techLoadingPulse {
0%, 100% {
opacity: 0.3;
background-position: 0% 50%;
}
50% {
opacity: 0.8;
background-position: 100% 50%;
}
}
`;
document.head.appendChild(robotStyle);
// Apply to cards only (removed button glow effects)
setTimeout(() => {
// const buttons = document.querySelectorAll('.rz-button, .btn');
// buttons.forEach(button => {
// button.classList.add('robot-pulse');
// });
const cards = document.querySelectorAll('.rz-card, .card');
cards.forEach(card => {
card.classList.add('robot-scan');
});
}, 400);
}
// Setup interactive hover effects
setupInteractiveHovers() {
setTimeout(() => {
// Add hover effects to interactive elements
const interactiveElements = document.querySelectorAll('button, .rz-button, .btn, a, .card');
interactiveElements.forEach(element => {
element.addEventListener('mouseenter', (e) => {
this.createHoverEffect(e.target);
});
element.addEventListener('mouseleave', (e) => {
this.removeHoverEffect(e.target);
});
});
}, 500);
}
createHoverEffect(element) {
// Create ripple effect
const ripple = document.createElement('div');
ripple.style.cssText = `
position: absolute;
border-radius: 50%;
background: radial-gradient(circle, rgba(0, 255, 255, 0.6) 0%, transparent 70%);
transform: scale(0);
animation: rippleEffect 0.6s linear;
pointer-events: none;
z-index: 1000;
`;
const rect = element.getBoundingClientRect();
const size = Math.max(rect.width, rect.height);
ripple.style.width = ripple.style.height = size + 'px';
ripple.style.left = (rect.left + rect.width / 2 - size / 2) + 'px';
ripple.style.top = (rect.top + rect.height / 2 - size / 2) + 'px';
document.body.appendChild(ripple);
// Remove after animation
setTimeout(() => {
if (ripple.parentNode) {
ripple.parentNode.removeChild(ripple);
}
}, 600);
// Add tech glow to element
element.style.transition = 'all 0.3s ease';
element.style.boxShadow = '0 0 30px rgba(0, 255, 255, 0.8), inset 0 0 20px rgba(138, 43, 226, 0.4)';
element.style.transform = 'scale(1.05)';
if (!document.getElementById('ripple-style')) {
const rippleStyle = document.createElement('style');
rippleStyle.id = 'ripple-style';
rippleStyle.textContent = `
@keyframes rippleEffect {
to {
transform: scale(4);
opacity: 0;
}
}
`;
document.head.appendChild(rippleStyle);
}
}
removeHoverEffect(element) {
element.style.boxShadow = '';
element.style.transform = '';
}
// Toggle effects on/off
toggleEffects() {
this.effectsActive = !this.effectsActive;
if (!this.effectsActive) {
// Remove all effect containers
const effectContainers = document.querySelectorAll('.data-stream-container, .particle-system');
effectContainers.forEach(container => {
if (container.parentNode) {
container.parentNode.removeChild(container);
}
});
} else {
// Restart effects
this.setupEffects();
}
console.log(`🤖 Holographic effects ${this.effectsActive ? 'enabled' : 'disabled'}`);
}
// Performance monitoring
checkPerformance() {
const start = performance.now();
setTimeout(() => {
const delta = performance.now() - start;
if (delta > 50) { // If frame time is too long
console.warn('🤖 Performance warning: Consider reducing effects');
}
}, 0);
}
}
// Initialize the system
const holographicSystem = new HolographicEffectsSystem();
// Expose control functions globally
window.toggleHolographicEffects = () => holographicSystem.toggleEffects();
window.holographicSystem = holographicSystem;
// Add keyboard shortcut (Ctrl+H) to toggle effects
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.key === 'h') {
e.preventDefault();
holographicSystem.toggleEffects();
}
});
console.log('🤖 Holographic Tech System loaded! Press Ctrl+H to toggle effects.');