POPSブログ

CreateJS 画像埋め込み、角丸RoundRectマウスオーバーボタンを考える

216

  Category:  javascript2013/04/27 pops 

CreateJS 画像埋め込み、角丸RoundRectマウスオーバーボタン(ロールオーバー)、グラフィックに画像埋め込みボタンを作り、それに「shadowフィルター」を設定してみます。勿論、Operaでは角丸RoundRectが壊れます( Chromeエンジンに移行で、現在解決済みです )。問題箇所の修正方法など考えます。
easeljs-0.7 でテストして見ました。

 

CreateJS 画像埋め込み、角丸RoundRectマウスオーバーボタン


2013/09/25/EaselJSなどバージョンUPされました(easeljs-0.7)。動作など確認してeaseljs-0.7用に更新しています。(2013/10/17)
Operaでの角丸RoundRect処理修正を、通常のCreateJS Graphicsクラス drawRoundRect()使用に戻します。(2014/09/06)


通常のボタンならともかく、画像埋め込みマウスオーバーボタンとなると余り作る人は居ないと思います。ベタ塗り、グラデーション、とくれば次ぎは当然「画像ボタン」に成ります。単なる勢いな訳です。
グラフィックには背景画像を埋め込む beginBitmapFill() が有りますので、ボタンに画像を使用する事も可能です。ボタン画像「読み込み失敗」の場合の代替画像を新たに「キャンバス要素」を画像の代用にして補正しています。


[ 説明図 ] DEMOのキャプチャー

 

DEMO等

▲[ 目次 ]

DEMO


上記、画像ボタンを作成して、rollover rollout を設定した簡単なデモ。

このページはHTML5では有りませんので、デモページでご覧下さい。「IE7.8」ではご覧戴けません。


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


HTML JS CSS


使用するライブラリ

easeljs preloadjs tweenjs

配布元 : CreateJS createjs.com


ライブラリの読み込み

ダウンロードしたJSを使用する場合。記述は一例です。(注意、easeljs-0.7用)


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

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


HTML

ボタンキャンバスは分離されています。(subCanvas)


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

createJS011.js DEMO用 (easeljs-0.7用)


//日本語
//createJS011.js
//画像なしはキャンバス要素
//easeljs-0.7 デモ用

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

//初期設定
var speed=1000;//拡大移動、アニメ速度
var delay_speed=2000;//1000-5000最初の遅延用に使用
var slide_time;//未使用

//canvasの大きさ/全てこの値を使用
var canvasWidth=640;
var canvasHeight=300;

//タイマーの使用/常時使用、判定なし
var timer_use;
//タイマー値 5000-10000
var time=8000;

//clickbtnの使用 useのこと
var clickbtn_use="use";
//Loading AUTOの文字を表示するかuse
var text_use="use";

//サムネールの大きさ余白
var thumbW=128;
var thumbH=60;
var margin=2;//余白 R

//ボタン画像
var outback;
var overback;

//Imageオブジェクト先読み
var backgroundimage=new Image();
backgroundimage.src="/main/images/welcome_black.png";

//画像manifestリスト
var manifest=[
{src:"/main/images/btnback2.png",id:"overback"},
{src:"/main/images/btnback1.png",id:"outback"},
{src:"/main/images/toyota_car10.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car11.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car12.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car13.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car15.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car16.jpg",id:"PHOTO"}
];

//最初の画像0のこと
var image_no=0;
//画像数
var image_max;

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

//ステージ
var stage,stage2;
//Loader
var loader;
//コンテナ
var container;
var backcontainer;
var loadingcontainer;
var progresscontainer;
var btncontainer;//stage2
//welcome画像
var welcomeImage;
//画像result
var mainImage;
//下画像
var backImage;
//上画像
var topImage;
//Loading
var loadingShape;
var progressbar;
//TEXT
var viewtext;

//読み込み画像の大きさcanvasと同じ
var imageW=canvasWidth;
var imageH=canvasHeight;

//サムネールBOX
var thumbBox;//container
var thumbImage;//画像Bitmap
var thumb=false;//サムネール動作判定

//ボタンが押された/有効
var btnValidity=false;

//読み込み画像result保存容器
var assets=[];

//変数
var globalflag=false,timerID=null
//loading変数
var loading=false;
//ProgressBar変数
var bar_v=0;

