POPSブログ

CreateJS 「角丸RoundRectボタン」「shadowフィルター」の振る舞いなどを考える

214

  Category:  javascript2013/04/22 pops 

CreateJSで 角丸RoundRectボタンを作り、それに「shadowフィルター」を設定してみます。Operaでは角丸RoundRectが壊れます。ブラウザにより多少見た目の違いが出ます。また、マウスオーバーした時の振る舞いも違う様です。問題箇所の修正方法など考えます。
「shadowフィルター」も簡単便利ですが、やはり多少の問題はあるようです。easeljs-0.7 でテストして見ました。

 

CreateJS 「角丸RoundRectボタン」「shadowフィルター」の振る舞いなどを考える


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


RoundRectボタンを作り、それに「shadowフィルター」を設定してみます。ブラウザにより多少見た目の違いが出ます。また、マウスオーバーした時の振る舞いも違う様です。CreateJSで 角丸RoundRectボタンの表示を「カラッポ頭」で考えて見ましょう。

以下、説明はバージョン easeljs-0.7 によるものです。「テストなどの結果」であり、スクリプト記述方法などは個人により違うかとは思います。アシカラズ。

私は「初心者」ですのでマチガイなど在るかも知れません、正確を期すには「専門家」の記事等を参照クダサイ。


[ 目次 ]


「デモ」の JS は「デモ」ページに記載しています。


 

CreateJS、RoundRectボタンの振る舞いなど

▲[ 目次 ]

RoundRectボタンを作り、その振る舞いなどをテストして、問題の解決を探ってみた。下図参照。


1. 角丸RoundRectボタンはグラフィックで簡単に出来るが、Operaで描画が崩れる
2. CreateJSではボタンをMouseOverさせる場合、特別な設定 enableMouseOver が必要
3. Canvasの仕様が完全に策定されては居ないので、ブラウザにより違いがあるが、テキストでは多い。
特に Safari(Win) では、ほとんど有効にならない。Safari(Mac)は不明。
(Safari(Win) は更新をやめたので、実際使用している人はいないと思いますが、当方は確認用で使用)
4. 簡単に陰影を設定できる、CreateJSの「shadowフィルター」を使用してみます。状況により問題がでます。
5.ボタンなどのインスタンスに、「shadowフィルター」を設定すると、MouseOver時フィルターが壊れる
6.マスク処理したインスタンスに「shadowフィルター」を設定してもマスクされて見えない。
7. CanvasのテキストはCSSですので、Canvas以外の他のCSSにも影響されますので注意。まだブラウザにより対応がまちまちで有るから、余りテキストは使用しない方が懸命カナ。
(むしろ、DOMElementクラスでテキスト表示した方がキレイに仕上がる)
8. ブラウザ、モニター、によりCanvasの描画品質が違う。特にGoogle Chromeは良くない。将来に期待!


等が、現在確認できるが、直るものかなどは一切不明である。取り合えず対処方法なども踏まえて記事にする。


[ 説明図 ]

 

 

ボタンの共通設定を考える(標準化)

▲[ 目次 ]

ボタンの共通設定。下記は、角丸RoundRect、ラベルテキスト中央、Safariで文字の食み出し防止、などの処理をしている。(Canvasの仕様が完全策定では無く、ブラウザで差異が大きい、よって状況に応じ変更の必要有り)

CreateJSでは、ボタンにするにはコンテナを作り、中に、グラフィックとテキスト(ラベル)を収納します。

Fontの種類は、以前「_ゴシック」になっていましたが、「Arial」に変更します。ブラウザ違いでも配置高さの差が少ない。



var btn=new createjs.Container();
btn.x=0;
btn.y=0;
//ボタン背景
var s=new createjs.Shape();
s.graphics.s(0).beginFill("#FFFFFF").drawRoundRect(0,0,幅,高さ,半径);
//ラベルテキスト
var tx=new createjs.Text("表示する文字","12px Arial","#000000");
tx.x=幅/2;
tx.y=3;
tx.maxWidth=幅;
tx.textAlign="center";
//文字の食み出し防止mask
tx.mask=s;
//name設定
tx.name="イイカゲンな名前";
btn.addChild(s,tx);
//テキスト以外で使用は注意
btn.shadow=shadow;

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

