プログラミングとイラストレーション » HTML5のCanvasでゲージのアニメーションを作り、ボタンで増減させる
プログラミングとイラストレーション > HTML5 > HTML5のCanvasでゲージのアニメーションを作り、ボタンで増減させる

HTML5のCanvasでゲージのアニメーションを作り、ボタンで増減させる

HTML5のCanvasでゲージのアニメーションを作り、ボタンで増減させる

ボタンを押すと、ゲージが任意の値まで増加します。ゲージが最大になった後、ボタンを押すと、ゲージが任意の値だけ減少します。ゲージが0になると、再び増えます。そのくり返しです。

HTML5のCanvasでゲージのアニメーションを作り、ボタンで増減させる : デモ

HTML5のCanvasでゲージのアニメーションを作り、ボタンで増減させる : ZIPファイル(8kb)

1.HTML

<!doctype html> <!-- 標準モードでWebページをレンダリング -->
<html lang="ja"> <!-- 言語指定付きのhtml要素 -->
	<head> <!-- ヘッダーの指定 HTMLページの生成に必要な情報を記述 -->
		<meta charset="UTF-8"> <!-- Web上の文字エンコーディングの指定 -->
		<title>HTML5のCanvasでゲージのアニメーションを作り、ボタンで増減させる</title> <!-- ブラウザの上部ウィンドウのバーに表示されるタイトル -->
        <link href="css/base.css" rel="stylesheet" type="text/css"> <!-- cssファイル(デザインの仕様)の読み込み -->
		<script src="js/devicecheck.js"></script> <!-- JavaScriptファイル(使用デバイスの特定)の読み込み -->
		<script src="js/base.js"></script> <!-- JavaScriptファイル(制御の仕様)の読み込み -->
	</head>

    <body> <!-- HTMLページのメインコンテンツを示す要素 -->
    	<div id="button" width = "20" height = "20"></div> <!-- ボタン要素 -->
        <canvas id = "viewArea" width = "275" height = "30"></canvas> <!-- 描画領域 -->
    </body>
</html>

2.CSS

@charset "UTF-8";

body /* bodyのデザイン */
{
	margin:0; /* borderより外側の余白は0 */
	padding:0; /* borderより内側の余白は0 */
	background-color: #fff; /* 背景色は白 */ 
	-webkit-transform:translateZ(0px); /* GPUの機能を使う */
}

#viewArea /* id名「viewArea」が付いたCanvas要素(タグ)のデザイン */
{
	position: absolute; /* 配置方法は絶対値 */
	top: 10px; /* Webのページの上から10ピクセルの位置 */
	left: 10px; /* Webのページの左から10ピクセルの位置 */
	width: 275px; /* 幅は275ピクセル */
	height: 30px; /* 高さは275ピクセル */
	border: 1px solid #000; /* 線は1ピクセルの太さで、実線、色は黒。上下左右に引く */
}

#button /* id名「button」が付いたDiv要素(タグ)のデザイン */
{
	position: absolute; /* 配置方法は絶対値 */
	top: 50px; /* Webのページの上から10ピクセルの位置 */
	left: 10px; /* Webのページの左から10ピクセルの位置 */
	width: 60px; /* 幅は275ピクセル */
	height: 60px; /* 高さは275ピクセル */
	background-color: #0000ff; /*背景カラーは黒*/
}

3.JavaScript

devicecheck.js

function Sandbox()
{
}
	
Sandbox.prototype = 
{
	/*name : "My App",
	version : "1.0",
	getName : function()
	{
		return this.name;
	}*/
};

Sandbox.prototype.g_mobiledevice = false;
Sandbox.prototype.g_browsername = "unknown";
Sandbox.prototype.g_browserver = -1;

var g_mobiledevice = false;	//iPhone、iPad、Androidのときtrue
var g_browsername = 'unknown';
var g_browserver = -1;

if(checkUserAgent() == false)
{
	window.alert('このブラウザは対象外です');
}

