POPSブログ

CreateJS MouseOverで背景を変化 ラベルを中心に配置した SpriteSheet 利用の画像ボタン

250

  Category:  javascript2013/09/25 pops 

一般的な、MouseOver で色が変化するボタンの中に SpriteSheet で作った画像を挿入しました。複数のアイコン画像などを1つのシート状にして読み込みSpriteSheetクラスで分解(各フレームに収容)して利用します。手の込んだ面倒なボタンですが簡単な形に改造も可能です。
easeljs-0.7 (easeljs-0.7.0)でのテストです。

 

CreateJS MouseOverで背景を変化 ラベルを中心に配置した SpriteSheet 利用の画像ボタン


前ページのボタンにSpriteSheet で作った画像を挿入しただけです。複数の画像を読み込むのが面倒な場合はSpriteSheetクラスで分解して利用するのも手段かと思います。勿論、Canvas処理のdrawImage()を使用して「画像分割」の手法でも作れますが、SpriteSheetクラス利用の方が少々処理が早いようです。
ボタン構造を変えるなどすれば少々ニュアンスの違うものも出来るかも知れません。


2013/09/25/EaselJSなどバージョンUPされました(easeljs-0.7)。SpriteSheetなどの部分が大きく変更されましたので、記事内容を変更します。2013/09/30


[説明図]

 

DEMO


CreateJS テキストを中心に配置したSpriteSheetボタンのデモ、(createJS038.js)

このページはHTML5では有りませんので、デモページでご覧ください。「IE7.8」ではご覧いただけません。
/// 注意、ブラウザ、マシン性能により描画品質などに大きな差が有ります事了承下さい ///


Chrome Firefox Safari(Win) IE9、で動作確認済み。 Safari(Mac)、IE10、は未確認です。


 

HTML JS CSS


使用するライブラリ

easeljs preloadjs tweenjs

配布元 : CreateJS createjs.com


ライブラリの読み込み

ダウンロードしたJSを使用する場合。記述は一例です。(バージョン 0.7.0 使用)


<script type="text/javascript" src="js/easeljs-0.7.0.min.js"></script>

重要、バージョン違いでは動かない場合が有りますので必ず合わせて下さい。
このデモでは tweenjs preloadjs は不要です。


HTML (HTML5)


<div id="demo-wrap">
	<div id="image-box" class="radius"><canvas id="mainCanvas" width="640" height="300"></canvas></div>
</div>

JS

createJS038.js、JS名は任意に変更可。注意、easeljs-0.7用です。

必要は無いと思いますが、以前の、easeljs-0.6用のJSは「デモ」ページに暫く掲載しておきます。


//日本語
//createJS038c.js
//スプライトシートボタンデモ用
//easeljs-0.7.0.js用

//必要ならばfirefox判定
var userAgent = window.navigator.userAgent.toLowerCase();
var firefox=false;
if (userAgent.indexOf("firefox") > -1) {firefox=true;}
//------------------------------------------------------
//初期設定
//canvasの大きさ/全てこの値を使用
var canvasWidth=640;
var canvasHeight=300;
//------------------------------------------------------

//ステージ
var stage;
//ボタンコンテナ、インスタンス配列
var btncontainer;
var myhitBtn=[];

//画像Object
var iconSheet;

//画像分割URL容器
var srcArr=[];

//shadowフィルター
var shadow=new createjs.Shadow("#000000",0,0,4);

//ステージ周りセット
function init() {

	//STAGE
	stage=new createjs.Stage('mainCanvas');
	//MouseOver設定/必要に応じ設定
	stage.enableMouseOver(20);

	//バックRect/最下位色背景層、無くとも良い
	var backrect=new createjs.Shape();
	backrect.graphics.beginFill("#FFFFFF").drawRect(0,0,canvasWidth,canvasHeight);
	stage.addChild(backrect);

	//welcome画像層画像表示
	var welcomeImage=new createjs.Bitmap('/main/images/welcome_back5.png');
	stage.addChild(welcomeImage);

	//ボタンcontainer
	btncontainer=new createjs.Container();
	btncontainer.x=120;
	btncontainer.y=150;
	stage.addChild(btncontainer);

	//必要ならTicker設定
	createjs.Ticker.setFPS(30);
	createjs.Ticker.addEventListener('tick',tick);

	//ボタンを作り表示する 
	iconSheet=new Image();
	iconSheet.onload=function() {

		//spriteSheet角丸ボタンその都度スプライトシートを作る
		spriteSheetBtns();

	};

	iconSheet.src="/main/images/icons01.png";

}

//------------------------------------------------------------------------------