テキスト位置中央補正、textAlign centerであること
tx.x=テキスト(ボタン)幅の半分;
tx.y=適当な数値;

yの位置は文字の大きさなどの条件により調整する

name設定をしておくと後でアクセスする時便利だ
tx.name="mojida";

MAC Safari での確認はして居りません。文字など独特ですから問題が出るかも知れません。

最近は、regX regYを使用せず textAlign、textBaseline で中央に配置なるように設計しましたのが有ります。グラフイックが面倒ですが、こちらが使い易いかも知れません。下記ページ参照下さい。


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


● テキストをmaxWidthにする

テキスト文字が長い場合に、文字の大きさを変えて指定幅に収まるように、自動調整してくれます。
Safariを除き設定可能、Safariの文字関係はほとんど設定出来ない。そのため文字の食み出しがあるので、マスクで対処した。(Shapeをラベル用のマスクに利用したために、Shapeに「shadowフィルター」は出来ません)

Safariのみ文字の大きさを変えるなどの工夫も必要かな。Safariが対処する時期などは全く不明。


tx.maxWidth

文字は食み出さないが、ブラウザにより文字の大きさ幅などに違いあり。


● テキスにト「shadowフィルター」をする

テキストを見やすくする。テキストはMouseOverで濃くなら無い。

CreateJSの「shadowフィルター」は、簡単でスコブル便利だ!。


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

tx.shadow=shadow;

● テキストを中のShapeでマスクする

Safari(Win)で maxWidth が機能しないので(上図参照)、文字の食み出し防止に中のShapeでマスクする(取り合えず苦肉の策)。Safariで maxWidth が機能するようになればマスクの必要は無い。
ボタンに食み出すほどに、文字を入れる人は居ないとは思いますが、一応用心のためです。但し、Safari(Mac)は未確認ですので問題があれば個別に対処下さい。


tx.mask=s;

 

● ボタンにshadowフィルターをするとMouseOverで濃く成る

▲[ 目次 ]

MouseOverで陰影が濃く成るので注意が必要。仕様なのかバグなのかは不明です。但し対処方法はあります。


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

btn.shadow=shadow;

中のShapeに「shadowフィルター」する事が出来るが、上記の例ではShapeがテキストの「マスク」に使用されているので、出来上がった「ボタン」に「shadowフィルター」を処理している。(これが原因では無い、また外側のCSS3 box-shadow も関係は無い、影のタタリだ!、CreateJSのグラフィックの構成上の問題かも知れない?)


MouseOverで「shadowフィルター」が濃く成る現象がおきる(上図参照)。

MouseOver、MouseOut (または、rollover rollout)の addEventListener() 設定をして、ボタンの色などを変えた場合、
MouseOver毎に「shadowフィルター」が濃く成る。(最後に真っ黒に壊れる)


// 防止するにはグラフィックを塗り替える際にグラフィックをクリアすれば治る。//


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

s.graphics.clear();

「グラフィック」を塗り替える場合は、常に「クリア」してから流し込む様に習慣にすればよい。(AS3では習慣だ)


下の説明、「ボタンインスタンスを指定個数作る」での、グラフィックをクリア例

ボタンに「shadowフィルター」をしている。実際に、MouseOverで濃く成るので「クリア」処理している。他に方法が有るかは現時点では不明だ。(見易い様、修正して書いています)

フィルターの理由。Chromeでの角丸が汚い、「shadowフィルター」をすると以外に見栄えが良いので処理している。


easeljs-0.6ではボタンのMouseOver、MouseOutに mouseover mouseout を使用していたが、

easeljs-0.7から は rollover rollout を使用した方が単純なのでボタン類は書き換える。
但し、以前の mouseover mouseout 形式でも動作します。構造、目的によって使い分けるのでしょうが少判り難い。



//create-bottun
function createbtn (x,y,w,h,r,c,label,lc,overc,outc) {
	//BTNコンテナ
	var btn=new createjs.Container();

	略す

	//rollover
	btn.addEventListener("rollover",function () {
		s.graphics.clear();
		s.graphics.s(0).beginFill(overc).drawRoundRect(x,y,w,h,r);
		stage.update();
	});
	//rollout
	btn.addEventListener("rollout",function () {
		s.graphics.clear();
		s.graphics.s(0).beginFill(outc).drawRoundRect(x,y,w,h,r);
		stage.update();
	});
	return btn;
}

