Initial commit: site monorepo with API, web, and infra.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// ===== SCRAMBLE HERO =====
|
||||
const heroTitleEl = document.getElementById('heroTitle');
|
||||
if (heroTitleEl) {
|
||||
const originalText = heroTitleEl.textContent.trim() || 'Технологии будущего на вашей ферме';
|
||||
const chars = '!@#$%^&*()_+{}[]|;:,.<>?';
|
||||
let iteration = 0;
|
||||
let isScrambling = true;
|
||||
let frameId = null;
|
||||
const maxIterations = 30;
|
||||
|
||||
function scramble() {
|
||||
if (!isScrambling) return;
|
||||
const result = originalText
|
||||
.split('')
|
||||
.map((char, index) => {
|
||||
if (index < iteration) return originalText[index];
|
||||
if (char === ' ') return ' ';
|
||||
return chars[Math.floor(Math.random() * chars.length)];
|
||||
})
|
||||
.join('');
|
||||
heroTitleEl.textContent = result;
|
||||
iteration += 1;
|
||||
if (iteration <= maxIterations) {
|
||||
frameId = requestAnimationFrame(scramble);
|
||||
} else {
|
||||
heroTitleEl.textContent = originalText;
|
||||
isScrambling = false;
|
||||
if (frameId) {
|
||||
cancelAnimationFrame(frameId);
|
||||
frameId = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
setTimeout(() => {
|
||||
scramble();
|
||||
}, 300);
|
||||
}
|
||||
|
||||
// ===== FADE-UP =====
|
||||
const fadeElements = document.querySelectorAll('.fade-up');
|
||||
if (fadeElements.length > 0 && 'IntersectionObserver' in window) {
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('visible');
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.15, rootMargin: '0px 0px -30px 0px' });
|
||||
fadeElements.forEach(el => observer.observe(el));
|
||||
} else {
|
||||
fadeElements.forEach(el => el.classList.add('visible'));
|
||||
}
|
||||
|
||||
// ===== EXPAND BLOCK =====
|
||||
const expandContent = document.getElementById('expandContent');
|
||||
if (expandContent && 'IntersectionObserver' in window) {
|
||||
let isExpanded = false;
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
if (!isExpanded) {
|
||||
expandContent.classList.add('expanded');
|
||||
isExpanded = true;
|
||||
}
|
||||
} else {
|
||||
if (isExpanded) {
|
||||
expandContent.classList.remove('expanded');
|
||||
isExpanded = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.25, rootMargin: '0px 0px -30px 0px' });
|
||||
observer.observe(expandContent);
|
||||
} else if (expandContent) {
|
||||
expandContent.classList.add('expanded');
|
||||
}
|
||||
|
||||
// ===== MARQUEE =====
|
||||
const marqueeTrack = document.getElementById('marqueeTrack');
|
||||
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
|
||||
if (prefersReducedMotion.matches && marqueeTrack) {
|
||||
marqueeTrack.style.animation = 'none';
|
||||
marqueeTrack.style.transform = 'translateX(0)';
|
||||
}
|
||||
prefersReducedMotion.addEventListener('change', (e) => {
|
||||
if (marqueeTrack) {
|
||||
if (e.matches) {
|
||||
marqueeTrack.style.animation = 'none';
|
||||
marqueeTrack.style.transform = 'translateX(0)';
|
||||
} else {
|
||||
marqueeTrack.style.animation = 'marqueeScroll 30s linear infinite';
|
||||
marqueeTrack.style.transform = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// ===== HERO VIDEO =====
|
||||
const heroVideo = document.querySelector('.hero-video');
|
||||
if (heroVideo) {
|
||||
heroVideo.play().catch(() => {
|
||||
document.addEventListener('click', () => {
|
||||
heroVideo.play();
|
||||
}, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user