HTML Canvasを利用して 画像のモザイクフェードイン、フェードアウトを実装する

HTML Canvasを利用して 画像のモザイクフェードイン、フェードアウトを実装するコードを紹介します。

概要

画像表示時に荒いモザイクから徐々に細かいモザイクにアニメーションしてフェードインする効果、画像表示状態から細かいモザイク表示に変わり徐々に荒いモザイク表示になり画像を非表示にするフェードアウト処理を実装します。

プログラム (フェードインのみ)

コード

下記のHTMLファイルを作成します。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title></title>
  <meta charset="utf-8" />

  <script type="text/javascript">
    var imageData;
    var fadeMosaicSize = 0;
    var THandle;
    var mem_canvas;
    var mem_context;
    var context;
    var img;

    function loadImage() {
      img = new Image();
      mem_canvas = document.createElement('canvas');

      img.onload = function onImageLoad() {
        mem_canvas.width = img.width;
        mem_canvas.height = img.height;
        mem_context = mem_canvas.getContext('2d');
        mem_context.drawImage(img, 0, 0);

        imageData = mem_context.getImageData(0, 0, mem_canvas.width, mem_canvas.height);
        startFadeIn();
      }
      img.src = 'resource/img03.png'; //相対URLの場合
      //img.src = 'http://www.ipentec.com/resource/img03.png';

      var canvas = document.getElementById('SimpleCanvas');
      if (!canvas || !canvas.getContext) {
        return false;
      }else{
        context = canvas.getContext('2d');
      }
    }

    function startFadeIn() {
      fadeMosaicSize = 64;
      THandle = setInterval(onFadeIn, 50);
    }

    function onFadeIn() {
      if (fadeMosaicSize <= 1) {
        clearInterval(THandle);
        context.drawImage(img, 32, 32);
      } else {
        CreateMosaic(mem_context, mem_canvas.width, mem_canvas.height, fadeMosaicSize);
        context.drawImage(mem_canvas, 32, 32);
        fadeMosaicSize = Math.floor(fadeMosaicSize / 1.5);
      }
    }
    
    function CreateMosaic(context, width,height,mosaicSize) {
      var x=0;
      var y=0;

      for (y = 0; y < height; y = y + mosaicSize) {
        for (x = 0; x < width; x = x + mosaicSize) {
          var cR = imageData.data[(y * width + x) * 4];
          var cG = imageData.data[(y * width + x) * 4 + 1];
          var cB = imageData.data[(y * width + x) * 4 + 2];

          context.fillStyle = "rgb("+cR+","+cG+","+cB+")";
          context.fillRect(x, y, x + mosaicSize, y + mosaicSize);
        }
      }
    }
  </script>

</head>
<body onload="loadImage();" style="background-color:#D0D0D0;">
  <canvas id="SimpleCanvas" width="640" height="360" style="background-color:#FFFFFF;"></canvas>
  <div>Canvas Demo</div>
  <div id="output"></div>
</body>
</html>

解説

bodyタグのonloadイベントにより、ページ表示時にloadImage()関数が呼び出されることで処理を開始します。
ページ表示開始後内部描画用のCanvasオブジェクトを作成し、画像を読み込み描画します。描画後ピクセルデータを取得します。その後、タイマー処理を起動し、タイマーのイベント中でモザイク画像を作成し画面のキャンバスに描画します。タイマー処理が実行されるごとにモザイクのサイズ(fadeMosaicSize)を減らし、荒いモザイクから細かいモザイクにアニメーションさせ、フェードイン効果を表現します。

フェードの速度を調整する場合は、タイマーのインターバールを変えるか、
fadeMosaicSize = Math.floor(fadeMosaicSize / 1.5);
の部分で、フェードのステップ数を変更するか、モザイクの初期サイズを変更する方法があります。
を参照してください。

実行結果

上記のHTMLファイルを表示します。荒いモザイクの画像が表示されます。