-----------------------------------------------
ここでは中のグラフィックの書き換えが簡単なため
btn.addEventListener("rollover",function () {..........})
の形式にしている

● カーソルに pointer を設定

カーソルの形状などを最小限に設定しないと「動作が重く」成るそうですので必要の無い所は設定しない。また必ず好みの所で表示させるのは難しい場合もあるそうです。
出来上がったボタンインスタンス(container)に pointer を設定しました。


btn.cursor="pointer";

「動作が重く」感じる場合は削除しても良い、どうしても必要なものでも無いし、、


 

クリックアクション関連のEVENTが変更になった

▲[ 目次 ]


● クリックアクションの設定

以前(easeljs-0.6)と違い、ボタンのラップであるコンテナに「クリックアクション」を設定しても中のグラフイックにEVENTは発生しなかったので(内部的に旨く処理されていたのでしょう)、ボタンのEVENTのみを判定すれば良かった。
今回(easeljs-0.7)から「親」であるコンテナに「クリックアクション」設定は中の「子」要素にもEVENTが発生する。前のままだと「クリック」が効かない。構造を考慮して処理しなければならない。


「デモ」の様に複数個のボタンが、ボタン階層コンテナに格納されているものとする。
ボタンの構造は、「親」であるコンテナに「子」である「テキスト要素」と「グラフイック要素」の2つが格納された標準の構造とする。


以前の設定と補正


ボタンインスタンス.addEventListener("click",handleclick);

//処理
function handleclick (event) {

	var target=event.target;
	//押されたボタンは何番目か
	var hit_no=target.parent.getChildIndex(target);

	その外の処置は略す

}

以前のアクションの補正は、次のようにボタン内部にEVENTが及ばないように mouseChildren を加えれば、そのままで機能はするが完全で有るかは不明です。(新しい設定方法が無難です)


ボタンインスタンス.addEventListener("click",handleclick);
ボタンインスタンス.mouseChildren=false;

新しい設定

中の要素の EVENT でも「親」要素を指定するように書く。勿論構造が違った場合は別の書き方に成る。


ボタンインスタンス.addEventListener("click",handleclick);

//処理
function handleclick (event) {

	var instance=event.target.parent;
	//押されたボタンは何番目か
	var hit_no=instance.parent.getChildIndex(instance);
	//インスタンスにIDで番号をいれてあるなら
	//var hit_no=instance.id;

	その外の処置は略す

}

easeljs-0.7 で追加された、on() メソッドで処理する


書式
on(type listener [scope] [once=false] [data] [useCapture=false])

実際の描き方は、引数をループの i値 とすると
ボタンインスタンス.on("click",handleclick,null,false,i);

//処理
function handleclick (event,no) {

	//押されたボタンは何番目か、引数を得る
	var hit_no=no;

	その外の処置は略す

}

以前より、非常に簡単に記述できるし連想配列にすれば複数の引数を渡せる。
この場合(scope は null)、押されたボタンは this で参照できるから便利になる。


 

CreateJSで、角丸RoundRectボックスを作る

▲[ 目次 ]


● CreateJSで、RoundRectボックスを量産する

通常の CreateJS drawRoundRect() を利用します。Operaで角丸がコケマス。「コケ角丸」が出来ます。

角丸を作る共通create関数、半径 r に 0.5 または 1 を入力で「角丸の無い通常の矩形」が出来ます(得意のゴマカシ戦法)。但し 0 入力はエラーになるので注意。

AS3でおなじみの、createXxxx()方式、複数作る時に便利だ。(高度な知識があればクラス化する事も可能かな)


//x,y,width,height,radius,color
var roundRectBox=createRoundRectBox (50,50,100,50,10,"#CCCCCC");
stage.addChild(roundRectBox);