//DRAW-スプライトシートボタン
function spriteSheetBtns() {

	var btn_width=84;//幅
	var btn_height=84;//高さ
	var c_radius=5;//コーナー半径
	var btn_spc=20;//ボタン間隔スペース
	var center=true;//全体の中央補正

	//スプライトの大きさ
	var sprite_width=80;
	var sprite_height=80;

	var labels=["BUTTON1","BUTTON2","BUTTON3","BUTTON4","BUTTON5"];//ラベル
	var num=labels.length;//数

	for (var i=0; i < num; i++) {

		//画像,sw,sh,x,y,w,h,r,c,label,size,lc,overc,outc,番号
		//RoundRect center補正ボタン、こちら使用
		myhitBtn[i]=createSpriteBtn_center (iconSheet,sprite_width,sprite_height,-btn_width/2,-btn_height/2,btn_width,btn_height,c_radius,"#FFFFFF",labels[i],"12px","#FFFFFF","#48D1CC","#FFFFFF",i);

		//簡易SpriteBtn、未使用
		//画像,sw,sh,番号
		//myhitBtn[i]=createSpriteBtn (iconSheet,sprite_width,sprite_height,i);

		myhitBtn[i].cursor="pointer";

		myhitBtn[i].x=(btn_width+btn_spc)*i;//通常
		//myhitBtn[i].x=(sprite_width+btn_spc)*i;//簡易の場合

		myhitBtn[i].y=0;
		//myhitBtn[i].rotation=-15;//回転も可能
		//addChild
		btncontainer.addChild(myhitBtn[i]);
	}

	var btnbox_w=myhitBtn[num-1].x-myhitBtn[0].x;
	//中央配置補正
	if (center) {btncontainer.x=(canvasWidth-btnbox_w)/2;}
	stage.update();
}

//createSpriteBtn_center
//色cは未使用、outcを使用している
function createSpriteBtn_center (sheet_img,sw,sh,x,y,w,h,r,c,label,size,lc,overc,outc,no) {

	var font_v=size+" "+"Arial";

	//BTNコンテナ
	var btn=new createjs.Container();
	var s=new createjs.Shape();
	s.graphics.s().beginFill(outc);//本来は色cを使用
	operaRoundRect(s,x,y,w,h,r);
	//Shapeに陰影
	s.shadow=shadow;

	//SpriteSheetデータの用意
	var data={
		images:[sheet_img],
		frames:{width:sw,height:sh,regX:sw/2,regY:sh/2},
		animations:{}
	}

	//スプライトシートを作る
	var spriteSheet=new createjs.SpriteSheet(data);
	//Spriteクラス設定
	var sprite=new createjs.Sprite(spriteSheet);
	sprite.alpha=0.8;//機能する
	sprite.gotoAndStop(no);//指定フレームを表示

	btn.addChild(s,sprite);
	//テキスト以外で使用は注意
	var tx=new createjs.Text(label,font_v,lc);
	tx.maxWidth=w;
	tx.textAlign="center";
	tx.textBaseline="middle";

	//firefox補正
	if (firefox) {tx.y=1;}
	//opera漢字補正用
	//if (window["opera"]) {tx.y=-1;}

	tx.shadow=shadow;//テキストは濃くなら無い
	tx.name="btntext";//name挿入
	btn.addChild(tx);

	//MouseOver
	btn.addEventListener("mouseover",function () {
		s.graphics.clear();
		s.graphics.s().beginFill(overc);
		operaRoundRect(s,x,y,w,h,r);
		sprite.alpha=1;//機能する
		stage.update();
	});
	//MouseOut
	btn.addEventListener("mouseout",function () {
		s.graphics.clear();
		s.graphics.s().beginFill(outc);
		operaRoundRect(s,x,y,w,h,r);
		sprite.alpha=0.8;//機能する
		stage.update();
	});
	return btn;
}

//簡易SpriteBtn、未使用
function createSpriteBtn (sheet_img,sw,sh,no) {

	//BTNコンテナ
	var btn=new createjs.Container();

	//SpriteSheetデータの用意
	var data={
		images:[sheet_img],
		frames:{width:sw,height:sh,regX:sw/2,regY:sh/2},
		animations:{}
	}

	//スプライトシートを作る
	var spriteSheet=new createjs.SpriteSheet(data);
	//Sprite設定
	var sprite=new createjs.Sprite(spriteSheet);
	sprite.gotoAndStop(no);//指定フレームを表示

	//BTNコンテナ陰影
	btn.shadow=shadow;
	btn.addChild(sprite);
	return btn;

}

//tick
function tick() {
	stage.update();
}

//quadraticCurveTo
function operaRoundRect(s,x,y,w,h,r) {
	s.graphics.moveTo(x+r,y)
	.lineTo(x+w-r,y)
	.quadraticCurveTo(x+w,y,x+w,y+r)
	.lineTo(x+w,y+h-r)
	.quadraticCurveTo(x+w,y+h,x+w-r,y+h)
	.lineTo(x+r,y+h)
	.quadraticCurveTo(x,y+h,x,y+h-r)
	.lineTo(x,y+r)
	.quadraticCurveTo(x,y,x+r,y);
}