function checkUserAgent()
{
	var ua = navigator.userAgent;

	//iPhoneか?	
	var mstr = ua.match(/iPhone OS \d+/);
	if(mstr != null){
		var vstr = mstr[0].match(/\d+/);
		if(parseInt(vstr[0]) >= 3) 
		{
			Sandbox.prototype.g_mobiledevice = true;
			Sandbox.prototype.g_browsername = 'iPhone';
			//alert('major-version ' + vstr);
			return true;
		}
	}
	//iPadか?
	if(ua.indexOf('iPad') > -1)
	{
		mstr = ua.match(/CPU OS \d+/);
		if(mstr != null)
		{
			var vstr = mstr[0].match(/\d+/);
			if(parseInt(vstr[0]) >= 3) {
				Sandbox.prototype.g_mobiledevice = true;
				Sandbox.prototype.g_browsername = 'iPad';
				//alert('major-version ' + vstr);
				return true;
			}		
		}		
	}	
	//Androidか?	
	var mstr = ua.match(/Android \d+\.\d+/);
	if(mstr != null)
	{
		Sandbox.prototype.g_browsername = 'Android';
		var vstr = mstr[0].match(/\d+\.\d+/);
		Sandbox.prototype.g_browserver = parseFloat(vstr[0]);
		Sandbox.prototype.g_mobiledevice = true;
		if(Sandbox.prototype.g_browserver > 2.1) 
		{
			//alert('version ' + vstr);
			return true;
		}
	}
	//Chromeか?
	mstr = ua.match(/Chrome\/\d+/);
	if(mstr != null)
	{
		Sandbox.prototype.g_browsername = 'Chrome';
		var vstr = mstr[0].match(/\d+/);
		Sandbox.prototype.g_browserver = parseInt(vstr[0]);
		if(Sandbox.prototype.g_browserver >= 9) 
		{
			//alert('major-version ' + vstr);
			
			return true;
		}		
	}
	//Safariか?
	if(ua.indexOf('Safari') > -1)
	{
		mstr = ua.match(/Version\/\d+/);
		if(mstr != null){
			var vstr = mstr[0].match(/\d+/);
			if(parseInt(vstr[0]) >= 5) 
			{
				Sandbox.prototype.g_browsername = 'Safari';
				//alert('major-version ' + vstr);
				return true;
			}		
		}		
	}
	//Internet Explorerか?
	mstr = ua.match(/MSIE \d+/);
	if(mstr != null)
	{
		var vstr = mstr[0].match(/\d+/);
		if(parseInt(vstr[0]) >= 9) 
		{
			Sandbox.prototype.g_browsername = 'MSIE';
			//alert('major-version ' + vstr);
			return true;
		}		
	}
	//Firefoxか?
	mstr = ua.match(/Firefox\/\d+/);
	if(mstr != null){
		var vstr = mstr[0].match(/\d+/);
		if(parseInt(vstr[0]) >= 4) 
		{
			Sandbox.prototype.g_browsername = 'Firefox';
			//alert('major-version ' + vstr);
			return true;
		}		
	}
	//Operaか?
	if(ua.indexOf('Opera') > -1)
	{
		mstr = ua.match(/Version\/\d+/);
		if(mstr != null){
			var vstr = mstr[0].match(/\d+/);
			if(parseInt(vstr[0]) >= 11) 
			{
				Sandbox.prototype.g_browsername = 'Opera';
				//alert('major-version ' + vstr);
				return true;
			}		
		}		
	}
	
	return false;
}

base.js

window.addEventListener("load", init, false);