//create-Shapeベタ塗り
function createRoundRectBox (x,y,w,h,r,c) {
	//Shapeを作る
	var s=new createjs.Shape();
	//CreateJSの drawRoundRect処理
	s.graphics.s(0).beginFill(c).drawRoundRect(x,y,w,h,r);
	return s;
}

 

● Operaの角丸RoundRectが壊れる

▲[ 目次 ]

角丸RoundRectボタンはグラフィックで簡単に出来るが、Operaで描画が崩れる。Operaは arcTo の解釈の仕方が違い変形します。治すべきか悩む所です。

現在、Operaのシェアは2%前後位と思います。ホッテおいても良いのですが、余りにも醜いので、修正方法を探しましたら、「Canvasでの修正」方法がありました。
それを、得意の「パクリ」で、スクリプトのグラフィックの描画部分のみ、CreateJSに利用したら修正出来ました。


【参考 引用】stackoverflow.com: How to draw a rounded Rectangle on HTML Canvas?

【参考 引用】html5.jp: quadraticCurveTo() メソッド


Operaのみ、arcTo の書き方の部分を修正するか、quadraticCurveTo は問題ない様ですので、全て、グラフィックの quadraticCurveTo を使用して角丸を作るかの「2つ」の方法になる。

OperaのarcTo処理を他のブラウザで実行すると、崩れた「平行四辺形」になります。Operaが将来修正するかはわかりません。(前のIE、padding の解釈違いの再来だ!)


 

Operaの角丸RoundRectを補正する

▲[ 目次 ]


● 補正

以前は、Operaのみ補正していたが、quadraticCurveTo の形式では全てのブラウザで処理できるので、角丸は一括して補正処理する方が効率的。Operaに対処しないならばCreateJSの角丸処理drawRoundRect()を使用しても良い。

quadraticCurveTo の形式の場合、仮に、Operaが正常に描画するようになっても変更の必要が無くなる。



//x,y,width,height,radius,color
var roundRectBox=createRoundRectShape (50,50,100,50,10,"#CCCCCC");
stage.addChild(roundRectBox);

//create-Shapeベタ塗り
function createRoundRectShape (x,y,w,h,r,c) {
	//Shapeを作る
	var s=new createjs.Shape();
	//角丸処理
	s.graphics.s(0).beginFill(c);
	operaRoundRect(s,x,y,w,h,r);
	return s;
}

//共通角丸処理
//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);
}

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

//Opera専用arcTo、未使用
function operaRoundRect(s,x,y,w,h,r) {
	s.graphics.moveTo(x+r,y)
	.arcTo(x+r,y,x,y+r,r)
	.lineTo(x,y+h-r)
	.arcTo(x,y+h-r,x+r,y+h,r)
	.lineTo(x+w-r,y+h)
	.arcTo(x+w-r,y+h,x+w,y+h-r,r)
	.lineTo(x+w,y+r)
	.arcTo(x+w,y+r,x+w-r,y,r);
}

上の角丸例は、左上が原点です。quadraticCurveTo の形式での中心補正は下の様にすれば移動します。


operaRoundRect(s,-w/2,h/2,w,h,r);

 

CreateJSで、角丸RoundRectボタンを作る

▲[ 目次 ]


CreateJSでは、角丸RoundRectグラフィックを描画するには、drawRoundRect()を指定すれば簡単に作れます。


Shapeインスタンス.graphics.s(ボーダー幅).beginFill(背景色).drawRoundRect(x位置,y位置,幅,高さ,半径)

次ぎの例は、背景色白、ボーダー無し、幅80、高さ20、半径10の角丸グラフィックを描画します。
s.graphics.s(0).beginFill("#FFFFFF").drawRoundRect(0,0,80,20,10)

但し、上の例はCreateJSの標準角丸処理ですから、Operaでコケます。コケ無いのは上で説明。


CreateJSでは、ボタンにするには「コンテナ」を作り、中に、グラフィック(背景)とテキスト(ラベル)を収納します。


Shapeインスタンス.graphics、の書き方

//ボタン(コンテナ)
var btn=new createjs.Container();
btn.x=0;
btn.y=0;
//ボタン背景
var s=new createjs.Shape();
s.graphics.s(0).beginFill("#FFFFFF").drawRoundRect(0,0,80,20,10);
//ラベルテキスト
var tx=new createjs.Text("表示する文字","12px Arial","#000000");
tx.x=40;
tx.y=3;
tx.maxWidth=80;
tx.textAlign="center";
btn.addChild(s,tx);

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

