Scratch と同じように「ステージ」と「スプライト」を JavaScript で用意しよう
Scratch では、新しいプロジェクトを作るだけで、ステージとスプライトが最初から出てきます。
このレッスンでは、JavaScript でも同じように「ステージ」と「まんなかにいるスプライト」を用意してみます。まだ動きはつけませんが、これが今後のレッスンの土台になります。
この黒いわくの中が「ステージ」。まんなかに、ペンギンのスプライトが1ついます。
Scratch で新しいプロジェクトを作ると、右側の白い画面(ステージ)に、ねこのスプライトが最初からいます。
Scratch では自動で用意されるステージとスプライトを、JavaScript では自分で作る必要があります。以下は、その対応関係です。
プロジェクトを新規作成
↓
ステージとスプライトが自動で表示される
Scratch では、何もしなくてもステージとスプライトが最初から用意されています。
<div class="stage">
<img class="sprite" src="sprite.svg">
</div>
<style>
.stage {
border: 4px solid #000;
}
.sprite {
position: absolute;
left: 50%; top: 50%;
transform: translate(-50%, -50%);
}
</style>
JavaScript では、HTML でステージの「箱」を作り、CSS でスプライトを「まんなか」に配置します。
以下は、1行ずつの解説です。左側がコード、右側が説明です。
<!DOCTYPE html>
このファイルがHTML5の文書であることを宣言します。ブラウザが正しく表示するための最初の1行です。
<html lang="ja">
HTMLファイル全体の開始タグ。lang="ja"で日本語のページだと伝えます。
<head>
ページの設定情報を書く部分の開始。ここに書いたものは画面には表示されません。
<meta charset="UTF-8" />
文字コードをUTF-8に設定。日本語を正しく表示するために必要です。
<title>レッスン0:ステージを用意しよう</title>
ブラウザのタブに表示されるページタイトルを設定します。
<style>
CSS(見た目のルール)を書く部分の開始タグ。
/* 全体のリセット&基本スタイル */
コメント(メモ)。プログラムの動作には影響しません。
*, *::before, *::after {
すべての要素に対するスタイル設定の開始。*は「全部」という意味です。
box-sizing: border-box;
要素のサイズ計算方法を設定。枠線や余白を含めたサイズになります。
}
スタイル設定の終わり。
(空行)読みやすくするための改行です。
body {
ページ全体(body要素)のスタイル設定を開始します。
margin: 0;
ページの外側の余白をゼロにします。
min-height: 100vh;
ページの最小の高さを画面いっぱい(100vh = 画面の高さ100%)に設定。
background: #ffffff;
背景色を白(#ffffff)に設定します。
font-family: system-ui, -apple-system, sans-serif;
文字のフォント(書体)を設定。システムの標準フォントを使います。
display: flex;
中身を横並びに配置できるモードにします。
justify-content: center;
中身を横方向の中央に配置します。
}
bodyのスタイル設定の終わり。
(空行)
/* コンテンツ本体 */
コメント:次からはページの本体部分のスタイルです。
.page {
class="page"という名前の要素のスタイル設定を開始。
width: min(1100px, 100% - 32px);
幅を「1100pxか画面幅-32pxの小さい方」に設定。画面に合わせて自動調整されます。
padding: 24px 16px 32px;
内側の余白を設定。上24px、左右16px、下32pxの余白ができます。
display: flex;
中身を並べて配置できるモードにします。
flex-direction: column;
中身を縦方向(column = 列)に並べます。
gap: 24px;
中身の要素同士の間隔を24pxに設定します。
}
.pageのスタイル設定の終わり。
(空行)
/* タイトル部 */
コメント:次からはタイトル部分のスタイルです。
.page-title {
class="page-title"の要素(ページタイトル)のスタイル開始。
font-size: 1.4rem;
文字の大きさを1.4rem(標準の1.4倍)に設定。
font-weight: 700;
文字を太字(700 = 太い)にします。
margin: 0;
外側の余白をゼロにします。
}
.page-titleのスタイル設定の終わり。
(空行)
.page-subtitle {
class="page-subtitle"の要素(サブタイトル)のスタイル開始。
font-size: 0.95rem;
文字の大きさを0.95rem(標準より少し小さめ)に設定。
color: #555;
文字色を灰色(#555)にします。
margin: 4px 0 0;
上に4pxの余白、左右と下は0の余白を設定。
}
.page-subtitleのスタイル設定の終わり。
(空行)
/* ステージ周り */
コメント:次からはステージ周りのスタイルです。
.stage-section {
class="stage-section"の要素のスタイル開始。
display: flex;
中身を並べて配置できるモードにします。
flex-direction: column;
中身を縦方向に並べます。
align-items: center;
中身を横方向の中央に配置します。
gap: 12px;
中身の要素同士の間隔を12pxに設定。
}
.stage-sectionのスタイル設定の終わり。
(空行)
.stage-label {
class="stage-label"の要素(ラベル)のスタイル開始。
font-size: 0.9rem;
文字の大きさを0.9rem(標準より少し小さめ)に設定。
color: #666;
文字色を灰色(#666)にします。
}
.stage-labelのスタイル設定の終わり。
(空行)
/* スプライトが動く枠(ステージ) */
コメント:次からはステージ本体のスタイルです。
.stage {
class="stage"の要素(ステージ)のスタイル開始。ここが重要です!
width: 80%;
幅を親要素の80%に設定。
max-width: 960px;
最大の幅を960pxに制限します。これ以上大きくなりません。
height: 432px;
高さを432pxに固定します。
border: 4px solid #000;
4pxの黒い(#000)実線の枠線を付けます。Scratchのステージと同じ!
background-color: #f7f7f7;
背景色を薄い灰色(#f7f7f7)に設定。
position: relative;
中の要素を自由に配置できるようにします。スプライトを動かすために必要!
overflow: hidden;
ステージからはみ出た部分を隠します。
margin: 0 auto;
左右の余白を自動調整して、ステージを中央に配置します。
}
.stageのスタイル設定の終わり。
(空行)
/* SVGスプライト */
コメント:次からはスプライトのスタイルです。
.sprite {
class="sprite"の要素(スプライト)のスタイル開始。ここも重要!
position: absolute;
自由な位置に配置できるようにします。ステージ内で動かせるようになります!
left: 50%;
左端から50%の位置に配置。
top: 50%;
上端から50%の位置に配置。
width: 96px;
スプライトの幅を96pxに設定。
height: 96px;
スプライトの高さを96pxに設定。
transform: translate(-50%, -50%);
スプライトを自分の幅・高さの半分だけずらして、本当の中央に配置します。
pointer-events: none;
マウスのクリックを無視します。スプライトを通り抜けられるようにします。
}
.spriteのスタイル設定の終わり。
(空行)
/* スマホ向け調整 */
コメント:次からはスマホ用の調整です。
@media (max-width: 600px) {
画面幅が600px以下の場合(スマホなど)に適用されるスタイルの開始。
.stage {
スマホ用のステージのスタイル開始。
width: 90%;
スマホでは幅を90%に広げます。
height: 300px;
スマホでは高さを300pxに縮小します。
}
スマホ用.stageスタイルの終わり。
.sprite {
スマホ用のスプライトのスタイル開始。
width: 72px;
スマホではスプライトの幅を72pxに縮小。
height: 72px;
スマホではスプライトの高さを72pxに縮小。
}
スマホ用.spriteスタイルの終わり。
}
メディアクエリ(スマホ用設定)の終わり。
</style>
CSSの部分の終わりタグ。
</head>
head部分(設定情報)の終わりタグ。
<body>
body(画面に表示される部分)の開始タグ。ここから実際に見える内容が始まります。
<main class="page">
main要素でページの主要コンテンツを囲む。class="page"で先ほどのCSSが適用されます。
<header>
ページのヘッダー部分の開始タグ。
<h1 class="page-title">レッスン0:ステージを用意しよう</h1>
h1(大見出し)でページタイトルを表示。class="page-title"で太字・大きめに表示されます。
<p class="page-subtitle">
p(段落)でサブタイトルの開始。class="page-subtitle"で灰色・小さめに表示されます。
スプライトを動かす前に、まずはステージとスプライトの見た目だけを用意します。
サブタイトルの本文テキスト。
</p>
p(段落)の終わりタグ。
</header>
headerの終わりタグ。
(空行)
<section class="stage-section">
section要素でステージ部分を囲む。class="stage-section"で中央配置されます。
<div class="stage-label">スプライトが動くステージ</div>
ステージの説明ラベルを表示。
<div class="stage">
ステージの箱を作成!class="stage"で黒枠・灰色背景のステージになります。
<img class="sprite" src="./images/chara00.svg" alt="主人公スプライト" />
img要素でスプライトの画像を表示。class="sprite"でステージの中央に配置されます。
</div>
ステージの終わりタグ。
</section>
sectionの終わりタグ。
</main>
mainの終わりタグ。
(空行)
<script>
JavaScript(プログラム)を書く部分の開始タグ。
// スプライトの移動・回転・拡大縮小を管理する変数
コメント:次からスプライトを動かすための変数を用意します。
let spriteX = 0; // 横方向オフセット
変数spriteXを作成。横方向の移動量を保存します。最初は0(中央)。
let spriteY = 0; // 縦方向オフセット
変数spriteYを作成。縦方向の移動量を保存します。最初は0(中央)。
let spriteAngle = 0; // 回転角度
変数spriteAngleを作成。回転の角度を保存します。最初は0度。
let spriteScale = 1; // 拡大縮小率
変数spriteScaleを作成。大きさの倍率を保存します。最初は1倍(標準サイズ)。
(空行)
function updateSpriteTransform() {
関数updateSpriteTransformを定義。スプライトの表示を更新する処理をまとめています。
const sprite = document.querySelector(".sprite");
HTML内のclass="sprite"の要素を探して、変数spriteに保存します。
sprite.style.transform =
スプライトのtransform(変形)スタイルを設定開始。
`translate(-50%, -50%) translate(${spriteX}px, ${spriteY}px) ` +
まず中央配置し、次にspriteX、spriteYの値だけ移動します。
`rotate(${spriteAngle}deg) scale(${spriteScale})`;
spriteAngleの角度だけ回転し、spriteScaleの倍率で拡大縮小します。
}
関数updateSpriteTransformの終わり。
(空行)
// 現時点では1回だけ呼び出し(初期表示)
コメント:今は1回だけ実行します。次のレッスンで何度も実行するようになります。
updateSpriteTransform();
updateSpriteTransform関数を実行。スプライトが中央に表示されます。
</script>
JavaScriptの部分の終わりタグ。
</body>
bodyの終わりタグ。
</html>
HTMLファイルの終わりタグ。これで完了です!
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>レッスン0:ステージを用意しよう</title>
<style>
/* 全体のリセット&基本スタイル */
*, *::before, *::after {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
background: #ffffff;
font-family: system-ui, -apple-system, sans-serif;
display: flex;
justify-content: center;
}
/* コンテンツ本体 */
.page {
width: min(1100px, 100% - 32px);
padding: 24px 16px 32px;
display: flex;
flex-direction: column;
gap: 24px;
}
/* タイトル部 */
.page-title {
font-size: 1.4rem;
font-weight: 700;
margin: 0;
}
.page-subtitle {
font-size: 0.95rem;
color: #555;
margin: 4px 0 0;
}
/* ステージ周り */
.stage-section {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
}
.stage-label {
font-size: 0.9rem;
color: #666;
}
/* スプライトが動く枠(ステージ) */
.stage {
width: 80%;
max-width: 960px;
height: 432px;
border: 4px solid #000;
background-color: #f7f7f7;
position: relative;
overflow: hidden;
margin: 0 auto;
}
/* SVGスプライト */
.sprite {
position: absolute;
left: 50%;
top: 50%;
width: 96px;
height: 96px;
transform: translate(-50%, -50%);
pointer-events: none;
}
/* スマホ向け調整 */
@media (max-width: 600px) {
.stage {
width: 90%;
height: 300px;
}
.sprite {
width: 72px;
height: 72px;
}
}
</style>
</head>
<body>
<main class="page">
<header>
<h1 class="page-title">レッスン0:ステージを用意しよう</h1>
<p class="page-subtitle">
スプライトを動かす前に、まずはステージとスプライトの見た目だけを用意します。
</p>
</header>
<section class="stage-section">
<div class="stage-label">スプライトが動くステージ</div>
<div class="stage">
<img class="sprite" src="./images/chara00.svg" alt="主人公スプライト" />
</div>
</section>
</main>
<script>
// スプライトの移動・回転・拡大縮小を管理する変数
let spriteX = 0; // 横方向オフセット
let spriteY = 0; // 縦方向オフセット
let spriteAngle = 0; // 回転角度
let spriteScale = 1; // 拡大縮小率
function updateSpriteTransform() {
const sprite = document.querySelector(".sprite");
sprite.style.transform =
`translate(-50%, -50%) translate(${spriteX}px, ${spriteY}px) ` +
`rotate(${spriteAngle}deg) scale(${spriteScale})`;
}
// 現時点では1回だけ呼び出し(初期表示)
updateSpriteTransform();
</script>
</body>
</html>
このプログラムで特に押さえておきたい 3 つのポイントを紹介します。
親要素(ステージ)を relative にすることで、子要素(スプライト)を absolute で自由に配置できるようになります。
スプライトの左上角を、ステージの中心(50%, 50%)に配置します。ただしこれだけでは中心からずれてしまいます。
スプライトを自身の幅・高さの半分だけずらすことで、スプライトの中心がステージの中心に来るように調整します。
Scratch 版と JavaScript 版、それぞれの完成したプロジェクトを確認できます。
学んだコードを改造して、さらに面白い見た目に挑戦してみましょう!
CSS の border: 4px solid #000; の #000 を #f00(赤)や #00f(青)に変えて、枠の色を変えてみよう。