lishiqi.conard 2e214c5b76 Add initial project files including .gitignore, LICENSE, README, and skill definitions
- Created .gitignore to exclude unnecessary files.
- Added MIT License for project licensing.
- Introduced README.md and README.zh-CN.md for documentation in English and Chinese.
- Implemented web design engineer skill with detailed workflow and design principles.
- Included advanced patterns and code templates for reference in the skill.
- Added demo HTML files showcasing the skill's capabilities.
2026-04-21 19:53:49 +08:00

133 lines
3.8 KiB
JavaScript

// Sticky nav background on scroll
const nav = document.getElementById('nav');
const onScroll = () => {
if (window.scrollY > 60) nav.classList.add('is-scrolled');
else nav.classList.remove('is-scrolled');
};
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
// Mobile burger (toggles a quick overlay menu)
const burger = document.getElementById('burger');
if (burger) {
burger.addEventListener('click', () => {
const menu = document.querySelector('.nav__menu');
if (!menu) return;
const open = menu.style.display === 'flex';
menu.style.display = open ? '' : 'flex';
menu.style.flexDirection = 'column';
menu.style.position = 'absolute';
menu.style.top = '100%';
menu.style.left = '0';
menu.style.right = '0';
menu.style.padding = open ? '' : '24px';
menu.style.background = open ? '' : 'rgba(245,242,236,.96)';
menu.style.color = open ? '' : '#1a1a1a';
menu.style.backdropFilter = 'blur(12px)';
});
}
// Works filter
const chips = document.querySelectorAll('.chip');
const cards = document.querySelectorAll('.grid .card');
chips.forEach(chip => {
chip.addEventListener('click', () => {
chips.forEach(c => c.classList.remove('is-active'));
chip.classList.add('is-active');
const filter = chip.dataset.filter;
cards.forEach(card => {
const cat = card.dataset.cat;
const show = filter === 'all' || cat === filter;
card.style.display = show ? '' : 'none';
});
});
});
// Reveal-on-scroll
const revealTargets = document.querySelectorAll(
'.section__head, .card, .about__media, .about__text, .service, .post, .quote blockquote, .contact__inner'
);
revealTargets.forEach(el => el.classList.add('reveal'));
const io = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('is-in');
io.unobserve(entry.target);
}
});
}, { threshold: 0.12, rootMargin: '0px 0px -40px 0px' });
revealTargets.forEach(el => io.observe(el));
// Init AI Canvas Background for Hero
initAICanvas();
function initAICanvas() {
const canvas = document.getElementById('ai-canvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
let width, height;
function resize() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
}
window.addEventListener('resize', resize);
resize();
const particles = [];
const particleCount = window.innerWidth > 768 ? 120 : 60;
for (let i = 0; i < particleCount; i++) {
particles.push({
x: Math.random() * width,
y: Math.random() * height,
vx: (Math.random() - 0.5) * 0.5,
vy: (Math.random() - 0.5) * 0.5,
size: Math.random() * 2 + 0.5
});
}
function draw() {
ctx.clearRect(0, 0, width, height);
// Draw lines
ctx.lineWidth = 0.5;
for (let i = 0; i < particleCount; i++) {
for (let j = i + 1; j < particleCount; j++) {
const dx = particles[i].x - particles[j].x;
const dy = particles[i].y - particles[j].y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 150) {
ctx.strokeStyle = `rgba(0, 240, 255, ${0.2 - dist/150*0.2})`;
ctx.beginPath();
ctx.moveTo(particles[i].x, particles[i].y);
ctx.lineTo(particles[j].x, particles[j].y);
ctx.stroke();
}
}
}
// Draw particles
ctx.fillStyle = 'rgba(0, 240, 255, 0.6)';
for (let i = 0; i < particleCount; i++) {
const p = particles[i];
p.x += p.vx;
p.y += p.vy;
if (p.x < 0 || p.x > width) p.vx *= -1;
if (p.y < 0 || p.y > height) p.vy *= -1;
ctx.beginPath();
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
ctx.fill();
}
requestAnimationFrame(draw);
}
draw();
}