新たにnewでグラフィックを作る場合、書き方の違いに注意
var g=new Graphics();
g.beginFill("#FFFFFF").drawRoundRect(0,0,80,20,10);
var s=new createjs.Shape(g);

注意、var g=new createjs.Graphics()では有りません
------------------------------------------------------

コンテナは複数のインスタンスを並べで設定可能
コンテナ.addChild(インスタンスA, インスタンスB);

勿論、別々にaddChildしても良い
コンテナ.addChild(インスタンスA);
コンテナ.addChild(インスタンスB);

グラフィックはaddChild出来ませんのでShape()に取り込む形で書きます。

グラフィックは好みの形が描ける。テキスト配置は中央にしています。テキストは、x y で位置は調整できます。


マニュアル記載のグラフィックの例、色はRGB形式になっています。


var g = new Graphics();
    g.setStrokeStyle(1);
    g.beginStroke(Graphics.getRGB(0,0,0));
    g.beginFill(Graphics.getRGB(255,0,0));
    g.drawCircle(0,0,3);

    var s = new Shape(g);
        s.x = 100;
        s.y = 100;

    stage.addChild(s);
    stage.update();

 

CreateJSで、角丸RoundRectマウスオーバーボタン

▲[ 目次 ]

ボタンインスタンスを1個作る。マウスオーバー、マウスアウトでボタン背景色が変わるようにしています。
必要ならボタンClickアクション設定も可能ですが、出来上がってから設定したほうが汎用性が良い。

AS3でおなじみの createXxxxx(.....) の形にして見ました。


//x,y,w,h,r,c,label,lc,overc,outc
//x位置,y位置,width,height,半径,背景色,ラベル,ラベル色,マウスオーバー色,マウスアウト色
ボタンインスタンス=createbtn (0,0,80,20,5,"#C0C0FF","BOTTUN","#FFFFFF","#48D1CC","#C0C0FF");

例ではベタ塗りですが、グラフィック部分を変えれば、グラデーション、画像流し込み、切り替えにも応用出来ます。


マウスオーバーを設定する場合の注意

▲[ 目次 ]

必ずステージを設定で enableMouseOver を設定しないと変化しませんので注意です。よく忘れるヨ!


//STAGE
canvasObject=document.getElementById('mainCanvas');
//createjsステージを設定
stage=new createjs.Stage(canvasObject);
//MouseOver重要
stage.enableMouseOver(20);

------------------------------------------------------------
または

//STAGE
stage=new createjs.Stage('mainCanvas');
//MouseOver重要
stage.enableMouseOver(20);


 

● ボタンインスタンスを指定個数作る

▲[ 目次 ]

Operaの角丸RoundRectを補正する処理を付けています。

EventListenerは、addEventListener("rollover",function () {}) の形式です。EventListenerは削除しない前提。
ラベル文字の fontは Arialにしているが日本語の表示も可能。但し、ブラウザで文字の縦方向の位置が微妙に違うがこれは簡単には治せない。


var canvasObject;
var stage;
var btncontainer;
var myBtn=[];

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

	//STAGE
	canvasObject=document.getElementById('mainCanvas');
	//createjsステージを設定
	stage=new createjs.Stage(canvasObject);
	//MouseOver重要
	stage.enableMouseOver(20);

	//ボタンコンテナ
	btncontainer=new createjs.Container();
	btncontainer.x=0;
	btncontainer.y=270;

	//ボタン個数
	var btn_max;
	//ボタン半径
	var round_v=5;

	//Create-Bottun
	for (var i=0; i < btn_max; i++) {

		//ラベル文字生成
		var label="PHOTO"+(i+1);

		//create-bottun1背景色指定/Operaボタンround修正
		//x,y,w,h,r,c,label,lc,overc,outc
		//x位置,y位置,width,height,半径,背景色,ラベル,ラベル色,マウスオーバー色,マウスアウト色
		myBtn[i]=createbtn (0,0,80,20,round_v,"#C0C0FF",label,"#FFFFFF","#48D1CC","#C0C0FF");
		//pointer
		myBtn[i].cursor="pointer";
		//ボタン間隔
		myBtn[i].x=(i*90)+10;

		//ボタン判別用のproperty:nameを書き込む
		myBtn[i].name="btn"+i;
		//myBtn[i].id=i;

		//EventListener設定
		myBtn[i].addEventListener("click",handleclick);

		//myBtn addChild
		btncontainer.addChild(myBtn[i]);

		//必要ならボタンClickアクション設定

	}

	stage.update();

	//その外の処理

}

