こんにちは😊
株式会社プロドウガの@YushiYamamotoです!
らくらくサイトの開発・運営を担当しながら、React.js・Next.js専門のフリーランスエンジニアとしても活動しています❗️
今回は、Webフォントを楽しく学べる「フォントスロット」というブラウザゲームの作り方をご紹介します。CDNFontsのディスプレイフォントを使って、スロットマシンのようにフォントが切り替わる面白いゲームを一緒に作っていきましょう!
See the Pen Untitled by Yushi Yamamoto (@yamamotoyushi) on CodePen.
🎯 今回作るもの
今回作成するのは、ボタンを押すとランダムにフォントが切り替わり、もう一度ボタンを押すと停止する「フォントスロット」ゲームです。
- CDNFontsのディスプレイフォントを使用
- スタート・ストップボタンでフォントの切り替えを制御
- 表示されるテキスト自体がそのフォントで表示される
🛠️ 開発環境
特別な開発環境は必要ありません。テキストエディタとブラウザがあれば作成できます。
📚 CDNFontsとは?
CDNFontsは、無料で使えるWebフォントを提供しているサービスです。Google Fontsと同様に、CDNを通じてフォントを簡単に利用できます。今回は特にディスプレイカテゴリのフォントを使用します。このカテゴリには13,000種類以上の個性的なフォントが揃っています!
🚀 実装手順
1. HTMLの基本構造を作成
まずは、HTMLの基本構造を作成します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>フォントスロット</title>
<!-- フォントのリンクはここに追加 -->
<style>
/* CSSスタイルはここに記述 */
</style>
</head>
<body>
<div class="container">
<h1>フォントスロット</h1>
<div class="link-section">
フォントの詳細や追加のフォントは、以下のリンクから確認できます:<br>
<a href="https://fonts.cdnfonts.com/category/display" target="_blank">https://fonts.cdnfonts.com/category/display</a>
</div>
<div id="font-display" class="font-display">フォントスロット</div>
<div class="buttons">
<button id="start-button">スタートボタン</button>
<button id="stop-button" disabled>ストップボタン</button>
</div>
</div>
<script>
// JavaScriptコードはここに記述
</script>
</body>
</html>
2. 使用するフォントを読み込む
CDNFontsから使用したいフォントを選び、<head>
タグ内に読み込みコードを追加します。
<head>
<!-- 前略 -->
<link href="https://fonts.cdnfonts.com/css/dasher" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/supernova" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/gemseatrial" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/wondrous" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/jumbotron" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/flavor-mellow" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/ovum" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/echelon" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/snowmas" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/bagel-fat-one" rel="stylesheet">
<!-- 後略 -->
</head>
フォントはCDNFontsのディスプレイカテゴリから好きなものを選べます。各フォントの詳細ページにリンクタグが表示されるので、それをコピーして使用します。
3. CSSでスタイルを設定
見た目を整えるためのCSSを追加します。
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
h1 {
margin-bottom: 20px;
}
.container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: white;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.font-display {
height: 150px;
display: flex;
align-items: center;
justify-content: center;
font-size: 48px;
margin: 30px 0;
padding: 20px;
border: 2px solid #ddd;
border-radius: 8px;
background-color: #f9f9f9;
}
.buttons {
margin-top: 20px;
}
button {
padding: 10px 20px;
margin: 0 10px;
font-size: 16px;
cursor: pointer;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
}
button:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
.link-section {
margin-top: 20px;
font-size: 14px;
}
4. JavaScriptでスロット機能を実装
最後に、JavaScriptでスロット機能を実装します。
const fonts = [
'DASHER', 'Supernova', 'GEMSEAtrial', 'Wondrous', 'JUMBOTRON',
'Flavor Mellow', 'Ovum', 'ECHELON', 'SNOWMAS', 'Bagel Fat One'
];
const fontDisplay = document.getElementById('font-display');
const startButton = document.getElementById('start-button');
const stopButton = document.getElementById('stop-button');
let slotInterval;
let isRunning = false;
startButton.addEventListener('click', () => {
if (!isRunning) {
startSlot();
}
});
stopButton.addEventListener('click', () => {
if (isRunning) {
stopSlot();
}
});
function startSlot() {
isRunning = true;
startButton.disabled = true;
stopButton.disabled = false;
slotInterval = setInterval(() => {
const randomFont = fonts[Math.floor(Math.random() * fonts.length)];
fontDisplay.style.fontFamily = randomFont;
fontDisplay.textContent = randomFont;
}, 100);
}
function stopSlot() {
clearInterval(slotInterval);
isRunning = false;
startButton.disabled = false;
stopButton.disabled = true;
}
🔍 コードの解説
HTMLの構造
-
container
クラスで全体を囲み、中央に配置 -
font-display
要素がフォントを表示する部分 - スタートとストップの2つのボタンを配置
CSSのポイント
-
font-display
クラスは高さを固定し、中央揃えにすることで、フォントが切り替わっても表示位置が安定 - ボタンは
disabled
状態のスタイルも設定し、使用できないときを視覚的に表現
JavaScriptの仕組み
- フォント名の配列を定義
- スタートボタンクリック時に
setInterval
でフォントをランダムに切り替え - ストップボタンクリック時に
clearInterval
で停止 - ボタンの有効/無効状態を適切に管理
🧩 フォントスロットの動作フロー
🔧 カスタマイズのアイデア
このフォントスロットは基本的な機能だけですが、以下のようにカスタマイズすることで、より楽しいゲームにできます:
1. フォントの追加
// より多くのフォントを追加
const fonts = [
'DASHER', 'Supernova', 'GEMSEAtrial', 'Wondrous', 'JUMBOTRON',
'Flavor Mellow', 'Ovum', 'ECHELON', 'SNOWMAS', 'Bagel Fat One',
// 追加フォント
'Caveat', 'Pacifico', 'Lobster', 'Comic Neue', 'Dancing Script'
];
追加するフォントは必ず<head>
タグ内にもリンクを追加してください。
2. 表示テキストのカスタマイズ
// 表示するテキストをフォント名以外に変更
function startSlot() {
// 前略
slotInterval = setInterval(() => {
const randomFont = fonts[Math.floor(Math.random() * fonts.length)];
fontDisplay.style.fontFamily = randomFont;
fontDisplay.textContent = "Hello World!"; // フォント名ではなく固定テキスト
}, 100);
}
3. 速度調整機能の追加
// スロットの回転速度を調整するスライダーを追加
const speedSlider = document.getElementById('speed-slider');
let speed = 100; // デフォルト速度
speedSlider.addEventListener('input', (e) => {
speed = 200 - e.target.value; // 1-100のスライダー値を200-100の速度に変換
});
function startSlot() {
// 前略
slotInterval = setInterval(() => {
// 中略
}, speed);
}
4. 複数のスロットリールの実装
複数のテキスト要素を用意し、それぞれ独立してフォントが変わるようにすることで、本格的なスロットマシンのような体験ができます。
複数リール対応コード
// 3つのリールを持つフォントスロット
const reels = document.querySelectorAll('.font-reel');
const startButton = document.getElementById('start-button');
const stopButton = document.getElementById('stop-button');
let reelIntervals = [];
let isRunning = false;
startButton.addEventListener('click', () => {
if (!isRunning) {
startAllReels();
}
});
stopButton.addEventListener('click', () => {
if (isRunning) {
stopNextReel();
}
});
function startAllReels() {
isRunning = true;
startButton.disabled = true;
stopButton.disabled = false;
reels.forEach((reel, index) => {
reelIntervals[index] = setInterval(() => {
const randomFont = fonts[Math.floor(Math.random() * fonts.length)];
reel.style.fontFamily = randomFont;
reel.textContent = randomFont;
}, 100);
});
}
let stoppedReels = 0;
function stopNextReel() {
if (stoppedReels < reels.length) {
clearInterval(reelIntervals[stoppedReels]);
stoppedReels++;
if (stoppedReels === reels.length) {
isRunning = false;
startButton.disabled = false;
stopButton.disabled = true;
stoppedReels = 0;
}
}
}
📝 完成したコード
完全なHTMLコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>フォントスロット</title>
<link href="https://fonts.cdnfonts.com/css/dasher" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/supernova" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/gemseatrial" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/wondrous" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/jumbotron" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/flavor-mellow" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/ovum" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/echelon" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/snowmas" rel="stylesheet">
<link href="https://fonts.cdnfonts.com/css/bagel-fat-one" rel="stylesheet">
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
h1 {
margin-bottom: 20px;
}
.container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: white;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.font-display {
height: 150px;
display: flex;
align-items: center;
justify-content: center;
font-size: 48px;
margin: 30px 0;
padding: 20px;
border: 2px solid #ddd;
border-radius: 8px;
background-color: #f9f9f9;
}
.buttons {
margin-top: 20px;
}
button {
padding: 10px 20px;
margin: 0 10px;
font-size: 16px;
cursor: pointer;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
}
button:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
.link-section {
margin-top: 20px;
font-size: 14px;
}
</style>
</head>
<body>
<div class="container">
<h1>フォントスロット</h1>
<div class="link-section">
フォントの詳細や追加のフォントは、以下のリンクから確認できます:<br>
<a href="https://fonts.cdnfonts.com/category/display" target="_blank">https://fonts.cdnfonts.com/category/display</a>
</div>
<div id="font-display" class="font-display">フォントスロット</div>
<div class="buttons">
<button id="start-button">スタートボタン</button>
<button id="stop-button" disabled>ストップボタン</button>
</div>
</div>
<script>
const fonts = [
'DASHER', 'Supernova', 'GEMSEAtrial', 'Wondrous', 'JUMBOTRON',
'Flavor Mellow', 'Ovum', 'ECHELON', 'SNOWMAS', 'Bagel Fat One'
];
const fontDisplay = document.getElementById('font-display');
const startButton = document.getElementById('start-button');
const stopButton = document.getElementById('stop-button');
let slotInterval;
let isRunning = false;
startButton.addEventListener('click', () => {
if (!isRunning) {
startSlot();
}
});
stopButton.addEventListener('click', () => {
if (isRunning) {
stopSlot();
}
});
function startSlot() {
isRunning = true;
startButton.disabled = true;
stopButton.disabled = false;
slotInterval = setInterval(() => {
const randomFont = fonts[Math.floor(Math.random() * fonts.length)];
fontDisplay.style.fontFamily = randomFont;
fontDisplay.textContent = randomFont;
}, 100);
}
function stopSlot() {
clearInterval(slotInterval);
isRunning = false;
startButton.disabled = false;
stopButton.disabled = true;
}
</script>
</body>
</html>
✅ 技術的なポイント
フォントスロットの実装には、以下の技術的なポイントがあります:
-
Webフォントの読み込み:CDNFontsのCSSリンクを使用して、外部フォントを簡単に読み込めます
-
setInterval/clearInterval:JavaScriptのタイマー機能を使って、フォントの切り替えとその停止を制御
-
DOM操作:
style.fontFamily
プロパティを動的に変更することで、表示フォントをリアルタイムに切り替え -
イベントハンドリング:ボタンクリックイベントを適切に処理し、ユーザー操作に応じた挙動を実現
-
状態管理:
isRunning
変数を使って、スロットの状態(回転中か停止中か)を管理
🎮 ゲーム開発の応用例
このフォントスロットの仕組みは、他のブラウザゲーム開発にも応用できます:
- カードゲーム:カードをランダムに表示するスロット
- 言語学習ゲーム:単語や文字をランダムに表示して学習
- クイズゲーム:問題をランダムに出題するシステム
🚀 発展的な機能
より高度なフォントスロットを作りたい場合は、以下の機能を追加することを検討してみてください:
- フォント情報の表示:選ばれたフォントの詳細情報(作者、スタイルなど)を表示
- お気に入り機能:気に入ったフォントをお気に入りに登録できる機能
- カテゴリ分け:フォントをカテゴリ別に分けて、特定のカテゴリだけで回す機能
- アニメーション効果:フォント切り替え時のトランジション効果の追加
2025年3月現在、CDNFontsには13,000種類以上のディスプレイフォントがありますが、すべてのフォントが常に利用可能とは限りません。使用前に各フォントの利用規約を確認することをお勧めします。
📱 モバイル対応のポイント
モバイルデバイスでもスムーズに動作させるためには、以下の点に注意しましょう:
- レスポンシブデザインの採用
- タッチ操作に適したボタンサイズの設定
- モバイルでのフォント読み込み時間を考慮した最適化
🔮 まとめ
今回は、CDNFontsのディスプレイフォントを活用した「フォントスロット」ゲームの作り方を紹介しました。シンプルなHTMLとCSS、JavaScriptだけで、楽しいインタラクティブなゲームが作れることがわかりました。
このようなミニゲームは、ウェブサイトのエンゲージメント向上や、フォント選びのインスピレーション源として活用できます。また、JavaScriptの基本的な概念(DOM操作、タイマー処理、イベントハンドリングなど)を学ぶ良い教材にもなります。
ぜひ自分なりにカスタマイズして、オリジナルのフォントスロットを作ってみてください!
最後に:業務委託のご相談を承ります
私は業務委託エンジニアとしてWEB制作やシステム開発を請け負っています。最新技術を活用したレスポンシブなWebサイト制作、インタラクティブなアプリケーション開発、API連携など幅広いご要望に対応可能です。
「課題解決に向けた即戦力が欲しい」「高品質なWeb制作を依頼したい」という方は、お気軽にご相談ください。一緒にビジネスの成長を目指しましょう!
👉 ポートフォリオ
🌳 らくらくサイト