//shadowフィルター
var shadow=new createjs.Shadow("#000000",0,0,4);
var once=true;
//ボタン
var myBtn=[];
var labels=["BOTTUN1","BOTTUN2","BOTTUN3"];//未使用

//アニメ位置データ
var pos_dx=[0,0,0,1,-1,0,0];
var pos_dy=[0,0,0,0,0,1,-1];

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

	//ステージ
	stage=new createjs.Stage('mainCanvas');
	//ステージ2
	stage2=new createjs.Stage('subCanvas');
	//MouseOver重要
	stage2.enableMouseOver(20);

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

	//welcome画像層画像表示
	welcomeImage=new createjs.Bitmap(backgroundimage);
	//welcomeImage=new createjs.Bitmap('/main/images/welcome_black_w.png');
	stage.addChild(welcomeImage);
	//welcome画像を先に表示
	stage.update();

	//下画像層、空画像コンテナを作る/寸法設定なくともOK
	backcontainer=new createjs.Container();
	backImage=new createjs.Bitmap();
	backcontainer.addChild(backImage);
	stage.addChild(backcontainer);
	
	//上画像層、空コンテナを作る
	container=new createjs.Container();
	topImage=new createjs.Bitmap();
	container.addChild(topImage);
	stage.addChild(container);

	//loadingコンテナを作る
	loadingcontainer=new createjs.Container();
	stage.addChild(loadingcontainer);
	//LOADINGを作る
	loadingShape=loadingIndicator();
	loadingShape.x=canvasWidth/2;
	loadingShape.y=canvasHeight/2;
	//tickを設定
	loadingShape.tick=function (){
		if(loading) {
			loadingShape.rotation +=5;
			stage.update();
		}
	}
	//loading addEventListenerを設定
	createjs.Ticker.addEventListener('tick',loadingShape.tick);
	//コンテナに貼り付け
	loadingcontainer.addChild(loadingShape);
	loading=true;//loading表示判定

	//ステージ2ボタンコンテナ、ボタンはあとで作る
	btncontainer=new createjs.Container();
	btncontainer.x=0;
	btncontainer.y=10;
	//ボタンコンテナをステージ2にaddChild
	stage2.addChild(btncontainer);
	createjs.Ticker.addEventListener('tick',tick2);
	stage2.update();

	//ProgressBar/canvasWidthの幅で描画
	progresscontainer=new createjs.Container();
	progresscontainer.x=0;
	progresscontainer.y=20;
	progressbar=new createjs.Shape();
	progressbar.graphics.s().beginFill("#888888").drawRect(0,0,canvasWidth,4);
	//bar_v判定tickを設定
	progressbar.tick=function (){
		if(bar_v > 0) {
			progressbar.graphics.s().beginFill("#48D1CC").drawRect(0,0,canvasWidth*bar_v,4);
			stage.update();
		}
	}
	//Ticker.Listener設定
	createjs.Ticker.addEventListener('tick',progressbar.tick);
	//addChild
	progresscontainer.addChild(progressbar);
	stage.addChild(progresscontainer);

	//簡易TEXT
	viewtext=new createjs.Text("","12px Arial","#FFFFFF");
	viewtext.x=20;
	viewtext.y=15;
	viewtext.maxWidth=canvasWidth-40;
	viewtext.lineHeight=20;
	viewtext.textBaseline="bottom";
	viewtext.shadow=shadow;//SHADOW処理
	stage.addChild(viewtext);
	set_text("Loading Now!");

	//FadeサムネールBOX
	thumbBox=new createjs.Container(0,0,thumbW+margin*2,thumbH+margin*2);
	thumbImage=new createjs.Bitmap();
	thumbImage.x=margin;
	thumbImage.y=margin;
	//縮小
	thumbImage.scaleX=thumbW/imageW;
	thumbImage.scaleY=thumbH/imageH;
	//back
	var thumbback=new createjs.Shape();
	//角丸
	thumbback.graphics.s().beginFill("#FFFFFF");
	operaRoundRect(thumbback,0,0,thumbW+margin*2,thumbH+margin*2,4);
	thumbback.shadow=shadow;

	thumbBox.addChild(thumbback,thumbImage);
	thumbBox.regX=(thumbW+margin*2)/2;
	thumbBox.regY=(thumbH+margin*2)/2;
	thumbBox.x=canvasWidth/2;
	thumbBox.y=canvasHeight-(thumbH);
	stage.addChild(thumbBox);
	thumbBox.visible=false;
	//フエード用tick設定
	thumbBox.tick=function (){
		if(thumbBox.alpha < 1 && thumb) {
			thumbBox.alpha+=0.05;
			stage.update();
		}
	}
	//Ticker.Listener設定
	createjs.Ticker.addEventListener('tick',thumbBox.tick);

	stage.update();

	//画像ロードに進む
	bulkload();
}

