.typewriter-text {
font-size: 2.5rem;
font-weight: 700;
color: #f8fafc;
min-height: 80px;
display: flex;
align-items: center;
justify-content: center;
font-family: 'Fira Code', 'Monaco', 'Consolas', monospace;
}
.typewriter-cursor {
display: inline-block;
width: 3px;
height: 2.5rem;
background: #6366f1;
margin-left: 5px;
animation: blink 1s infinite;
}
@keyframes blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
}
.typewriter-controls {
display: flex;
gap: 15px;
flex-wrap: wrap;
justify-content: center;
}
.typewriter-btn {
padding: 12px 24px;
background: #334155;
border: 1px solid #475569;
border-radius: 8px;
color: #f8fafc;
cursor: pointer;
transition: all 0.3s ease;
font-weight: 500;
}
.typewriter-btn:hover {
background: #475569;
border-color: #6366f1;
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(99, 102, 241, 0.2);
}
class TypewriterEffect {
constructor(element, texts, options = {}) {
this.element = element;
this.texts = texts;
this.currentTextIndex = 0;
this.currentCharIndex = 0;
this.isTyping = false;
this.isPaused = false;
this.options = {
typeSpeed: options.typeSpeed || 100,
deleteSpeed: options.deleteSpeed || 50,
pauseTime: options.pauseTime || 2000,
loop: options.loop !== false
};
this.init();
}
init() {
this.type();
}
async type() {
if (this.isPaused) return;
const currentText = this.texts[this.currentTextIndex];
if (this.currentCharIndex < currentText.length) {
this.element.textContent += currentText[this.currentCharIndex];
this.currentCharIndex++;
await this.delay(this.options.typeSpeed);
this.type();
} else {
await this.delay(this.options.pauseTime);
this.delete();
}
}
async delete() {
if (this.isPaused) return;
if (this.currentCharIndex > 0) {
this.element.textContent = this.element.textContent.slice(0, -1);
this.currentCharIndex--;
await this.delay(this.options.deleteSpeed);
this.delete();
} else {
this.currentTextIndex = (this.currentTextIndex + 1) % this.texts.length;
if (this.options.loop || this.currentTextIndex > 0) {
await this.delay(500);
this.type();
}
}
}
pause() {
this.isPaused = true;
}
resume() {
this.isPaused = false;
this.type();
}
reset() {
this.currentTextIndex = 0;
this.currentCharIndex = 0;
this.element.textContent = '';
this.isPaused = false;
this.type();
}
setSpeed(speed) {
this.options.typeSpeed = speed;
}
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Utilisation
const typewriter = new TypewriterEffect(
document.getElementById('typewriter-content'),
['Bonjour le monde !', 'Bienvenue sur EXTRIZY', 'Découvrez nos composants'],
{ typeSpeed: 100, deleteSpeed: 50, pauseTime: 2000 }
);