//START
init();

注釈文を削除すれば、幾分早くなります。
登録画像パスは当方の場合です。使用の際は環境に合わせて下さい。


CSS

createJS038.css、CSS名は任意に変更可


/*日本語 createJS038.css*/

#demo-wrap {
text-align:center;
}

#image-box {
position:relative;
top:0;left:0;
width:640px;
height:300px;
margin:0 auto;
padding:0;
box-shadow:0 0 10px #000;
-moz-box-shadow:0 0 10px #000;
-webkit-box-shadow:0 0 10px #000;
-o-box-shadow:0 0 10px #000;
-ms-box-shadow:0 0 10px #000;
background-color:#FFFFFF;
}

#image-box #mainCanvas {
border-radius:10px;
}
canvas {
border-style:none;
background-color:transparent;
}

.radius {
border-radius:10px;
-moz-border-radius:10px;
-webkit-border-radius:10px;
-o-box-border-radius:10px;
-ms-border-radius:10px;
}

当方のサンプルの例です。


簡単な説明


SpriteSheetの利用

Spriteの様なものに、フレームを加え、そのフレームに画像を分割して並べているような構造のようです。イワユル「パラパラ漫画」の構造であり、Spriteクラスにして(BitmapAnimationクラス非推奨)、制御する仕組みのようです。詳しくは調べていませんので詳細などは省略します。一応表示するのでマチガイは無いものと判断して、、
「パラパラ漫画」は絵を描くのが面倒ですのでこれも省略して、ここでは、アイコンなどの部品に利用して見ます。
新たに、Spriteクラスが加えられました。思考的に理解し易くなった?。


1. SpriteSheetを表示するのが、Spriteオブジェクトです。
2. BitmapAnimationは非推奨、将来撤廃される。Spriteクラスを使用する。


BitmapAnimationを使用すると一応警告が出るような形で、ブラウザによってはコンソールがでる。


1. SpriteSheeクラスで使用する画像は必ず読み込み完了後に処理する
2. SpriteSheeクラスの data を作る。
3. 新規に、new createjs.SpriteSheet(data) で、SpriteSheetオブジェクトを作る。
4. 新規に、new createjs.Sprite(spriteSheet) で、Spriteのインスタンスを作る。
(以前は、new createjs.BitmapAnimation(spriteSheet) で、BitmapAnimationのインスタンス)
5. フレーム番号指定して、リストに加えて表示する。(アニメも可能)


アニメ無しで、gotoAndStop(指定フレーム番号)、を利用して指定フレームの画像を表示しているに過ぎない。


SpriteSheetの処理

ボタンを作る、createSpriteBtn_center()関数で画像オブジェクトを引数にして渡し、ボタン個別に処理しています。アニメーションにはしていませんが、gotoAndStop() で指定フレームを表示。


画像を分割する感じではなく、画像の指定部分のみを表示している。フレーム番号を変更すれば瞬時切り替えも可能。
CSSで有れば、バック背景画像をポジションで移動させる「CSS Sprite 処理」を連想すれば判り易い。


デモでは、MouseOver時、画像の下の graphics の色を替えています。陰影はShape()に処理しました。


● createJS038.js、clone()を使用しない、(注意、easeljs-0.7用)


function createSpriteBtn_center (sheet_img,sw,sh,x,y,w,h,r,c,label,size,lc,overc,outc,no) {

	略す

	//SpriteSheetデータの用意
	var data={
		images:[sheet_img],
		frames:{width:sw,height:sh,regX:sw/2,regY:sh/2},
		animations:{}
	}

	//スプライトシートを作る
	var spriteSheet=new createjs.SpriteSheet(data);
	//Sprite設定
	var sprite=new createjs.Sprite(spriteSheet);

	sprite.alpha=0.8;//機能する
	sprite.gotoAndStop(no);//指定フレームを表示

	btn.addChild(s,sprite);

	略す

}

ここでは、フレーム移動だけで、animations:{} は使用していないので、省略可。


参考、以前の記述、(注意、easeljs-0.6用です) アニメーションはしていませんが、BitmapAnimation()クラス処理をしないとgotoAndStop()が利用出来ません。


function createSpriteBtn_center (sheet_img,sw,sh,x,y,w,h,r,c,label,size,lc,overc,outc,no) {

	略す

	//SpriteSheetデータの用意
	var data={
		images:[sheet_img],
		frames:{width:sw,height:sh,regX:sw/2,regY:sh/2}
	}

	//スプライトシートを作る
	var spriteSheet=new createjs.SpriteSheet(data);
	//BitmapAnimation設定
	var sprite=new createjs.BitmapAnimation(spriteSheet);

	sprite.alpha=0.8;//機能する
	sprite.gotoAndStop(no);//指定フレームを表示

	btn.addChild(s,sprite);

	略す
}