//progressBar
function progress(event) {

	//loadedのみ効く
	bar_v=event.loaded;
}

//bulk-load、画像一括ロード
function bulkload() {

	//Loaderを作る
	loader=new createjs.LoadQueue(false);
	//全体、progressがあれば先に設定
	loader.addEventListener("progress",progress);

	//loader EventListener設定
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);
	//Manifestを使用、manifest読み込み開始
	loader.loadManifest(manifest);

}

//各画像読み込み完了
function fileload (event) {

	var id=event.item.id;
	//画像選別
	if (id == 'PHOTO') {
		//エラー無しの画像をassets容器に保存
		assets.push(event.result);
	}
	//ボタン画像
	if (id=='outback') {outback=event.result;}
	if (id=='overback') {overback=event.result;}
}
//全ての画像読み込み完了
function complete (event) {

	//画像数確認、再計算
	image_max=assets.length;
	//簡易TEXT
	set_text("Loading End!")
	//loader Listener削除
	loader.removeEventListener("fileload",fileload);
	loader.removeEventListener("complete",complete);

	//loading EventListener削除
	createjs.Ticker.removeEventListener('tick',loadingShape.tick);
	//非表示でも良い
	loadingcontainer.visible=false;
	loading=false;//loading表示判定

	//ボタン画像読み込み失敗
	//Gradient
	if(!overback) {overback=createGradientCanvas (60,20,"#DB7093");}
	if(!outback) {outback=createGradientCanvas (60,20,"#BBBBBB");}

	//Create-Bottunボタンを作る
	if (clickbtn_use == 'use') {
		for (var i=0; i < image_max; i++) {

			//ラベル文字生成
			var label="PHOTO"+(i+1);
			//番号受け渡し
			var no=i;

			//create-画像ボタン/代替色の登録
			myBtn[i]=createImagebtn (0,0,60,20,5,"#FFFFFF",label,"#FFFFFF",outback,overback,"#FFFFFF","#DB7093",no);

			myBtn[i].cursor="pointer";
			//ボタン間隔ステージ用
			//myBtn[i].x=(i*70)+10;
			//ステージ2用
			myBtn[i].x=(i*70);
			//ボタン判別用のproperty:idを書き込む、未使用
			myBtn[i].id=i;
			//クリックアクション
			myBtn[i].addEventListener("click",handleclick);
			//myBtn addChild
			btncontainer.addChild(myBtn[i]);

		}
		//ボタンコンテナを中央に修正
		var btncont_x=(canvasWidth-(70*image_max-10))/2;
		btncontainer.x=btncont_x;
		stage2.update();
	}

	stage.update();

	//画像があれば、最初の画像表示
	if (image_max) {

		//早すぎるので調整
		setTimeout(function() {

			//遅延progressbar最後の前にcompleteが反応する
			event.target.removeEventListener("progress",progress);
			//progressTicker削除
			createjs.Ticker.removeEventListener('tick',progressbar.tick);
			//progress非表示
			progresscontainer.visible=false

			//簡易TEXTクリア
			set_text("");
			//viewtext.visible=false;

			//画像表示に進む
			draw();

		},delay_speed);
	}
}

