Typing Effect

ターミナル風のタイピングエフェクト。
文字の追加・削除をループするアニメーションです。

Demo

HTML index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Typing Effect</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="terminal">
    <div class="terminal-header">
      <div class="terminal-buttons">
        <span class="btn close"></span>
        <span class="btn minimize"></span>
        <span class="btn maximize"></span>
      </div>
      <div class="terminal-title">terminal</div>
    </div>
    <div class="terminal-body">
      <div class="typing-container">
        <span class="prompt">$</span>
        <span class="typed-text"></span>
        <span class="cursor"></span>
      </div>
    </div>
  </div>
  <script src="script.js"></script>
</body>
</html>

CSS style.css

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  font-family: 'Courier New', monospace;
  padding: 20px;
}

.terminal {
  width: 100%;
  max-width: 700px;
  background: #1e1e1e;
  border-radius: 10px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}

.terminal-header {
  background: #2d2d2d;
  padding: 10px 15px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.terminal-buttons {
  display: flex;
  gap: 8px;
}

.btn {
  width: 12px;
  height: 12px;
  border-radius: 50%;
}

.btn.close {
  background: #ff5f56;
}

.btn.minimize {
  background: #ffbd2e;
}

.btn.maximize {
  background: #27c93f;
}

.terminal-title {
  color: #8b8b8b;
  font-size: 0.9rem;
  flex: 1;
  text-align: center;
}

.terminal-body {
  padding: 20px;
  min-height: 200px;
  color: #00ff00;
  font-size: 1.2rem;
  line-height: 1.6;
}

.typing-container {
  display: flex;
  align-items: center;
  gap: 8px;
}

.prompt {
  color: #00ff00;
  font-weight: bold;
}

.typed-text {
  color: #00ff00;
}

.cursor {
  display: inline-block;
  width: 10px;
  height: 1.2em;
  background: #00ff00;
  animation: blink 1s infinite;
}

@keyframes blink {
  0%, 50% {
    opacity: 1;
  }
  51%, 100% {
    opacity: 0;
  }
}

/* レスポンシブ */
@media (max-width: 768px) {
  .terminal-body {
    font-size: 1rem;
    padding: 15px;
  }

  .terminal-title {
    font-size: 0.8rem;
  }
}

JS script.js

const typedTextElement = document.querySelector('.typed-text');
const cursor = document.querySelector('.cursor');

const textArray = [
  'Hello, World!',
  'Welcome to Code Bits',
  'I love coding...',
  'HTML CSS JavaScript'
];

let textArrayIndex = 0;
let charIndex = 0;
let isDeleting = false;
let typingDelay = 100;
let erasingDelay = 50;
let newTextDelay = 2000;

function type() {
  const currentText = textArray[textArrayIndex];

  if (!isDeleting) {
    // タイピング中
    typedTextElement.textContent = currentText.substring(0, charIndex + 1);
    charIndex++;

    if (charIndex === currentText.length) {
      // テキスト完成、待機後に削除開始
      isDeleting = true;
      setTimeout(type, newTextDelay);
      return;
    }
  } else {
    // 削除中
    typedTextElement.textContent = currentText.substring(0, charIndex - 1);
    charIndex--;

    if (charIndex === 0) {
      // 削除完了、次のテキストへ
      isDeleting = false;
      textArrayIndex = (textArrayIndex + 1) % textArray.length;
    }
  }

  const delay = isDeleting ? erasingDelay : typingDelay;
  setTimeout(type, delay);
}

// 開始
setTimeout(type, 1000);

// クリックでアニメーション速度変更
const terminal = document.querySelector('.terminal');
terminal.addEventListener('click', () => {
  if (typingDelay === 100) {
    typingDelay = 50;
    erasingDelay = 25;
  } else {
    typingDelay = 100;
    erasingDelay = 50;
  }
});

Download

すべてのファイルをZIP形式でダウンロードできます。