function init()
{
	//変数の定義
	var count = 0,
	gaugeFlag = false;
	offsetX = 0,
	offsetY = 0,
	buttonStart = null,
    buttonMove = null,
    buttonEnd = null,
    motion = null,
    buttonFlag = 1,
    currentWidth = 0,
    score = 0;
	
	//MVCデザインパターンの宣言
	function View(){}; //外観の処理を行うオブジェクトのグループ
	function Controller(){}; //インタラクティブな制御を行なうオブジェクトのグループ
	function Model(){}; //ロジックの処理を行うオブジェクトのグループ
	
	//視覚の処理を行うオブジェクトのグループ
	View =
	{
		//空のinit関数を作る
		init : function()
		{

		}
	}
	
	//Viewの中の関数(init)にプロトタイプの変数や関数を定義します
	//プロトタイプには、インスタンスで使う共有の関数や変数を設定します
	View.init.prototype.animation = function()
	{
		//もしgaugeFlagが真なら、countは減少する
		//その減少がcurrentWidthより小さくなったら、ゲージのアニメーションは破棄
		if(gaugeFlag === true)
		{
			count--;
			if(count < currentWidth)
			{
				count = currentWidth;
				cancelAnimationFrame(motion);
				motion = null;
			}
		}
		//もしgaugeFlagが偽なら、countは増加する
		//その増加がcurrentWidthより大きくなったら、ゲージのアニメーションは破棄
		else
		if(gaugeFlag === false)
		{
			count++;
			if(count > currentWidth)
			{
				count = currentWidth;
				cancelAnimationFrame(motion);
				motion = null;
			}
		}

		//もしcountがゲージの幅以上になったら、gaugeFlagを真にする
		if(count >= offsetX)
		{
			gaugeFlag = true;
			count = offsetX;
		}
		//もしcountが0以下になったら、gaugeFlagを偽にする
		else
		if(count <= 0)
		{
			gaugeFlag = false;
			count = 0;
		}

		Model.init.prototype.gauge(); //モデルでゲージの計算処理をして、その値をビューに反映

		//console.log("count: " + count);
	}
	
	//ロジックの処理を行うオブジェクトのグループ
	Model = 
	{
		//空のinit関数を作る
		init: function()
		{

		}
	}
			
	//Modelの中の関数(init)にプロトタイプの変数や関数を定義します
	//プロトタイプには、インスタンスで使う共有の関数や変数を設定します
	Model.init.prototype.ready = function()
	{
		//Canvasのエレメント要素を変数に代入する
		theCanvas = document.getElementById("viewArea");

		//Canvasタグで2次元描画を行ないます
		ctx = theCanvas.getContext("2d");
		
		//Canvasの中心座標を取得
		//centerX: Canvasタグの横幅の1/2を取得
		offsetX = (theCanvas.currentStyle || document.defaultView.getComputedStyle(theCanvas,'')).width;
		offsetX = Number(offsetX.replace('px',''));
		centerX =  offsetX / 2;
		
		//centerY: Canvasタグの高さの1/2を取得
		offsetY = (theCanvas.currentStyle || document.defaultView.getComputedStyle(theCanvas,'')).height;
		offsetY = Number(offsetY.replace('px',''));
		centerY =  offsetY / 2;

		score = offsetX / 10;
		//console.log("score: " + score);
	}

	Model.init.prototype.gauge = function()
	{
		motion = requestAnimationFrame(View.init.prototype.animation);
		ctx.clearRect(0, 0, offsetX, offsetY);
		ctx.strokeStyle = "#000000";
		ctx.lineWidth = 0;
		ctx.fillStyle = "#000000";
		ctx.beginPath();
		ctx.moveTo(0,0);
		ctx.lineTo(count,0);
		ctx.lineTo(count,offsetY);
		ctx.lineTo(0,offsetY);
		ctx.lineTo(0,0);
		ctx.fill();
		ctx.stroke();
	}

	//ボタンタイプ
    Model.init.prototype.setButton = function()
    {
    	//Sandbox.prototype.g_mobiledeviceがtrueなら、モバイルデバイス用にボタンをタッチイベントに変更します
    	//Sandbox.prototype.g_mobiledeviceの変数は、devicecheck.jsに設定されていて、ユーザーが使っているデバイスを解析したときの結果(true また false)を格納しています
        if(Sandbox.prototype.g_mobiledevice === true)
        {
            buttonStart = 'touchstart';
            buttonMove = 'touchmove';
            buttonEnd = 'touchend';
        }
        else //Sandbox.prototype.g_mobiledeviceがtrueでないなら、パーソナルコンピュータ用にマウスイベントに変更します
        {
            buttonStart = 'mousedown';
            buttonMove = 'mousemove';
            buttonEnd = 'mouseup';
        }

        //window.alert('ブラウザ: ' + Sandbox.prototype.g_browsername);
        console.log('ブラウザ: ' + Sandbox.prototype.g_browsername);
    }

    //ボタンが押されたり、タッチされたときに起こす処理です
    //ここでは、ボタンの色を変えています
	Model.init.prototype.buttonStartHandler = function()
	{
		if(gaugeFlag === true)
		{
			currentWidth -= score;
		}
		else
		{
			currentWidth += score;
		}
		
		//ゲージのアニメーションを開始
		motion = requestAnimationFrame(View.init.prototype.animation);
        
        var name = this.getAttribute("Id");
        View.init.prototype.element = document.getElementById(name);
        View.init.prototype.element.style.backgroundColor = "#ff0000";
        console.log(name); //Chromeのデベロッパーツールを使うと、出力できます
	}

	Model.init.prototype.buttonMoveHandler = function()
	{
		//今回は使いません
	}

	//ボタンからマウスが離れたり、タッチから離れたときに起こす処理です
	Model.init.prototype.buttonEndHandler = function()
	{
		var name = this.getAttribute("Id");
        View.init.prototype.element = document.getElementById(name);
        View.init.prototype.element.style.backgroundColor = "#0000ff";     
	}

	//インタラクティブの処理を行うオブジェクトのグループ
	Controller = 
	{
		//空のinit関数を作る
		init: function()
		{

		}
	}

	//インタラクティブの中の関数(init)にプロトタイプの変数や関数を定義します
	//プロトタイプには、インスタンスで使う共有の関数や変数を設定します
	//ここでは、インタラクティブなボタンの制御を設定しています
	Controller.init.prototype.buttonMove = function()
	{
		document.getElementById('button').addEventListener(buttonStart, Model.init.prototype.buttonStartHandler, false);
		document.getElementById('button').addEventListener(buttonMove, Model.init.prototype.buttonMoveHandler, false);
        document.getElementById('button').addEventListener(buttonEnd, Model.init.prototype.buttonEndHandler, false);
	}

	//今回は使いません
	/*Controller.init.prototype.buttonReMove = function()
	{
		document.getElementById('button').removeEventListener(buttonStart, Model.init.prototype.buttonStartHandler, false);
        document.getElementById('button').removeEventListener(buttonMove, Model.init.prototype.buttonMoveHandler, false);
        document.getElementById('button').removeEventListener(buttonEnd, Model.init.prototype.buttonEndHandler, false);
	}*/
	
	//Modelの中のInit関数のインスタンスを生成
	var model = new Model.init();
	//Model関数のプロトタイプにあるready関数を呼び出します
	model.ready();

	//Model関数のプロトタイプにあるsetButton関数を呼び出します
	model.setButton();

	//Controllerの中のInit関数のインスタンスを生成
	var controller = new Controller.init();
	controller.buttonMove();
	
	//Viewの中のInit関数のインスタンスを生成
	var view = new View.init();
}

// 各ブラウザ対応
//Safari対応で、一番外側に書く
(function()
{
    var requestAnimationFrame = window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function(callback)
            {
                setTimeout(callback, 1000 / 60);
            };

    var cancelAnimationFrame = window.cancelAnimationFrame ||
            window.webkitCancelRequestAnimationFrame ||
            window.mozCancelRequestAnimationFrame ||
            window.oCancelRequestAnimationFrame ||
            window.msCancelRequestAnimationFrame ||
            function(id)
            {
                clearTimeout(id);
            };

    window.requestAnimationFrame = requestAnimationFrame;
    window.cancelAnimationFrame = cancelAnimationFrame;
})();

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

コメントフィード

トラックバック URL : http://www.htmlcode.jp/html5%e3%81%aecanvas%e3%81%a7%e3%82%b2%e3%83%bc%e3%82%b8%e3%81%ae%e3%82%a2%e3%83%8b%e3%83%a1%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%82%92%e4%bd%9c%e3%82%8a%e3%80%81%e3%83%9c%e3%82%bf%e3%83%b3%e3%81%a7/trackback/