//DRAW、アニメ
function draw() {

	globalflag=false;

	//AUTO文字表示/ボタン有効判定
	if (!btnValidity) {
		set_text("AUTO");

	};

	//サムネール表示中ならクリア
	if (thumb) {
		thumbBox.visible=false;
		thumb=false;
	}

	//activeボタン色変更
	if (clickbtn_use == 'use') {

		for (var i=0; i < image_max; i++) {
			//var target=myBtn[i].getChildAt(1);
			var target=myBtn[i].getChildByName("btntext");
			target.color=(i == image_no) ? "#FF0000":"#FFFFFF";
		}
		stage2.update();
	}

	//MODE
	var mode=1;
	//位置データ
	var rno=Math.floor(Math.random()*pos_dx.length);
	//移動
	var px = pos_dx[rno];
	var py = pos_dy[rno];
	if (px+py == 0) {mode=0;}//移動なし

	//最初は強制FADE
	if(once) {
		mode=0;
		once=false;
	}

	//画像result取得/Tween後も使用する
	mainImage=assets[image_no];

	//上画像更新画像Bitmap挿入、中央補正なし回転は出来ない
	topImage.image=new createjs.Bitmap(mainImage).image;
	if (mode == 0) {
		//FADE透明度0
		topImage.alpha=0;
		topImage.x=0;
		topImage.y=0;
	} else {
		//SLIDE
		topImage.alpha=1;
		topImage.x=canvasWidth*px;
		topImage.y=canvasHeight*py;
	}

	//TWEENの実行
	var tw=createjs.Tween.get(topImage)
	.to({x:0,y:0,alpha:1},speed)
	.call(finshtween);

	//Ticker設定
	createjs.Ticker.setFPS(30);
	createjs.Ticker.addEventListener('tick',tick);

}

//アニメ完了
function finshtween () {

	//ボタン有効解除
	btnValidity=false;

	//Tween全てが完了してから下画像表示
	backImage.image=new createjs.Bitmap(mainImage).image;

	//上画像に空Bitmap挿入
	topImage.image=new createjs.Bitmap();
	stage.update();

	//アニメ作業中である
	globalflag=true;

	//画像処理に時間がかかるので、少し遅延させる、あったほうが良い
	setTimeout(function() {

		//Ticker OFF
		createjs.Ticker.removeEventListener('tick',tick);
		//タイマー常時使用
		set_timer();

	},500);

}

//tickステージ
function tick() {
	stage.update();
}
//tick2ステージ2
//アニメなどなければ特別いらないようだ、ボタンでupdateしているから
function tick2() {
	//stage2.update();
}

//次ぎの開く要素を計算
function next_set() {

	//次ぎの番号
	image_no +=1;
	if (image_no > (image_max-1)) {image_no=0;}
	draw();
}

//タイマー
function set_timer() {

	//一旦切ってからセット
	clearTimeout(timerID);
	timerID=setTimeout(next_set,time);
}

//VIEWTEXT
function set_text(t) {
	if (text_use=='use') {
		viewtext.text=t;
	}
}

//BtnClick
function handleclick (event) {

	//アニメ中は機能しない
	if (!globalflag) {return;}

	//v0.7
	var instance=event.target.parent;
	var hit_no=instance.parent.getChildIndex(instance);

	//idで判定v0.7未使用
	//var hit_no=event.target.parent.id;

	//表示中番号なら戻る
	if (hit_no == image_no) {
		return;
	} else {
		//ボタン有効/AUTO文字書き換え
		btnValidity=true;
		viewtext.text="";
		//タイマー強制停止
		clearTimeout(timerID);
		//指定番号の画像表示
		image_no=hit_no;
		draw();
	}
}

//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);
}

//ThumbBox表示/update自動
function openThumbBox(no) {
	//サムネール画像書き換え/画像result取得
	thumbImage.image=new createjs.Bitmap(assets[no]).image;
	thumbBox.alpha=0;
	thumbBox.visible=true;
	thumb=true;
	//stage.update();
}
//ThumbBox非表示
function closeThumbBox(no) {
	//サムネール画像クリア空画像挿入
	//thumbImage.image=new createjs.Bitmap().image;
	thumbBox.visible=false;
	thumb=false;
	stage.update();
}

