-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
111 lines (94 loc) · 3.5 KB
/
Copy pathscript.js
File metadata and controls
111 lines (94 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
document.addEventListener('DOMContentLoaded', () => {
// Mobile menu toggle
const menuBtn = document.getElementById('mobile-menu-btn');
const mobileMenu = document.getElementById('mobile-menu');
if (menuBtn && mobileMenu) {
menuBtn.addEventListener('click', () => {
mobileMenu.classList.toggle('open');
const icon = menuBtn.querySelector('svg');
if (mobileMenu.classList.contains('open')) {
icon.innerHTML = '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />';
} else {
icon.innerHTML = '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />';
}
});
}
// Code rain effect
const canvas = document.getElementById('code-rain');
if (canvas) {
const ctx = canvas.getContext('2d');
let width, height;
const resize = () => {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
};
resize();
window.addEventListener('resize', resize);
const chars = '01アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン';
const fontSize = 14;
const columns = Math.floor(width / fontSize);
const drops = Array(columns).fill(1);
const draw = () => {
ctx.fillStyle = 'rgba(13, 13, 26, 0.05)';
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = '#8b5cf6';
ctx.font = `${fontSize}px monospace`;
for (let i = 0; i < drops.length; i++) {
const text = chars[Math.floor(Math.random() * chars.length)];
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
if (drops[i] * fontSize > height && Math.random() > 0.975) {
drops[i] = 0;
}
drops[i]++;
}
};
setInterval(draw, 35);
}
// Copy code buttons
document.querySelectorAll('.copy-btn').forEach(btn => {
btn.addEventListener('click', async () => {
const target = document.querySelector(btn.dataset.target);
if (!target) return;
try {
await navigator.clipboard.writeText(target.textContent);
const original = btn.textContent;
btn.textContent = 'Copied!';
btn.classList.add('btn-success');
setTimeout(() => {
btn.textContent = original;
btn.classList.remove('btn-success');
}, 2000);
} catch (err) {
console.error('Failed to copy:', err);
}
});
});
// Intersection Observer for fade-in animations
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('opacity-100', 'translate-y-0');
entry.target.classList.remove('opacity-0', 'translate-y-8');
}
});
}, observerOptions);
document.querySelectorAll('.animate-on-scroll').forEach(el => {
el.classList.add('opacity-0', 'translate-y-8', 'transition-all', 'duration-700');
observer.observe(el);
});
// Prompt carousel in the hero terminal card
document.querySelectorAll('[data-carousel]').forEach(carousel => {
const slides = carousel.querySelectorAll('.prompt-slide');
if (slides.length < 2) return;
let current = 0;
setInterval(() => {
slides[current].classList.remove('active');
current = (current + 1) % slides.length;
slides[current].classList.add('active');
}, 10000);
});
});