Files
2026-09-01 10:46:29 -03:00

225 lines
7.1 KiB
JavaScript
Executable File

/**
* Default Theme - JavaScript
* SysCMS - Content Management System
*/
document.addEventListener('DOMContentLoaded', function() {
// Theme initialization
initTheme();
// Initialize animated counters
initAnimatedCounters();
// Initialize scroll animations
initScrollAnimations();
// Initialize hover effects
initHoverEffects();
});
/**
* Initializes the theme
*/
function initTheme() {
// Add theme class to body
document.body.classList.add('theme-default');
// Check for custom theme configurations
applyThemeConfig();
}
/**
* Applies custom theme configurations
*/
function applyThemeConfig() {
// Here we could apply dynamic theme configurations
// For example, custom colors, fonts, etc.
// Example of how to apply custom colors if they exist
const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--primary-color');
const secondaryColor = getComputedStyle(document.documentElement).getPropertyValue('--secondary-color');
if (primaryColor && primaryColor.trim() !== '') {
document.documentElement.style.setProperty('--primary-color', primaryColor.trim());
}
if (secondaryColor && secondaryColor.trim() !== '') {
document.documentElement.style.setProperty('--secondary-color', secondaryColor.trim());
}
}
/**
* Initializes animated counters for statistics
*/
function initAnimatedCounters() {
const counters = document.querySelectorAll('.stat-number');
const speed = 200;
const countUp = function() {
counters.forEach(counter => {
const target = +counter.getAttribute('data-count');
const count = +counter.innerText;
const increment = target / speed;
if (count < target) {
counter.innerText = Math.ceil(count + increment);
setTimeout(countUp, 10);
} else {
counter.innerText = target;
}
});
};
// Trigger animation when statistics section is visible
const statsSection = document.querySelector('.stats-section');
if (statsSection) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
countUp();
observer.unobserve(entry.target);
}
});
}, { threshold: 0.5 });
observer.observe(statsSection);
}
}
/**
* Initializes scroll animations
*/
function initScrollAnimations() {
// Animation for elements appearing on scroll
const animatedElements = document.querySelectorAll('.feature-card, .service-card, .price-card, .team-member');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
observer.unobserve(entry.target);
}
});
}, { threshold: 0.1 });
animatedElements.forEach(element => {
// Configure initial state
element.style.opacity = '0';
element.style.transform = 'translateY(20px)';
element.style.transition = 'opacity 0.6s ease, transform 0.6s ease';
// Observe element
observer.observe(element);
});
}
/**
* Initializes hover effects
*/
function initHoverEffects() {
// Parallax effect in hero section
const heroSection = document.querySelector('.hero-section');
if (heroSection) {
window.addEventListener('scroll', () => {
const scrolled = window.pageYOffset;
const parallax = heroSection.querySelector('img');
if (parallax) {
const speed = 0.5;
parallax.style.transform = `translateY(${scrolled * speed}px)`;
}
});
}
// Elevation effect on cards
const cards = document.querySelectorAll('.feature-card, .service-card, .price-card');
cards.forEach(card => {
card.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-10px)';
});
card.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
});
});
}
/**
* Utility function to animate elements
*/
function animateElement(element, animation, duration = 1000) {
element.style.animation = `${animation} ${duration}ms ease-in-out`;
setTimeout(() => {
element.style.animation = '';
}, duration);
}
/**
* Utility function to add class with delay
*/
function addClassWithDelay(element, className, delay = 100) {
setTimeout(() => {
element.classList.add(className);
}, delay);
}
/**
* Function to create background particles (optional)
*/
function createBackgroundParticles() {
const particlesContainer = document.createElement('div');
particlesContainer.className = 'particles-container';
particlesContainer.style.position = 'fixed';
particlesContainer.style.top = '0';
particlesContainer.style.left = '0';
particlesContainer.style.width = '100%';
particlesContainer.style.height = '100%';
particlesContainer.style.pointerEvents = 'none';
particlesContainer.style.zIndex = '-1';
particlesContainer.style.overflow = 'hidden';
// Create particles
for (let i = 0; i < 50; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
particle.style.position = 'absolute';
particle.style.width = Math.random() * 5 + 'px';
particle.style.height = particle.style.width;
particle.style.backgroundColor = 'rgba(255, 255, 255, 0.5)';
particle.style.borderRadius = '50%';
particle.style.left = Math.random() * 100 + '%';
particle.style.top = Math.random() * 100 + '%';
particle.style.opacity = Math.random() * 0.5 + 0.2;
// Float animation
const duration = Math.random() * 20 + 10;
const delay = Math.random() * 5;
particle.style.animation = `float ${duration}s ${delay}s infinite ease-in-out`;
particlesContainer.appendChild(particle);
}
// Add CSS for float animation
const style = document.createElement('style');
style.textContent = `
@keyframes float {
0%, 100% { transform: translateY(0) translateX(0); }
25% { transform: translateY(-20px) translateX(10px); }
50% { transform: translateY(10px) translateX(-10px); }
75% { transform: translateY(-10px) translateX(20px); }
}
`;
document.head.appendChild(style);
document.body.appendChild(particlesContainer);
}
// Export functions for global use
window.ThemeDefault = {
animateElement,
addClassWithDelay,
createBackgroundParticles
};