//create-画像ボタン-quadraticCurveTo方式、画像manifestリストが良い
//画像なしはキャンバス要素
function createImagebtn (x,y,w,h,r,c,label,lc,out,over,outcolor,overcolor,no) {

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

	//Opera判定はしない、quadraticCurveTo方式
	s.graphics.s();
	s.graphics.beginBitmapFill(out);
	operaRoundRect(s,x,y,w,h,r);

	btn.addChild(s);
	//myBtn shadow onMouseOverでupdate()すると濃くなる
	//テキスト以外で使用は注意
	btn.shadow=shadow;
	var tx=new createjs.Text(label,"12px Arial",lc);
	tx.x=w/2;
	tx.y=3;
	tx.maxWidth=w;
	//tx.lineWidth=w;
	tx.textAlign="center";
	tx.shadow=shadow;//テキストは濃くなら無い
	tx.name="btntext";//name挿入
	btn.addChild(tx);
	//文字の食み出し防止mask
	tx.mask=s;

	//画像rollover
	btn.addEventListener("rollover",function () {
		s.graphics.clear();
		//Opera判定はしない、quadraticCurveTo方式
		s.graphics.s();
		s.graphics.beginBitmapFill(over);
		operaRoundRect(s,x,y,w,h,r);
		stage2.update();
		//サムネールopen
		openThumbBox(no);
	});
	//画像rollout
	btn.addEventListener("rollout",function () {
		s.graphics.clear();
		//Opera判定はしない、quadraticCurveTo方式
		s.graphics.s();
		s.graphics.beginBitmapFill(out);
		operaRoundRect(s,x,y,w,h,r);
		stage2.update();
		//サムネールclose
		closeThumbBox(no);
	});
	return btn;
}

//色付きcanvasを作る
function createGradientCanvas (w,h,c) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	var gradient=ctx.createLinearGradient(0,h/2,0,0);
	gradient.addColorStop(0,c);
	gradient.addColorStop(1,"#FFFFFF");
	ctx.fillStyle=gradient;
	ctx.rect(0,0,w,h);
	ctx.fill();

	/*
	ctx.fillStyle="white";
	ctx.font="bold 12px Arial";
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	ctx.fillText("NONE",w/2,h/2);
	*/

	return canvas;
}

//簡単なLOADING
function loadingIndicator(){

	//graphicのスタイル
	var graphics=new createjs.Graphics();
	graphics.setStrokeStyle(2,"round").beginStroke("#CCCCCC");//round

	//描画データ
	var cx,cy,
	numNeedles=12,
	innerR=10,
	outerR=5,
	cAngle= -Math.PI/2,
	nAngle;

	//ライン描画
	nAngle=Math.PI*2/numNeedles;
	for (var i=0; i < numNeedles; i++){
		cAngle +=nAngle;
		cx=Math.cos(cAngle)*innerR;
		cy=Math.sin(cAngle)*innerR;
		graphics.moveTo(cx,cy);
		cx=Math.cos(cAngle)*outerR;
		cy=Math.sin(cAngle)*outerR;
		graphics.lineTo(cx,cy);
	}
	//Shapeに格納
	var s=new createjs.Shape(graphics);
	return s
}

//START
init();


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


CSS

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


/*日本語 createJS011.css*/

#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:#000000;
}

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

#btn-box {
width:640px;
height:50px;
margin:10px auto;
padding:0;
}

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;
}

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


簡単な説明


ボタン部分は、stage2 に成っています。ボタン画像読み込み失敗の場合は新しい方法に変更「キャンバス要素」を画像の代用にして補正しています。


EaselJSなどバージョンUPに伴う変更と機能追加

EaselJSなどバージョンUP(easeljs-0.7)のために一部変更になっています。


1. ボタン、mouseover mouseout から rollover rollout に変更なりますが振る舞いは同じです。
2.「キャンバス要素」を画像の代用にして補正が簡単になります。他の目的でも利用可能です。
3. マウスオーバー(rollover)でサムネールを表示します。


以前の beginBitmapFill() 記事など新たに「キャンバス要素」を画像の代用するなど加えて新たなページに移動しました。下記記事を参照下さい。

【参照】当方の記事: CreateJS Graphicsクラスの beginBitmapFill() を考える


画像がなくとも、beginBitmapFill()で処理しているのが特徴です。グラデーションですからキレイで、使用者が自由に変更可能です。

 

1. manifestリスト登録とresult値の取得。

各画像読み込み完了 fileload で、画像をより分ける「方法」がコツだ。


var outback;
var overback;
var assets=[];

//画像manifestリスト
var manifest=[
{src:"/main/images/btnback2.png",id:"overback"},
{src:"/main/images/btnback1.png",id:"outback"},
{src:"/main/images/toyota_car10.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car11.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car12.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car13.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car15.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car16.jpg",id:"PHOTO"}
];

//各画像読み込み完了
function fileload (event) {

	var id=event.item.id;
	//画像選別
	if (id == 'PHOTO') {
		//エラー無しの画像をassets容器に保存
		assets.push(event.result);
	}
	//ボタン画像
	if (id == 'outback') {outback=event.result;}
	if (id == 'overback') {overback=event.result;}
}

