Skip to content

Commit f592c5f

Browse files
committed
Replace JavaScript typewriter with pure CSS animation using steps() for cleaner performance
1 parent 5a21884 commit f592c5f

File tree

1 file changed

+60
-49
lines changed

1 file changed

+60
-49
lines changed

index.html

Lines changed: 60 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
<div class="container">
88
<div class="hero-content">
99
<div class="hero-text">
10-
<h1 class="hero-title" id="terminal-name"></h1>
11-
<h2 class="hero-subtitle" id="terminal-headline"></h2>
12-
<p class="hero-description" id="terminal-bio"></p>
13-
<div class="hero-buttons" id="hero-buttons" style="opacity: 0; transition: opacity 0.5s ease-in;">
10+
<h1 class="hero-title typewriter" id="terminal-name">{{ site.data.profile.name }}</h1>
11+
<h2 class="hero-subtitle typewriter-delay-1" id="terminal-headline">{{ site.data.profile.headline }}</h2>
12+
<p class="hero-description typewriter-delay-2" id="terminal-bio">{{ site.data.profile.bio }}</p>
13+
<div class="hero-buttons fade-in-after-typing">
1414
<a href="{{ site.data.profile.contact.github }}" class="btn btn-primary github-btn" target="_blank">
1515
<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor" style="margin-right: 8px;">
1616
<path d="M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"/>
@@ -92,58 +92,69 @@ <h3>Connect</h3>
9292
</section>
9393

9494
<style>
95-
.hero-title, .hero-subtitle, .hero-description {
96-
min-height: 1.2em;
95+
/* CSS-based typewriter effect */
96+
.typewriter {
97+
overflow: hidden;
98+
border-right: 2px solid var(--gold-primary);
99+
white-space: nowrap;
100+
margin: 0 auto;
101+
letter-spacing: 0.05em;
102+
animation:
103+
typing 2s steps(30, end),
104+
blink-caret 0.75s step-end infinite;
105+
animation-fill-mode: forwards;
97106
}
98-
</style>
99-
100-
<script>
101-
// Terminal typewriter effect with single cursor
102-
const nameText = "{{ site.data.profile.name }}";
103-
const headlineText = "{{ site.data.profile.headline }}";
104-
const bioText = "{{ site.data.profile.bio }}";
105107

106-
const texts = [
107-
{ element: document.getElementById('terminal-name'), text: nameText, speed: 80 },
108-
{ element: document.getElementById('terminal-headline'), text: headlineText, speed: 60 },
109-
{ element: document.getElementById('terminal-bio'), text: bioText, speed: 40 }
110-
];
108+
.typewriter-delay-1 {
109+
overflow: hidden;
110+
border-right: 2px solid var(--gold-primary);
111+
white-space: nowrap;
112+
margin: 0 auto;
113+
letter-spacing: 0.05em;
114+
width: 0;
115+
animation:
116+
typing 1.5s steps(40, end) 2.2s,
117+
blink-caret 0.75s step-end infinite 2.2s;
118+
animation-fill-mode: forwards;
119+
}
111120

112-
let currentTextIndex = 0;
113-
let charIndex = 0;
114-
const cursor = '<span class="terminal-cursor">_</span>';
121+
.typewriter-delay-2 {
122+
overflow: hidden;
123+
border-right: 2px solid var(--gold-primary);
124+
white-space: nowrap;
125+
margin: 0 auto;
126+
letter-spacing: 0.05em;
127+
width: 0;
128+
animation:
129+
typing 3s steps(60, end) 4s,
130+
blink-caret 0.75s step-end infinite 4s,
131+
remove-caret 0s 7s forwards;
132+
animation-fill-mode: forwards;
133+
}
115134

116-
function typeWriter() {
117-
if (currentTextIndex >= texts.length) {
118-
// All text typed, remove cursor and show buttons
119-
texts[texts.length - 1].element.innerHTML = texts[texts.length - 1].element.innerHTML.replace(cursor, '');
120-
document.getElementById('hero-buttons').style.opacity = '1';
121-
return;
122-
}
123-
124-
const current = texts[currentTextIndex];
125-
126-
if (charIndex < current.text.length) {
127-
// Type current character
128-
current.element.innerHTML = current.text.substring(0, charIndex + 1) + cursor;
129-
charIndex++;
130-
setTimeout(typeWriter, current.speed);
131-
} else {
132-
// Finished current element, move to next
133-
current.element.innerHTML = current.text; // Remove cursor from completed element
134-
currentTextIndex++;
135-
charIndex = 0;
136-
setTimeout(typeWriter, 300); // Pause between elements
137-
}
135+
@keyframes typing {
136+
from { width: 0; }
137+
to { width: 100%; }
138138
}
139139

140-
// Start typing when page loads
141-
if (document.readyState === 'loading') {
142-
document.addEventListener('DOMContentLoaded', () => setTimeout(typeWriter, 500));
143-
} else {
144-
setTimeout(typeWriter, 500);
140+
@keyframes blink-caret {
141+
from, to { border-color: transparent; }
142+
50% { border-color: var(--gold-primary); }
145143
}
146-
</script>
144+
145+
@keyframes remove-caret {
146+
to { border-right: none; }
147+
}
148+
149+
.fade-in-after-typing {
150+
opacity: 0;
151+
animation: fade-in 0.5s ease-in 7.2s forwards;
152+
}
153+
154+
@keyframes fade-in {
155+
to { opacity: 1; }
156+
}
157+
</style>
147158

148159
<script>
149160
// Fetch live GitHub contributions count

0 commit comments

Comments
 (0)