//create-bottun
function createbtn (x,y,w,h,r,c,label,lc,overc,outc) {
	//BTNコンテナ
	var btn=new createjs.Container();
	btn.x=x;
	btn.y=y;
	var s=new createjs.Shape();
	//角丸処理
	s.graphics.s(0).beginFill(outc);
	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();
		s.graphics.s(0).beginFill(overc);
		operaRoundRect(s,x,y,w,h,r);
		stage.update();
	});
	//rollout
	btn.addEventListener("rollout",function () {
		s.graphics.clear();
		s.graphics.s(0).beginFill(outc);
		operaRoundRect(s,x,y,w,h,r);
		stage.update();
	});
	return btn;
}

但し、DEMOでは画像読み込み完了complete の所でボタンを作成しています。


● 後でテキストにアクセスしたい場合、name を入れて置くと便利。

重ね順で探すことが出来ますが、name propertyを入れて置くと尚便利です。文字列なら何でも構いません。ボタンは myBtn[n] に保存されています。


tx.name="btntext";

------------------------------------------------------
ボタンの文字色を「赤色」に変更する、n がインデックス番号とすれば
var target=myBtn[n].getChildByName("btntext");
target.color="#FF0000";

------------------------------------------------------
重ね順で探しボタンの文字色を「赤色」に変更する、テキストはインデックス 1 にある
var target=myBtn[n].getChildAt(1);
target.color="#FF0000";

重ね順インデックスでも、アクセス出来ますから、name 挿入は自由ですが、AS3と同様に事前の準備が必要です。


 

● 押されたボタン番号の判定

▲[ 目次 ]

押されたボタン番号の判定は、3つの方法があります。どちらを使用しても良いでしょう。


1. ボタンのindex番号(重ね順)を得て判定する。
2. ボタンに、id name などを事前に登録してそれを得て判定する。
3. ボタンの「クリックアクション」で引数を渡す。(easeljs-0.7 で追加された on() を使用する)
4. その他の方法として、HTMLボタンのvalue値を得る事も可能だがここでは除外する。


1. ボタンのindex番号(重ね順)を得て判定する

但し、各々の「子ボタンインスタンス」が、1つの「親コンテナ」に収容されている場合です。ボタン以外は収容しないで下さい。判定が難しくなる。上記説明ではボタンコンテナ(btncontainer)になる。


//クリックアクション
myBtn[i].addEventListener("click",handleclick);
//myBtn addChild
btncontainer.addChild(myBtn[i]);


//handler
function handleclick (event) {

	var instance=event.target.parent;
	//押されたボタンは何番目か
	var hit_no=instance.parent.getChildIndex(instance);
	//インスタンスにIDで番号をいれてあるなら
	//var hit_no=instance.id;

	//その外の処理を書く
}

通常、得られる、index番号は 0 1 2 3 .....となります。最初は 0 です。
easeljs-0.7 から「クリックアクション」設定の EVENT の仕組みが変更になったので注意が必要です。


2. ボタン生成時、各々のボタンに、id name などを事前に登録してそれを得て判定する

IDでは支障が出るなどの場合は、好きな名前で登録する。実際機能するかテストの事。


//ボタンにIDを登録、ボタン判別用のpropertyを書き込む
myBtn[i].id=i;

----------------------------
//handler
function handleclick (event) {

	//idで判定
	var hit_no=event.target.parent.id;

	//その外の処理を書く
}

3. 新しい on() メソッドで「引数」を渡し、それを得て判定する

easeljs-0.7 で追加された、on()では「引数」を渡せますので、今までより簡単になります。引数 i として上記の例を書き換えれば、、、


