new file: .gitignore
new file: Dockerfile new file: README.md new file: app.py new file: index.html new file: projekte des/PROJECT_DESCRIPTION.txt new file: projekte des/WEBSITE_DESCRIPTION.md new file: projekte des/website_project_description_en.txt new file: requirements.txt new file: script.js new file: static/css/styles.css new file: static/js/script.js new file: styles.css new file: templates/about.html new file: templates/base.html new file: templates/contact.html new file: templates/index.html new file: templates/minecraft.html new file: templates/project_detail.html new file: templates/projects.html
This commit is contained in:
98
static/js/script.js
Normal file
98
static/js/script.js
Normal file
@@ -0,0 +1,98 @@
|
||||
// Mirrors root script.js for Flask static serving
|
||||
// Mobile Navigation Toggle
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const hamburger = document.querySelector('.hamburger');
|
||||
const navLinks = document.querySelector('.nav-links');
|
||||
|
||||
if (hamburger && navLinks) {
|
||||
hamburger.addEventListener('click', function() {
|
||||
navLinks.classList.toggle('active');
|
||||
hamburger.classList.toggle('active');
|
||||
});
|
||||
|
||||
document.querySelectorAll('.nav-links a').forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
navLinks.classList.remove('active');
|
||||
hamburger.classList.remove('active');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Smooth scrolling for navigation links
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
const href = this.getAttribute('href');
|
||||
if (href && href.startsWith('#')) {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(href);
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Navbar background on scroll
|
||||
window.addEventListener('scroll', function() {
|
||||
const navbar = document.querySelector('.navbar');
|
||||
if (navbar) {
|
||||
navbar.style.background = window.scrollY > 100 ? 'rgba(10, 10, 10, 0.98)' : 'rgba(10, 10, 10, 0.95)';
|
||||
}
|
||||
});
|
||||
|
||||
// Intersection Observer for animations
|
||||
const observeElements = () => {
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.style.opacity = '1';
|
||||
entry.target.style.transform = 'translateY(0)';
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
|
||||
|
||||
document.querySelectorAll('.project-card, .tech-item, .contact-card').forEach((el, i) => {
|
||||
el.style.opacity = '0';
|
||||
el.style.transform = 'translateY(30px)';
|
||||
el.style.transition = `opacity 0.6s ease ${i * 0.1}s, transform 0.6s ease ${i * 0.1}s`;
|
||||
observer.observe(el);
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', observeElements);
|
||||
|
||||
// Hover effects for project cards
|
||||
document.querySelectorAll('.project-card').forEach(card => {
|
||||
card.addEventListener('mouseenter', function() {
|
||||
this.style.transform = 'translateY(-10px) scale(1.02)';
|
||||
});
|
||||
card.addEventListener('mouseleave', function() {
|
||||
this.style.transform = 'translateY(0) scale(1)';
|
||||
});
|
||||
});
|
||||
|
||||
// Active state to navigation links based on scroll position
|
||||
const updateActiveNav = () => {
|
||||
const sections = document.querySelectorAll('section[id]');
|
||||
const navLinks = document.querySelectorAll('.nav-links a[href^="#"]');
|
||||
let current = '';
|
||||
sections.forEach(section => {
|
||||
if (pageYOffset >= section.offsetTop - 200) {
|
||||
current = section.getAttribute('id');
|
||||
}
|
||||
});
|
||||
navLinks.forEach(link => {
|
||||
link.classList.toggle('active', link.getAttribute('href') === `#${current}`);
|
||||
});
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', updateActiveNav);
|
||||
|
||||
// Inject minimal CSS for active nav indicator
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
.nav-links a.active { color: #00d4ff !important; }
|
||||
.nav-links a.active::before { width: 100% !important; }
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
Reference in New Issue
Block a user