● createJS038b.js、clone()を使用、(easeljs-0.6用JSはデモページに記載しています)

沢山あると混乱しますので、easeljs-0.7用は省略します。デモページ記載のものを参考に書き換えください。


ラベルを使用しない場合

ボタンの、ラベル(テキスト文字)を使用しない場合は、受け渡すラベルを「半角スペース」にして下さい。


var labels=["BUTTON1","BUTTON2","BUTTON3","BUTTON4","BUTTON5"];//ラベル

を「半角スペース」に変更
var labels=[" "," "," "," "," "];//ラベル

ラベルが何も無い(null)状態でも中心は変わらないようだが、ブラウザにより問題が出るか判らないので、「半角スペース」指定している。


ラベル位置の補正と調整

このボタンはテキストが、textAlign:center、textBaseline:middle、の設定で作られている構造です。
この「デモ」では画像が大きいために、ラベル(文字)に対してのマスクを設定していません。(もしマスクをした場合、デモではShape()に陰影処理しているためにマスク範囲が広がりますので注意下さい)


一応、Firefoxでラベル位置がずれるので補正していますが、ボタンが大きい場合は余り気にならないかとも思いますし、「ラベル無し」での使用も考えられますので、ラベル位置ズレは無視して良いかも知れません。
ボタン構造、ラベルなどの詳細は「前ページ」を参照下さい。


● 補正: 画像の大きさにも左右されるが、余り問題なき場合は、高さの補正は無理にしなくとも良いと思う。


//firefox補正
if (firefox) {tx.y=1;}
//opera漢字補正用
//if (window["opera"]) {tx.y=-1;}

● 調整:テキストの位置は「y値」tx.y で調整可能です、ボタン全体の中心点は変わりません。


テキストの位置を中央より下に30ピクセル下げます

tx.y=30;

スプライトシートに陰影をつけただけの簡単なボタン

 

ラベルも、ボタン背景、MouseOverも無く、スプライトシートに陰影を付けただけの簡単なボタンは下記の様に出来る。
一応、コンテナ収容で作り(コンテナ収容にしなくとも可能) createJS038.js に加えておくが未使用である。
コンテナ収容の形式ですから必要があればテキストなど書き加えることが出来ます。


MouseOverは使用しない
//stage.enableMouseOver(20);

-------------------------------------------------------

//簡易SpriteBtn
//new Image()のオブジェクト,幅,高さ,番号
myhitBtn[i]=createSpriteBtn (iconSheet,sprite_width,sprite_height,i);

//myhitBtn[i].x=(btn_width+btn_spc)*i;//通常
myhitBtn[i].x=(sprite_width+btn_spc)*i;//簡易の場合

-------------------------------------------------------

//簡易SpriteBtn、未使用
function createSpriteBtn (sheet_img,sw,sh,no) {

	//BTNコンテナ
	var btn=new createjs.Container();

	//SpriteSheetデータの用意
	var data={
		images:[sheet_img],
		frames:{width:sw,height:sh,regX:sw/2,regY:sh/2},
		animations:{}
	}

	//スプライトシートを作る
	var spriteSheet=new createjs.SpriteSheet(data);
	//Sprite設定
	var sprite=new createjs.Sprite(spriteSheet);
	sprite.gotoAndStop(no);//指定フレームを表示

	//BTNコンテナ陰影
	btn.shadow=shadow;
	btn.addChild(sprite);
	return btn;

}

ボタンの改造などの注意

ボタンの中心位置決定の方法(textAlign:center、textBaseline:middle、の設定で作られている構造)などを理解の上に改造下さい。ややもするとgraphicsの中心がずれたりしますので、これらは自己責任で処理下さい。


Tickerの設定

テスト的には、Tickerを設定せずにstage.update()で表示出来ましたが、Tickerを設定した方が良いと思います。
「デモ」では事前に Tickerを設定 を行っています。


使用画像

原則、使用目的に合わせて作ります。下記はサンプルで使用の画像です。

背景画像である、Welcome画像は別途用意下さい。ここでは、640x300サイズ


SpriteSheetの画像、icons01.png、400x80サイズ

 


ラベルなどの詳細は「前ページ」記事を参照下さい。

【参照】当方の記事: CreateJS ラベルを中心に配置し、MouseOver で背景を変化させるボタンを考える




一応、完動しますが全てテストです。効率化のため、予告無くJSなど修正する場合がありますので了承下さい。
また、CreateJSの「仕様」もクルクル変わっていますので、バージョン違い等に充分注意下さい


次回は同じものを、画像分割の手法で作ってみます。
以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]