//クリックアクション
myBtn[i].on("click",handleclick,null,false,i);

----------------------------
//handler
function handleclick (event,no) {

	//引数を得る
	var hit_no=no;

	//その外の処理を書く
}

activeボタン色変更の例 (DEMOの例)

CSSではないので、旨く変更できるように事前の準備が必要。


function draw() {
	略す

	//activeボタン色変更
	for (var i=0; i < image_max; i++) {
		//重ね順で判定
		var target=myBtn[i].getChildAt(1);
		target.color=(i == image_no) ? "#FF0000":"#FFFFFF";
	}

	stage.update();

	略す
}

------------------------------------------------------
事前登録の name に'btntext' を使用するなら
var target=myBtn[i].getChildByName("btntext");

● ボタンラベルの登録

ボタンラベルを事前に登録しての使用も出来ますが、画像読み込み失敗の時にラベルが一致しなくなります。適正な処置をしておけば宜しいが。


var labels=["BOTTUN1","BOTTUN2","BOTTUN3",..............];

//Create-Bottun
for (var i=0; i < btn_max; i++) {
	略す

	myBtn[i]=createbtn (...,labels[i],...);

	略す
}

-------------------------------------
面倒なので、ワタシワこれでごまかした
//ラベル文字生成
var label="PHOTO"+(i+1);

 

マスクとSHADOWのテスト(マスク、SHADOW、は同時に処理出来ない)

▲[ 目次 ]

マスクした要素に「SHADOWフィルター」処理を施すと、SHADOWまでマスクされ「フィルター」が有効になりません。
解決方法を考えてみました。マスクに「SHADOWフィルター」処理をして解決します。但し構造などによって有効でない事も有るでしょう。そんな時は「ナヤメ」。


[ 説明図 ]

 


imageitemにMASKとSHADOWフィルターは駄目だ

var shadow=new createjs.Shadow("#000000",0,0,4);
var testcontainer;

testcontainer=new createjs.Container();//コンテナ
var maskitem=createRoundRectShape (0,0,160,75,10,"#000000");//マスクがあるとする
var imageitem=new createjs.Bitmap("/main/images/toyota_car16s.jpg");
imageitem.width=160;
imageitem.height=75;
imageitem.mask=maskitem;//MASK
imageitem.shadow=shadow;//SHADOW
testcontainer.addChild(imageitem);
stage.addChild(testcontainer);

SHADOWまでマスク(カット)されたと言う事だ。


※ コンテナに「SHADOWフィルター」をして補正 (たまたまコンテナが有った為)

ここではコンテナに収容されている。コンテナは位置の移動用途のためにあり、元来「SHADOWフィルター」の為ではない。取り合えず「SHADOWフィルター」は機能する。コンテナは大きさを設定していないが中の収容要素で広がる。


imageitem.mask=maskitem;//MASK
testcontainer.shadow=shadow;//SHADOW;

 

● 要素にマスク、マスクにSHADOWフィルター処理

▲[ 目次 ]

Bitmap()形式なので、マスクだけなら画像を、先読みでなくともOKのよう、表示が遅れるだけだ。

通常マスク材である Shape は addChild しないで使用するのだそうナ。但し、ここではマスク材(maskitem)は addChild している。でないと「SHADOWフィルター」が見えない。ここが「ミソ」だ。「大吟醸3年合わせミソ」だヨ。


var testcontainer;
var shadow=new createjs.Shadow("#000000",0,0,4);

//マスクテスト160x75
testcontainer=new createjs.Container();
var maskitem=createRoundRectShape (0,0,160,75,10,"#000000");
var imageitem=new createjs.Bitmap("/main/images/toyota_car16s.jpg");
imageitem.width=160;
imageitem.height=75;
imageitem.mask=maskitem;//MASK
maskitem.shadow=shadow;//SHADOW
//imageitem.shadow=shadow;//SHADOW
testcontainer.addChild(maskitem,imageitem);
testcontainer.x=400;
testcontainer.y=50;
stage.addChild(testcontainer);