モザイクがだんだん細かくなります。


画像が表示され、処理完了です。

プログラム (フェードイン+フェードアウト)

コード

下記のHTMLファイルを作成します。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title></title>
  <meta charset="utf-8" />

  <script type="text/javascript">
    var imageData;
    var fadeMosaicSize = 0;
    var THandle;
    var mem_canvas;
    var mem_context;
    var context;
    var img;

    function loadImage() {
      img = new Image();
      mem_canvas = document.createElement('canvas');

      img.onload = function onImageLoad() {
        mem_canvas.width = img.width;
        mem_canvas.height = img.height;
        mem_context = mem_canvas.getContext('2d');
        mem_context.drawImage(img, 0, 0);

        imageData = mem_context.getImageData(0, 0, mem_canvas.width, mem_canvas.height);
        startFadeIn();
      }
      img.src = 'resource/img03.png'; //相対URLの場合
      //img.src = 'http://www.ipentec.com/resource/img03.png';

      var canvas = document.getElementById('SimpleCanvas');
      if (!canvas || !canvas.getContext) {
        return false;
      }else{
        context = canvas.getContext('2d');
      }
    }

    function startFadeIn() {
      fadeMosaicSize = 64;
      THandle = setInterval(onFadeIn, 50);
    }

    function startFadeOut() {
      fadeMosaicSize = 1;
      THandle = setInterval(onFadeOut, 50);
    }

    function onFadeIn() {
      if (fadeMosaicSize <= 1) {
        clearInterval(THandle);
        context.drawImage(img, 32, 32);
        THandle = setInterval(onShow, 2000);

      } else {
        CreateMosaic(mem_context, mem_canvas.width, mem_canvas.height, fadeMosaicSize);
        context.drawImage(mem_canvas, 32, 32);
        fadeMosaicSize = Math.floor(fadeMosaicSize / 1.5);
      }
    }

    function onShow() {
      clearInterval(THandle);
      startFadeOut();
    }
    
    function onFadeOut() {
      if (64 < fadeMosaicSize) {
        clearInterval(THandle);

        context.fillStyle = "#FFFFFF";
        context.fillRect(32, 32, mem_canvas.width, mem_canvas.height);
      } else {
        CreateMosaic(mem_context, mem_canvas.width, mem_canvas.height, fadeMosaicSize);
        context.drawImage(mem_canvas, 32, 32);
        fadeMosaicSize = Math.ceil(fadeMosaicSize * 1.5);
      }
    }

    function CreateMosaic(context, width,height,mosaicSize) {
      var x=0;
      var y=0;

      for (y = 0; y < height; y = y + mosaicSize) {
        for (x = 0; x < width; x = x + mosaicSize) {
          var cR = imageData.data[(y * width + x) * 4];
          var cG = imageData.data[(y * width + x) * 4 + 1];
          var cB = imageData.data[(y * width + x) * 4 + 2];

          context.fillStyle = "rgb("+cR+","+cG+","+cB+")";
          context.fillRect(x, y, x + mosaicSize, y + mosaicSize);
        }
      }
    }

  </script>

</head>
<body onload="loadImage();" style="background-color:#D0D0D0;">
  <canvas id="SimpleCanvas" width="640" height="360" style="background-color:#FFFFFF;"></canvas>
  <div>Canvas Demo</div>
  <div id="output"></div>
</body>
</html>

解説

先のコードの処理後に、2秒間のインターバルを実行し、その後、onFadeOutをインターバル実行することでフェードアウトまでを実装したコードになります。

実行結果

上記のHTMLファイルを表示します。モザイクの画像が表示されます。


モザイクが細かくなり画像が表示されます。


2秒ほど画像が表示され、その後、モザイク画像に変化します。


徐々にモザイクが荒くなります。



最後は画像が非表示になります。

著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2024-01-06
作成日: 2016-08-03
iPentec all rights reserverd.