2. 「キャンバス要素」を画像の代用にして補正

「キャンバス要素」を画像の代用に利用します。大きさ、色はここで設定下さい。
関数、createGradientCanvas() で得られる値は、ローダーのイベントresult値と同様です。


//全ての画像読み込み完了
function complete (event) {

	途中略す

	//ボタン画像読み込み失敗
	//Gradient
	if(!overback) {overback=createGradientCanvas (60,20,"#DB7093");}
	if(!outback) {outback=createGradientCanvas (60,20,"#BBBBBB");}

	途中略す
}

//色付きcanvasを作る
function createGradientCanvas (w,h,c) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	var gradient=ctx.createLinearGradient(0,h/2,0,0);
	gradient.addColorStop(0,c);
	gradient.addColorStop(1,"#FFFFFF");
	ctx.fillStyle=gradient;
	ctx.rect(0,0,w,h);
	ctx.fill();

	/*
	ctx.fillStyle="white";
	ctx.font="bold 12px Arial";
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	ctx.fillText("NONE",w/2,h/2);
	*/

	return canvas;
}

3. ループで必要の数ボタン画像を生成する、概略のみ記載

上の説明、「キャンバス要素」を入れている所で「代替色」を設定しています。ここでの、out代替色 over代替色、[背景色c] は未使用になります。


(x値,y値,幅,高さ,半径,背景色c,ラベル,文字色,out画像,over画像,out代替色,over代替色,番号no)


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

	略す

	//ボタン画像/代替色の登録
	myBtn[i]=createImagebtn (0,0,60,20,5,"#FFFFFF",label,"#FFFFFF",outback,overback,"#FFFFFF","#DB7093",no);

	略す

}

4. ボタン画像を生成する、createImagebtn()

stage2.update() はステージ2に成っている。前と違う形式に変更されています。


1. 角丸補正で、Opera判定をすると繁雑になるため、全てのブラウザで、quadraticCurveTo方式にした。
(Operaのブラウザエンジンが、Chrome用になっていますので考慮の必要は有りません)
2. 画像なしはキャンバス要素で修正。(新たな方法です)
3. easeljs-0.7のために rollover rollout 形式に変更なります。(mouseover mouseout、と変わりは無い、easeljs-0.7より「イベント処理」が少し変更にはなりましたが、、、)


現在、Operaのブラウザエンジンが、Chrome用に変わっていますので、Chromeと同じ振る舞いのために不具合を考慮しなくとも良くなっています。(他の記事などではこのことに言及していますが、このページでも訂正します)
古いバージョンのOperaでは問題が出ますが、問題の出るバージョンは現在は使用されていないと思います。(2014/09/06 追記)


createImagebtn関数を以下の様に修正します。2014/09/06


● 修正後、CreateJS Graphicsクラス drawRoundRect()使用に修正します。(通常のCreateJS処理にもどった)


//drawRoundRect方式
//画像なしはキャンバス要素
function createImagebtn (x,y,w,h,r,c,label,lc,out,over,outcolor,overcolor,no) {

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

	//Opera判定はしない、quadraticCurveTo方式
	s.graphics.s();
	s.graphics.beginBitmapFill(out).drawRoundRect(x,y,w,h,r);

	btn.addChild(s);
	//myBtn shadow onMouseOverでupdate()すると濃くなる
	//テキスト以外で使用は注意
	btn.shadow=shadow;
	var tx=new createjs.Text(label,"12px Arial",lc);
	tx.x=w/2;
	tx.y=3;
	tx.maxWidth=w;
	//tx.lineWidth=w;
	tx.textAlign="center";
	tx.shadow=shadow;//テキストは濃くなら無い
	tx.name="btntext";//name挿入
	btn.addChild(tx);
	//文字の食み出し防止mask
	tx.mask=s;

	//画像rollover
	btn.addEventListener("rollover",function () {
		s.graphics.clear();
		//Opera判定はしない、quadraticCurveTo方式
		s.graphics.s();
		s.graphics.beginBitmapFill(over).drawRoundRect(x,y,w,h,r);
		stage2.update();
		//サムネールopen
		openThumbBox(no);
	});
	//画像rollout
	btn.addEventListener("rollout",function () {
		s.graphics.clear();
		//Opera判定はしない、quadraticCurveTo方式
		s.graphics.s();
		s.graphics.beginBitmapFill(out).drawRoundRect(x,y,w,h,r);
		stage2.update();
		//サムネールclose
		closeThumbBox(no);
	});
	return btn;
}