//create-Shapeベタ塗り
function createRoundRectShape (x,y,w,h,r,c) {
	//Shapeを作る
	var s=new createjs.Shape();
	s.graphics.s(0).beginFill(c);
	operaRoundRect(s,x,y,w,h,r);
	return s;
}

//共通角丸処理
//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);
}

 

● グラフィックで角丸を作り、SHADOWフィルター処理

▲[ 目次 ]

beginBitmapFill()で角丸RoundRectのグラフィックに画像を流し込みます。backimageは先読みしておく事。当然マスクはしません。

beginBitmapFill()の画像は、先読みして下さい。または fileload で保存の event.result を使用の事。画像データが URL では処理できずエラーになるので注意。


var testcontainer2;
var backimage=new Image();
backimage.src="/main/images/toyota_car16s.jpg";

//RoundRect shadow160x75
testcontainer2=new createjs.Container();
var vitem= new createjs.Shape();
//CreateJSのRoundRect処理
//vitem.graphics.s(0).beginBitmapFill(backimage).drawRoundRect(0,0,160,75,10);
//quadraticCurveTo処理
vitem.graphics.s(0).beginBitmapFill(backimage);
operaRoundRect(vitem,0,0,160,75,10);

vitem.shadow=shadow;//SHADOW
testcontainer2.addChild(vitem);
testcontainer2.x=400;
testcontainer2.y=150;
stage.addChild(testcontainer2);

//共通角丸処理quadraticCurveToどちらも使える
//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);
}

● beginBitmapFill()の画像を更新したい場合。

インスタンスはグローバルに作って、最初の画像が表示されているものとする。新しい画像は、先読みして下さい。または fileload で保存の event.result を使用の事。

画像データbackimage を更新して beginBitmapFill() で流し込む。


var vitem;
vitem= new createjs.Shape();
で作ってある

------------------------------------------
更新

backimage=新しい画像データ;
//quadraticCurveTo処理
vitem.graphics.clear();
vitem.graphics.s(0).beginBitmapFill(backimage);
operaRoundRect(vitem,0,0,160,75,10);

 

● マスクの使いまわし

▲[ 目次 ]

AS3の時はマスクする場合に、1個のマスク材を「複数の要素」にマスクは出来なかった。それぞれの要素専用のマスク材が必要であった。不便さを感じたものだ!

しかし、CreateJSでは1個のマスク材(Shape)を「複数の要素」にマスク出来るのは便利である(大きさ位置が同じ場合だ、確認は必要)。


//1個のマスク材
var mask=new createjs.Shape();
mask.graphics.beginFill("#000000").drawRect(0,0,640,300);

//複数の要素にマスク
container.mask=mask;
backcontainer.mask=mask;

 

● CSS3に拠る角丸陰影処理

▲[ 目次 ]

ステージのキャンバス要素、及びそのWRAP構造を、CSS3で border-radius box-shadow 処理しています(余りこんな処理は無いと思うが)。よってCanvasテキストに影響があります。影響を考慮して設定しましょう。


1. CSSの影響が、同じCSSである、テキストなどに及ぶ場合があります。
2. 現在、ボタンには影響は出ていない。
3. Bitmap()、Shape()等が、border-radius の四隅でカットされず食み出す場合がある。コンテナに収容すれば直る時がある。(画像分割でtoDataURL()を使用した場合に画像要素が食み出す、現在はtoDataURL()を使用しない処理にしている)


 

以上、判っている「修正方法」などを述べました。他の条件下で「何らかの症状」が出た時の参考に成るかも知れません。但し、CreateJSバージョンが替わった時は違った振る舞いになる恐れも有ります。「ナヤむチャンスだ!」。


 

DEMO等

▲[ 目次 ]

DEMO


上記、ボタンを作成して、rollover rollout (mouseover mouseoutとほぼ同じ) を設定した簡単な画像フェード デモ。

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


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


参考


Canvas関連の参考になるサイト

【参考】html5.jp : Canvas

【参考】defghi1977-onblog.blogspot.jp : canvas要素の基本的な使い方まとめ


項目毎にページにすれば、「ページが増えてウレシイ」のですが、関連性が有るので「1ページ」にまとめた。損失大。

よって繁雑ですが、以上です。

 


[ この記事のURL ]


 

ブログ記事一覧



[1]