Typewriter Command Button
ボタンテキストがタイプライター風に順番に切り替わるCTA。anime.jsで文字送り。
HTML
<button class="tcb-btn" id="tcb-btn"><span class="tcb-text" id="tcb-text"></span><span class="tcb-cursor">|</span></button>
CSS
.tcb-btn {
display: inline-flex;
align-items: center;
padding: 12px 28px;
background: #18181b;
color: #a3e635;
border: 1px solid #334155;
border-radius: 6px;
font-size: 14px;
font-weight: 600;
font-family: 'Courier New', monospace;
cursor: pointer;
min-width: 180px;
}
.tcb-cursor {
animation: tcb-blink 0.8s step-end infinite;
margin-left: 2px;
}
@keyframes tcb-blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
JavaScript
const words = ['npm install', 'git commit', 'deploy now', 'run tests'];
const el = document.getElementById('tcb-text');
let wi = 0;
function typeWord() {
const word = words[wi % words.length];
let ci = 0;
el.textContent = '';
const typing = anime({
duration: word.length * 80,
easing: 'linear',
update: function(anim) {
const idx = Math.floor(anim.progress / 100 * word.length);
el.textContent = word.substring(0, idx + 1);
},
complete: function() {
el.textContent = word;
setTimeout(function() {
anime({
duration: word.length * 50,
easing: 'linear',
update: function(anim) {
const idx = word.length - Math.floor(anim.progress / 100 * word.length);
el.textContent = word.substring(0, idx);
},
complete: function() {
wi++;
setTimeout(typeWord, 300);
}
});
}, 1200);
}
});
}
typeWord();