CSS Sprite

CSS(Cascading Style Sheets) を使って画像を切り抜いて描画する手法を CSS Sprite などと呼んでいます。
HTMLでは文書構造のみを定義して、スタイルについてはスタイルシートで指定することが推奨されています。
JavaScript と CSS は別物ですが、JavaScript でゲームを作成するとき CSS の機能が良く使われます。
CSS(Cascading Style Sheets) は実行環境に左右されます。
2014/11 現在、プログラムは Windows8.1 & Internet Explorer11 の環境で確認しています。
2017/07 現在、プログラムは Windows10 & Microsoft Edge 40.15063.0.0 の環境で確認しています。
CSS の基礎は CSS Before CSS After などを参照して下さい。

スタイルシートを使うと様々な利点があるのですが、最もよく使われるものは先に説明した 自由に配置 でしょうか。
Cascading Style Sheets を使うと次のような利点があります。

CSS Sprite を使ったときの注意点です。
通常の HTML で描画したものと CSS Sprite で描画したものが重なったり隠れたりすることがあり、画面のレイアウトに注意が必要です。
画像を切り抜いて描画したとき、全体画像が配置された状態から矩形領域部分だけが描画されます。
  1. 画像を切り抜いて描画


    1. プログラムを起動すると ffx2s.jpg の画像から一部を切り抜いた画像が描画されます。
      "javascript.css" は、私が作成した Javascript ページ用の CSS で HTML と同じフォルダーに格納しています。
      "ffx2s.jpg" は親フォルダーに作成されている ../img/ に格納されています。
      【css_rect.html】
      <html>
      <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-16">
      <link rel="stylesheet" href="javascript.css" type="text/css">
      <title>css rect</title>
      </head>
      
      <body>
      <img src="../img/ffx2s.jpg" style="clip:rect(0px,240px,120px,0px);
        position:absolute">
      
      <img src="../img/ffx2s.jpg" style="clip:rect(0px,120px,80px,20px);
        position:absolute;left:0px;top:200px;">
      
      <img src="../img/ffx2s.jpg" style="clip:rect(0px,200px,80px,120px);
        position:absolute;left:0px;top:300px;">
      
      <img src="../img/ffx2s.jpg" style="clip:rect(0px,200px,80px,120px);
        position:absolute;left:-100px;top:400px;">
      
      </body>
      </html>
      
    2. 画像全体を描画します。
      全体のサイズは 240*120 ピクセルなので、rect では「上, 右, 下, 左」の順に指定します。
      0,0 が左上の座標で、240,120 が右下の座標です。
      position:absolute なので画像は座標 0,0 に描画されます。
      <img src="../img/ffx2s.jpg" style="clip:rect(0px,240px,120px,0px);
        position:absolute">
      
    3. 左の人物を切り分けて描画します。
      左の人物の座標は、左上が 0,20 で右下が 120,80 です。
      top:200px; で画像全体の下に描画します。
      <img src="../img/ffx2s.jpg" style="clip:rect(0px,120px,80px,20px);
        position:absolute;left:0px;top:200px;">
      
    4. 右の人物を切り分けて描画します。
      右の人物の座標は、左上が 0,120 で右下が 200,80 です。
      top:300px; で左の人物の下に描画します。
      left: の値は左の人物と同じですが、元の全体画像の左端が 0px に合わせられるので、その分右に移動します。
      人物をもっと左に寄せようと思えば、left: の値をマイナスにしなければなりません。
      <img src="../img/ffx2s.jpg" style="clip:rect(0px,200px,80px,120px);
        position:absolute;left:0px;top:300px;">
      
    5. 右の人物をもっと左に寄せて描画します。
      left:-100px; で 100 ピクセル左に寄せます。
      <img src="../img/ffx2s.jpg" style="clip:rect(0px,200px,80px,120px);
        position:absolute;left:-100px;top:400px;">
      

  2. CSS Position

    1. ffx2s.jpg を「縦に pos の位置から 100px 切り取って」描画します。
      【css_pos.html】
      <html>
      <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-16">
      <link rel="stylesheet" href="javascript.css" type="text/css">
      <script type="text/javascript">
        function cut(pos)
        { var s1 = '(0px,' + (pos+100) + 'px,120px,' + pos + 'px)';
          var s2 = pos + 'px;top:0px;">';
          var s = '<img src="../img/ffx2s.jpg" style="clip:rect' + s1 + '; position:absolute;left:-' + s2;
          document.write(s);
        }
      </script>
      
      <body>
      <script type="text/javascript">
        //cut(20);
        cut(110);
      </script>
      </body>
      </html>
      
    2. 画像を幅 100px で縦に切り取る関数です。
      rect は「上, 右, 下, 左」の順に切り取る位置を指定します。
      window.alert(s); は画像を切り取るソースコードの確認です。
        function cut(pos)
        { var s1 = '(0px,' + (pos+100) + 'px,120px,' + pos + 'px)';
          var s2 = pos + 'px;top:0px;">';
          var s = '<img src="../img/ffx2s.jpg" style="clip:rect' + s1 + '; position:absolute;left:-' + s2;
      //window.alert(s);
          document.write(s);
        }
      
    3. cut(20); で左の人物を切り取ります。
      cut(110); で右の人物を切り取ります。
        //cut(20);
        cut(110);
      

  3. CSS Scroll


    1. 画像のスクロールでは CSS ファイル(jQuery など)を使った例をよく見かけます。
      それでは根本的なことが解らないので CSS ファイルを使わずに背景画像を横にスクロールします。
      【css_scroll.html】
      <html>
      <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-16">
      <title>Scroll</title>
      <script type="text/javascript">
        function cut(pos)
        { var s1 = '(0px,' + (640+pos) + 'px,480px,' + pos + 'px)';
          var s2 = pos + 'px;top:0px;';
          var s = 'clip:rect' + s1 + '; position:absolute;left:-' + s2;
          return s;
        }
      </script>
      </head>
      
      <body onLoad="setInterval('scroll()',25)">
      <img src="bg2.gif" name="bg2"
        style="clip:rect(0px,640px,480px,0px); position:absolute;left:0px; top:0px;">
      
      <script type="text/javascript">
        var pos = 0;
        function scroll()
        { pos++;
          if (pos>=640)   pos = 0;
          var str = cut(pos);
      //window.alert(str);
          document.bg2.style = str;
        }
      </script>
      
      </body>
      </html>
      
    2. CSS ファイルを使わずに cut(pos) 関数で画像を切り出してスクロールします。
      "bg2.gif" は上の画像(bg.gif)を横に2枚並べた 1280×480 ドットの画像です。
      <img src="bg2.gif" name="bg2"
        style="clip:rect(0px,640px,480px,0px); position:absolute;left:0px; top:0px;">
      
    3. body から 25 ミリ秒間隔で 'scroll()' 関数を呼び出します。
      <body onLoad="setInterval('scroll()',25)">
      
    4. 'scroll()' 関数では cut(pos); で取得した String を document.bg2.style に設定することで画像をスクロールします。
      pos は画像を切り出す位置で、640 を超えると 0 に戻します。
        function scroll()
        { pos++;
          if (pos>=640)   pos = 0;
          var str = cut(pos);
      //window.alert(str);
          document.bg2.style = str;
        }
      
    5. function cut(pos) は "bg2.gif" の画像を pos の位置から幅 640 で切り出す関数です。
      CSS Position を参照して下さい。
    6. jQuery を使った例に、画面全体で背景画像をスクロールするものを見かけましたが、画面全体でスクロールするのは簡単です。
      bg.gif を横に4枚、縦に2枚並べた 2560×960 ドットの画像(bg4.gif)を作成して下さい。
      img タグは次のようになります。
      <img src="bg4.gif" name="bg4"
        style="clip:rect(0px,1280px,960px,0px); position:absolute;left:0px; top:0px;">
      
      scroll() 関数は次のようになります。
        var pos = 0;
        function scroll()
        { pos++;
          if (pos>=1280)  pos = 0;
          var str = cut(pos);
          document.bg4.style = str;
        }
      
      cut(pos) 関数は次のようになります。
        function cut(pos)
        { var s1 = '(0px,' + (1280+pos) + 'px,960px,' + pos + 'px)';
          var s2 = pos + 'px;top:0px;';
          var s = 'clip:rect' + s1 + '; position:absolute;left:-' + s2;
          return s;
        }
      

  4. CSS Image Scroll


    1. CSS ファイル(jQuery など)を使わずに ffx2.jpg の画像を右端から左に向かって流します。
      【css_image.html】
      <html>
      <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-16">
      <title>Image Scroll</title>
      <script type="text/javascript">
        function cut(pos, size, left)
        { var s1 = '(0px,' + (pos+size) + 'px,600px,' + pos + 'px)';
          var s2 = 'left:' + (left-pos) + 'px;top:0px;';
          var s = 'clip:rect' + s1 + '; position:absolute;' + s2;
          return s;
        }
      </script>
      </head>
      
      <body onLoad="setInterval('scroll()',25)">
      <img src="../img/ffx2.jpg" name="img"
        style="clip:rect(0px,0px,600px,0px); position:absolute;left:0px; top:0px;">
      
      <script type="text/javascript">
        var pos = 0;
        var size = 0;
        var left = 800;
        function scroll()
        { size++;
          left--; 
          str = cut(pos, size, left);
          document.img.style = str;
          if (size>=800)
          { size = 0;
            left = 800;
          }
        }
      </script>
      
      </body>
      </html>
      
    2. "../img/ffx2.jpg" の画像サイズは「幅=800, 高さ=600」です。
      cut(pos) 関数で「pos の位置から size の幅で切り出し、描画位置を left に設定」します。
        function cut(pos, size, left)
        { var s1 = '(0px,' + (pos+size) + 'px,600px,' + pos + 'px)';
          var s2 = 'left:' + (left-pos) + 'px;top:0px;';
          var s = 'clip:rect' + s1 + '; position:absolute;' + s2;
          return s;
        }
      
    3. cut(pos) 関数を使って画像を右から左にスクロールします。
      size が 800 になると元に戻ります。
        var pos = 0;
        var size = 0;
        var left = 800;
        function scroll()
        { size++;
          left--; 
          str = cut(pos, size, left);
          document.img.style = str;
          if (size>=800)
          { size = 0;
            left = 800;
          }
        }
      

  5. CSS File

    1. CSS File(sample.css) を使って画像を切り抜いて描画します。
      【css_file.html】
      <html>
      <head>
        <meta http-equiv="Content-Script-Type" content="text/javascript" charset="utf-16">
        <link rel="stylesheet" href="sample.css" type="text/css">
        <title>CSS File</title>
      </head>
      
      <body>
       <img src="../img/ffx2s.jpg">
       <img src="../img/ffx2s.jpg" class="sample1">
       <img src="../img/ffx2s.jpg" class="sample2">
      </body>
      </html> 
      
      【sample.css】
      img.sample1
      { clip:rect(0px,120px,80px,20px);
        position:absolute;left:0px;top:180px;
      }
      img.sample2
      { clip:rect(0px,200px,80px,120px);
        position:absolute;left:-100px;top:270px;
      }
      
    2. "sample.css" は css_file.html が格納されているフォルダーに格納します。
      css_file.html の文字コードは utf-16 ですが sample.css は Shift-JIS を使ってみました。
        <meta http-equiv="Content-Script-Type" content="text/javascript" charset="utf-16">
        <link rel="stylesheet" href="sample.css" type="text/css">
      
    3. 画像を切り抜いて描画する CSS Sprite です。
      左の人物では class="sample1" を設定して img.sample1 と関連付けます。
      右の人物では class="sample2" を設定して img.sample2 と関連付けます。
       <img src="../img/ffx2s.jpg">
       <img src="../img/ffx2s.jpg" class="sample1">
       <img src="../img/ffx2s.jpg" class="sample2">
      
    4. "sample.css" の説明です。
      画像のサイズは 240*120 ピクセルです。
      rect() は「上, 右, 下, 左」の順に指定します。
      sample2 では、X座標が -100 に設定されていることに注目して下さい。
      元の画像に対して -100 を指定すると、右の人物と左の人物が並びます。
      img.sample1
      { clip:rect(0px,120px,80px,20px);
        position:absolute;left:0px;top:180px;
      }
      img.sample2
      { clip:rect(0px,200px,80px,120px);
        position:absolute;left:-100px;top:270px;
      }
      

  6. CSS Mapchip


    Mapchip を並べて美人の画像を描画します。
    1. CSS で切り分ける Map Chip(Sprite)の情報は *.css ファイルで定義します。
      Map Chip を組み合わせて画像を構成する並び情報は .js ファイル定義します。
      これらのファイルはテキスト・エディタを使って直接タイプしても良いのですが、私が提供している Map Editor を使うと簡単に作成することが出来ます。
      私のダウンロードサイトから Map Editor をダウンロードして下さい。
      1. Mapedit.exe をダブルクリックで起動して[ファイル][開く]から "JavaS.map" を開くと JavaScript テスト用の BGMAP が表示されます。
        MapChip ファイルは JavaS.gif を使っています。
      2. [ファイル][JavaData 作成] から "javas.css" で保存して下さい。
        "javas.css" と "javas.js" のファイルが作成されます。
        アップロードに備えて、ファイル名は小文字に統一して下さい。
      3. "javas.css" と "javas.js" を使うとプログラムは非常に簡単です。
        <html>
        <head>
        <meta http-equiv="Content-Script-Type" content="text/javascript" charset="shift_jis">
        <link rel="stylesheet" href="javas.css" type="text/css">
        <title>BG MAP</title>
        </head>
        
        <body>
        <script src="javas.js"></script>
        </body>
        </html>
        
    2. Map Editor の使い方が分かった所で "bijin16.jpg" を切り分けて描画してみましょう。
      Mapedit.exe を使って "bijin.css" と "bijin.js" を作成します。
      bijin16.jpg は 60*60 の Sprite を4行4列に並べた画像です。
      1. Mapedit.exe を起動して[ファイル][Mapchip load(L)]から bijin16.jpg をロードします。
      2. [設定(S)][サイズ]から Map Size を 4,4 に、Mapchip を 60,60 に設定します。
      3. MapChip ウインドウから16枚の画像を順に貼り付けます。
        (元の画像と同じ画面を作成します)
      4. [ファイル][JavaData 作成] から "bijin.css" で保存して下さい。
        "bijin.css" と "bijin.js" のファイルが作成されます。
    3. "bijin.css" と "bijin.js" を使うとプログラムは非常に簡単です。
      "bijin.css" と "bijin.js" を HTML と同じフォルダーに格納します。
      HTML の文字コードに shift_jis を使ってみました。
      <html>
      <head>
      <meta http-equiv="Content-Script-Type" content="text/javascript" charset="shift_jis">
      <link rel="stylesheet" href="bijin.css" type="text/css">
      </head>
      
      <body>
      <script src="bijin.js"></script>
      </body>
      </html>
      
    4. <head> から "bijin.css" をリンクします。
      <link rel="stylesheet" href="bijin.css" type="text/css">
      
    5. <body> に "bijin.js" を組み込みます。
      <script src="bijin.js"></script>
      
    6. Mapedit.exe で作成した "bijin.css" のソースコードです。
      文字コードは shift_jis ですが、そのまま使います。
      #map {
          width: 240px;
          height: 240px;
      }
      #bg {
          width: 240px;
          height: 240px;
      }
      .info {
          clear: both;
          padding: 10px 0;
      }
      .chip {
          float: left;
          width: 60px;
          height: 60px;
          background-image: url("bijin16.jpg");
      }
      .c0 {background-position: -0px -0px;}
      .c1 {background-position: -60px -0px;}
      .c2 {background-position: -120px -0px;}
      .c3 {background-position: -180px -0px;}
      .c4 {background-position: -0px -60px;}
      .c5 {background-position: -60px -60px;}
      .c6 {background-position: -120px -60px;}
      .c7 {background-position: -180px -60px;}
      .c8 {background-position: -0px -120px;}
      .c9 {background-position: -60px -120px;}
      .c10 {background-position: -120px -120px;}
      .c11 {background-position: -180px -120px;}
      .c12 {background-position: -0px -180px;}
      .c13 {background-position: -60px -180px;}
      .c14 {background-position: -120px -180px;}
      .c15 {background-position: -180px -180px;}
      
    7. Mapedit.exe で作成した "bijin.js" のソースコードです。
      文字コードは shift_jis ですが、そのまま使います。
      var map = [
      0, 1, 2, 3, 
      4, 5, 6, 7, 
      8, 9, 10, 11, 
      12, 13, 14, 15, 
      ];
      document.write('<div class="info">Map Chip<br></div>');
      document.write('<div id="bg">');
      for(i=0; i<map.length; i++)
      { document.write('<div class="chip c', map[i], '"></div>'); }
      document.write('</div>');
      
    8. 苦労して描画したのが元の画像と同じでは、何をしているか解りませんが、この後を楽しみにして下さい。 (^_^;)

  7. CSS Animation

    16枚の Sprite を切り替えながら美人のアニメーションです。
    1. CSS Mapchip では Sprite を並べて元の bijin16.jpg と同じ画像を描画しました。
      次に16枚の Sprite を切り替えながら美人のアニメーションをします。
      全て JavaScript に任せるなら パラパラアニメーション の方が簡単かも知れません。
    2. <head> から "bijin.css" をリンクします。
      <html>
      <head>
      <meta http-equiv="Content-Script-Type" content="text/javascript" charset="shift_jis">
      <link rel="stylesheet" href="bijin.css" type="text/css">
      
    3. setInterval で 200 ミリ秒毎に chenge() 関数を呼び出します。
      div で一枚目の画像(c0)を表示します。
      <body onLoad="setInterval('chenge()',200)">
      <div class="chip c0" id="sample"></div>
      
    4. "bijin.css" を参照して Sprite の位置を pos の配列で定義しています。
      num は現在描画中の Sprite 番号で、0 ~ 15 を繰り返します。
      id="sample" の画像に Sprite の位置(pos[num])を設定します。
      <script type="text/javascript">
      <!--
        pos = ["0 0", "-60 0", "-120 0", "-180 0",
               "0 60", "-60 -60", "-120 -60", "-180 -60",
               "0 -120", "-60 -120", "-120 -120", "-180 -120",
               "0 -180", "-60 -180", "-120 -180", "-180 -180" ];
        num = 0;    //現在の画像
        function chenge()
        { num = (num+1)%16;
          var elementReference = document.getElementById( "sample" );
          elementReference.style.backgroundPosition = pos[num];
        }
      // -->
      </script>
      

前田稔の超初心者のプログラム入門
超初心者のプログラム入門(JavaScript)