beginBitmapFill()は初期で、リピート状態ですので、ボタンの幅が広くなっても画像はそのままで機能します。


修正前のquadraticCurveTo方式です(このままでも問題は有りません)、上記の処理を使用ください。


//create-画像ボタン-quadraticCurveTo方式
//画像なしはキャンバス要素
function createImagebtn (x,y,w,h,r,c,label,lc,out,over,outcolor,overcolor,no) {

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

	//Opera判定はしない、quadraticCurveTo方式
	s.graphics.s();
	s.graphics.beginBitmapFill(out);
	operaRoundRect(s,x,y,w,h,r);

	btn.addChild(s);
	//myBtn shadow onMouseOverでupdate()すると濃くなる
	//テキスト以外で使用は注意
	btn.shadow=shadow;
	var tx=new createjs.Text(label,"12px Arial",lc);
	tx.x=w/2;
	tx.y=3;
	tx.maxWidth=w;
	//tx.lineWidth=w;
	tx.textAlign="center";
	tx.shadow=shadow;//テキストは濃くなら無い
	tx.name="btntext";//name挿入
	btn.addChild(tx);
	//文字の食み出し防止mask
	tx.mask=s;

	//画像rollover
	btn.addEventListener("rollover",function () {
		s.graphics.clear();
		//Opera判定はしない、quadraticCurveTo方式
		s.graphics.s();
		s.graphics.beginBitmapFill(over);
		operaRoundRect(s,x,y,w,h,r);
		stage2.update();
		//サムネールopen
		openThumbBox(no);
	});
	//画像rollout
	btn.addEventListener("rollout",function () {
		s.graphics.clear();
		//Opera判定はしない、quadraticCurveTo方式
		s.graphics.s();
		s.graphics.beginBitmapFill(out);
		operaRoundRect(s,x,y,w,h,r);
		stage2.update();
		//サムネールclose
		closeThumbBox(no);
	});
	return btn;
}

//Opera RoundRec修正用 quadraticCurveTo
function operaRoundRect2(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);
}

beginBitmapFill()は初期で、リピート状態ですので、ボタンの幅が広くなっても画像はそのままで機能します。


5. その他


● MouseOverで陰影が濃く成る

MouseOverで陰影が濃く成るので注意が必要、MouseOver毎に「shadowフィルター」が濃く成る。 防止するにはグラフィックを塗り替える際にグラフィックをクリアすれば治る。


中のShapeインスタンス.graphics.clear();

s.graphics.clear();

● サムネールBOXフェード用Ticker設定

フェードさせないで、簡単に thumbBox.visible を true false だけで制御するならいらない。


thumbBox.tick=function (){
	if(thumbBox.alpha < 1 && thumb) {
		thumbBox.alpha+=0.05;
		stage.update();
	}
}
//Ticker.Listener設定
createjs.Ticker.addEventListener('tick',thumbBox.tick);

● ボタンのactive処理

ボタンへの本格的な active 処理はしていない、簡単に「ラベル文字色」のみを変化させた。表示する画像番号とボタン番号は同じになる様に作って有る。

ここでは、登録 name の'btntext'で判定。登録してなければ getChildAt() で判定すれば良い。


ラベルの name で判定

//activeボタン色変更
for (var i=0; i < image_max; i++) {
	//var target=myBtn[i].getChildAt(1);
	var target=myBtn[i].getChildByName("btntext");
	target.color=(i == image_no) ? "#FF0000":"#FFFFFF";
}
stage2.update();

ボタンの重ね順でも判定可能
var target=myBtn[i].getChildAt(1);



ボタン画像

btnback1.png btnback2.png (100x20)

 

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


「角丸RoundRectボタン」「shadowフィルター」などの問題点などは、下記記事を参照下さい。

【参照】当方の記事: CreateJS 「角丸RoundRectボタン」「shadowフィルター」の振る舞いなどを考える

「グラデーション角丸RoundRectマウスオーバーボタン」は、前ページを参照下さい。

【参照】当方の記事: CreateJS Gradient 角丸RoundRectマウスオーバーボタンを考える


軍手は新しくなって価格据置、消費税込みです。以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]