POPSブログ

CreateJS キャプチャー画像 表示と 画像保存

295

  Category:  javascript2014/05/12 pops 

ステージ画面、あるいはBitmap画像、コンテナなどをキャプチャー(capture)してCanvasに表示したり、画像化してPNG画像保存できるようにHtmlに表示します。
easeljs-0.7.1 でのテストです。

 

CreateJS キャプチャー画像 表示と 画像保存 テスト

Canvasエレメントなどのキャプチャー画像を保存することは特殊と思いますが、キャプチャーしたものを利用できればエフェクトなども多彩になる可能性があります。また、toDataURL() を利用すれば簡単にpng画像に変換できます。


1. ステージ、またはCanvasエレメントなどをキャプチャーします。
2. 画像として保存出来るようにしますが、<img />で出力します。
(location.href はSecurityの関係で IE で機能しないようです)
3. 勿論、キャプチャー画像はCanvas内部でも利用出来ます。
4. CreateJSでは指定の Bitmap、Shape、Container、などをキャッシュ出来ますのでそれを利用する方法も考えられます。(但し、処理が遅い)


 

▼ [ 簡単な説明に進む ]

 

 

DEMO (2種)

▼[ 目次 ]


CreateJS キャプチャー画像 表示と 画像保存 テストのデモ、(createJS079.js/createJS079b.js)

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


1. ステージ画像、保存のデモ 1


2. キャッシュを利用する方法のデモ 2


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


 

HTML JS CSS


使用するライブラリ

easeljs preloadjs tweenjs

配布元 : CreateJS createjs.com


DEMO 1


ライブラリの読み込み

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


<script type="text/javascript" src="js/easeljs-0.7.1.min.js"></script>
<script type="text/javascript" src="js/tweenjs-0.5.1.min.js"></script>

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


jQueryの読み込み

ごく一般的な処理ですから、適当なものを読み込んでください。


HTML (HTML5)



<div id="demo-wrap">
	<div id="image-box">
		<canvas id="mainCanvas" width="640" height="300"></canvas>
	</div>
	<br>
	<p>下の、画像表示エリアを「クリック」すれば、上のステージキャプチャー画像を表示します。(押すたびに画像を更新、右クリックで保存可能)</p>
	<br>
	<div id="download">画像表示エリア(Click=DownLoad)</div>
</div>
<br>

JS

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


//日本語
//createJS079.js
//ステージキャプチャー画像テスト/capture

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

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

//ステージ
var stage;
//コンテナ
var textcontainer,basecontainer;
//陰影
var shadow=new createjs.Shadow("#000000",0,0,4);

//MAIN-TEXT
var maintextcontainer;
var maintext;
//MOVE-TEXT
var textChip=[];
var textPosx=[];
var textPosy=[];

//メインテキスト
var mainstring="ViVa POPS WEB KOUBOU";
//メインテキスト表示位置
var mtcontainer_x=100;//中央補正しない場合
var mtcontainer_y=120;//使用

//完了判定用
var mt_all;
var mt_count=0;

//キャプチャー画像
var cacheImage;

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

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

	//STAGE
	stage=new createjs.Stage('mainCanvas');

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

	//welcome画像層画像表示
	welcomeImage=new createjs.Bitmap(backgroundimage);
	stage.addChild(welcomeImage);
	keep_mainImage=backgroundimage;

	//TEXTアニメコンテナ
	basecontainer=new createjs.Container();//キャッシュ文字ずれ補正用
	maintextcontainer=new createjs.Container();
	basecontainer.addChild(maintextcontainer);
	stage.addChild(basecontainer);

	//Main-Ticker設定
	createjs.Ticker.setFPS(30);
	//createjs.Ticker.timingMode=createjs.Ticker.RAF;
	createjs.Ticker.addEventListener('tick',tick);

	//mainに進む
	main();

}

//MAIN
function main() {

	//MOVE-TEXT配列クリア
	textChip=[];
	textPosx=[];
	vtextPosy=[];

	//MAINテキストアニメ
	set_mainTextanime();

}

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

//MAINテキストアニメ/現在使用
function set_mainTextanime() {

	//MAINテキストアニメーション
	var maintext_W=0;
	var text_spc=0;//テキストスペース
	var center=true;//true
	var tcount=0;

	//インスタンス配列取得
	//サイズ,フォント,色,虹色,スペース,文字/Arial 32px
	textChip=createMoveText("50px","Impact","#FFFFFF",true,text_spc,mainstring);
	var textlen=mainstring.length;

	//完了判定用
	mt_all=textlen;
	mt_count=0;

	//ランダム配置のため全幅の計算を先に
	for (var i=0; i < textlen; i++) {
		maintext_W +=textChip[i].width;
		if(i < textlen) {maintext_W +=text_spc;}
	}
	//コンテナ中央ランダムのため速く決めた
	//X
	if (center) {maintextcontainer.x=(canvasWidth-maintext_W)/2;}
	else {maintextcontainer.x=mtcontainer_x;}
	//Y
	maintextcontainer.y=mtcontainer_y;

	//移動
	var delay_st=[];
	//パターン番号
	var pattern_no=Math.floor(Math.random()*6);
	//多目的判定用フラグ
	var chgxyflag=Math.floor(Math.random()*5);
	//多目的用2
	var chgflag=Math.floor(Math.random()*3);
	var chgflag2=Math.floor(Math.random()*3);
	//逆転フラグ
	var chg_v=Math.floor(Math.random()*2);
	if (chg_v < 1) {chg_v=-1;}

	//回転
	var rotate_no=chgflag*chg_v;
	//スケール
	var sclsdata=[1,1,1,.5,4,8];
	var scls=sclsdata[Math.floor(Math.random()*sclsdata.length)];
	//delay番号
	var delay_no=Math.floor(Math.random()*3);

	var sh=textlen-1;
	var k=0;
	var flag=-1;

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

		//addChild
		maintextcontainer.addChild(textChip[i]);
		//ポジション取得
		textPosx[i]=textChip[i].x;
		textPosy[i]=textChip[i].y;

		//全幅計算は上で行っている
		//maintext_W +=textChip[i].width;
		//if(i < textlen) {maintext_W +=text_spc;}

		//移動左右1、X方向のみ
		if (pattern_no == 0) {
			textChip[i].x=canvasWidth*chg_v;
			textChip[i].y=textPosy[i];
		}
		//移動左右2、Y方向ズレ
		if (pattern_no == 1) {
			textChip[i].x=canvasWidth/2*chg_v;
			textChip[i].y +=100*flag*chg_v*(chgflag2-1);
		}
		//移動上下
		if (pattern_no == 2) {
			textChip[i].x=textPosx[i];//その場
			textChip[i].y=canvasHeight/2*chg_v*(chgflag+1);
			if (chgflag == 1) {
				textChip[i].y *=flag;//上下交互
			}
		}
		//ランダム
		if (pattern_no == 3) {
			//globalToLocal
			var point=maintextcontainer.globalToLocal(Math.random()*canvasWidth,Math.random()*canvasHeight);
			textChip[i].x=point.x;
			textChip[i].y=point.y;
		}
		//文字列の中心から
		if (pattern_no == 4) {
			textChip[i].x=maintext_W/2;
			textChip[i].y=textPosy[i];//その場
		}
		//その場所から
		if (pattern_no == 5) {
			textChip[i].x=textPosx[i]+20*(chgflag-1);//その場少しずらす
			textChip[i].y=textPosy[i];//その場
		}

		textChip[i].rotation=rotate_no*180*(chgflag2-1);
		textChip[i].alpha=0;
		textChip[i].scaleX=scls;
		textChip[i].scaleY=scls;

		//delay
		delay_st[i]=100*i;//標準
		if (delay_no == 1) {delay_st[i]=20*i*i;}
		if (delay_no > 1) {delay_st[i]=Math.abs(i-sh/2)*150;}//150-200

		//交互遅延
		if (chgflag2 == 1) {
			if (flag == 1) {delay_st[i] +=1500;}
		}

		k ++;
		flag *=-1;
	}
	//delay逆転
	if (chgflag == 0) {
		delay_st.reverse();
	}

	//Tween
	for (var i=0; i < textlen; i++) {
		//Tween
		var twn=createjs.Tween.get(textChip[i])
		.wait(delay_st[i])
		.to({x:textPosx[i],y:textPosy[i],scaleX:1,scaleY:1,alpha:1,rotation:0},1000)
		.wait(100).to({scaleX:2,scaleY:2},50)
		.wait(100).to({scaleX:1,scaleY:1},200)
		.wait(500).call(textshadow)
		.call(finshmove);//MOVE終了
	}

}

//要素ごとのアニメ完了処理
function finshmove() {

	//全て完了
	if(mt_count == mt_all-1 ){
		allfinsh();//全て終了に進む
	}
	//0からカウント加算
	mt_count ++;

}

//全て終了
function allfinsh() {

	//遅延
	setTimeout(function() {

		//コンテナの中を削除
		maintextcontainer.removeAllChildren();
		//removeAllTweens必要なら
		createjs.Tween.removeAllTweens();
		//mainに戻る
		main();

	},6000);

}

//TEXT陰影処理
function textshadow() {
	//this.shadow=new createjs.Shadow("#000000",0,0,5);//黒
	this.shadow=new createjs.Shadow("#FFFFFF",-1,-1,2);//白ハイライト
}

//MOVEテキストインスタンスを作る
function createMoveText(size,font,color,rainbow,space,str) {

	var fontdata=size + " " + font;

	var chip=[];
	var len=str.length;
	var tpos_x=0;
	var tpos_y=0;

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

		//文字インスタンスを作る
		var t=new createjs.Text("",fontdata,color);
		//1文字入れる
		t.text=str.charAt(i);
		//幅高さ
		var w=t.getMeasuredWidth();
		var h=t.getMeasuredHeight();
		//原点中央
		t.regX=w/2;
		t.regY=h/2;
		//虹色
		if (rainbow) {
			t.color=createjs.Graphics.getHSL(i/len*360,100,50);//直接
		}
		//位置
		tpos_x +=w/2;//half
		t.x=tpos_x;
		t.y=tpos_y;//0
		//位置加算
		tpos_x +=(w/2+space);//half+space
		//大きさ重要
		t.width=w;
		t.height=h;
		//
		chip[i]=t;
	}
	//戻り配列
	return chip;
}

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

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

//幅、高さ、画像
function createImgCanvas(w,h,patternimg) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,0,0,w,h);

	return canvas;
}


//幅、高さ、画像1画像2
function createCapcherCanvas(w,h,img,img2) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//背景
	//ctx.fillStyle="#000000";
	//ctx.fillRect(0,0,w,h);
	//合成
	ctx.drawImage(img,0,0,w,h);
	ctx.drawImage(img2,0,0,w,h);
	//
	return canvas;
}

//------------------------------------------------------------------------
//LinearGradientBox
//幅、高さ、色1、色2、色3、方向(x.y)、タイプ(2.3)
function createLineGradBox (w,h,color1,color2,color3,direction,type) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");

	//LinearGradient
	var gradient;
	if(direction == 'x') {
		gradient=ctx.createLinearGradient(0,h,w,h);
	}
	if(direction == 'y') {
		gradient=ctx.createLinearGradient(w,0,w,h);
	}
	if(direction == 'xy') {
		gradient=ctx.createLinearGradient(0,0,w,h);
	}
	if(type == 2) {
    		gradient.addColorStop(0,color1);
    		gradient.addColorStop(1,color2);
	}
	if(type == 3) {
    		gradient.addColorStop(0,color1);
		gradient.addColorStop(0.5,color2);
    		gradient.addColorStop(1,color3);
	}
	ctx.fillStyle=gradient;
	//FILL
	ctx.fillRect(0,0,w,h);

	return canvas;
}

//------------------------------------------------------------------------
//ステージエレメントをcapture
function get_image() {

	//ステージエレメント指定
	var canvas=document.getElementById('mainCanvas');
	//キャプチャー画像変換
	cacheImage=createImgCanvas(canvasWidth,canvasHeight,canvas).toDataURL("image/png");

}
//------------------------------------------------------------------------

//jQuery
$("#download").click(function(e) {
	get_image();
	set_download2();
});

//LOAD/少しは早い
function set_download2() {

	var img_v=new Image();
	img_v.src=cacheImage;//保存値

	img_v.onload=function(){

    		//例 現在のウィンドウに出力/IEだめ;
		//location.href=img_v.src;
		//window.open(img_v.src,"","width=640,height=300,resizable=yes");//ブロックされる

		//表示 IEこちらはOK
		$("#download").html('<img />');
		$("#download").children("img").attr({src:img_v.src});
	};

}

//LOAD/getCacheDataURL処理
function set_download3() {

	//処理が遅いのでクリックとあわない

	//cacheされるがステージが停止する
	//cache()はステージのみ、合成が難しい
	stage.cache(0,0,640,300);
	var cachedImage=stage.getCacheDataURL();
	//保存したらアンキャッシュすること
	stage.uncache();

	var img_v=new Image();
	img_v.src=cachedImage;

	img_v.onload=function(){

		//IEこちらはOK
		$("#download").html('<img />');
		//保存値を表示する、IElocation.hrefは機能しない
		$("#download").children("img").attr({src:cachedImage});

	};

}

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

//START

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

backgroundimage.onload=function() {
	init();
}
backgroundimage.onerror=function() {
	//代替画像
	backgroundimage=createLineGradBox(canvasWidth,canvasHeight,"#DD8FAB","#910D39","#DD8FAB","y",2);
	init();
}

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


CSS

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


/*日本語 createJS079.css*/

#demo-wrap {
position:relative;
width:auto;
height:650px;
text-align:center;
}

#image-box {
/*position:absolute;*/
position:relative;
top:0;left:0;
width:640px;
height:300px;
padding:0;
margin:0 auto;
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;
}

#download {
width:640px;
height:300px;
padding:0;
margin:0 auto;
border:1px #CCCCCC solid;
}

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



DEMO 2


ライブラリの読み込み

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


<script type="text/javascript" src="js/easeljs-0.7.1.min.js"></script>
<script type="text/javascript" src="js/tweenjs-0.5.1.min.js"></script>

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


HTML (HTML5)


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

JS

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


//日本語
//createJS079b.js
//キャプチャー画像テスト/capture

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

//ステージ
var stage;
//コンテナ
var textcontainer,basecontainer;
var cachecontainer;
var viewtext;
//陰影
var shadow=new createjs.Shadow("#000000",0,0,4);

//MAIN-TEXT
var maintextcontainer;
var maintext;
//MOVE-TEXT
var textChip=[];
var textPosx=[];
var textPosy=[];

//メインテキスト
var mainstring="ViVa POPS WEB KOUBOU";
//メインテキスト表示位置
var mtcontainer_x=100;//中央補正しない場合
var mtcontainer_y=120;//使用

//完了判定用
var mt_all;
var mt_count=0;

//キャプチャー画像
var cacheImage;
var btn1;
var btn2;

//キャプチャー画像表示判定
var captureOn=false;

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

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

	//STAGE
	stage=new createjs.Stage('mainCanvas');

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

	//welcome画像層画像表示
	welcomeImage=new createjs.Bitmap(backgroundimage);
	stage.addChild(welcomeImage);
	keep_mainImage=backgroundimage;

	//TEXTアニメコンテナ
	basecontainer=new createjs.Container();//キャッシュ文字ずれ補正用
	maintextcontainer=new createjs.Container();
	basecontainer.addChild(maintextcontainer);
	stage.addChild(basecontainer);

	btn1=createShapeBtn (0,0,60,20,5,"Capture","12px","#FFFFFF","#FF69B4",0);
	btn1.x=600;
	btn1.y=25;

	//クリックアクション
	btn1.on("click",handleclick,null,false,0);
	stage.addChild(btn1);

	//キャプチャー画像表示コンテナ
	cachecontainer=new createjs.Container();
	btn2=createShapeBtn (0,0,60,20,5,"Clear","12px","#FFFFFF","#20B2AA",1);
	btn2.x=600;
	btn2.y=275;
	//クリックアクション
	btn2.on("click",handleclick2,null,false,1);
	cacheImage=new createjs.Bitmap();
	cachecontainer.addChild(cacheImage,btn2);
	stage.addChild(cachecontainer);
	cachecontainer.visible=false;


	//TEXT text_useが有効なら作る
	if (text_use) {
		//注意 大きさを設定しないと文字は表示しない
		viewtext=new createjs.Text("","12px Arial","#FFFFFF");
		viewtext.x=20;
		viewtext.y=18;
		viewtext.lineWidth=canvasWidth-40;
		viewtext.lineHeight=20;
		viewtext.textBaseline="bottom";
		stage.addChild(viewtext);
		//テキスト陰影
		viewtext.shadow=shadow;

	}

	//Main-Ticker設定
	createjs.Ticker.setFPS(30);
	//createjs.Ticker.timingMode=createjs.Ticker.RAF;
	createjs.Ticker.addEventListener('tick',tick);

	//mainに進む
	main();

}

//MAIN
function main() {

	//MOVE-TEXT配列クリア
	textChip=[];
	textPosx=[];
	vtextPosy=[];

	//MAINテキストアニメ
	set_mainTextanime();
	//案内テキス/キャプチャー画像表示判定
	if(!captureOn) {
		text_set("Captureボタンを押してください");
	}

}

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

//MAINテキストアニメ/現在使用
function set_mainTextanime() {

	//MAINテキストアニメーション
	var maintext_W=0;
	var text_spc=0;//テキストスペース
	var center=true;//true
	var tcount=0;

	//インスタンス配列取得
	//サイズ,フォント,色,虹色,スペース,文字/Arial 32px
	textChip=createMoveText("50px","Impact","#FFFFFF",true,text_spc,mainstring);
	var textlen=mainstring.length;

	//完了判定用
	mt_all=textlen;
	mt_count=0;

	//ランダム配置のため全幅の計算を先に
	for (var i=0; i < textlen; i++) {
		maintext_W +=textChip[i].width;
		if(i < textlen) {maintext_W +=text_spc;}
	}
	//コンテナ中央ランダムのため速く決めた
	//X
	if (center) {maintextcontainer.x=(canvasWidth-maintext_W)/2;}
	else {maintextcontainer.x=mtcontainer_x;}
	//Y
	maintextcontainer.y=mtcontainer_y;

	//移動
	var delay_st=[];
	//パターン番号
	var pattern_no=Math.floor(Math.random()*6);
	//多目的判定用フラグ
	var chgxyflag=Math.floor(Math.random()*5);
	//多目的用2
	var chgflag=Math.floor(Math.random()*3);
	var chgflag2=Math.floor(Math.random()*3);
	//逆転フラグ
	var chg_v=Math.floor(Math.random()*2);
	if (chg_v < 1) {chg_v=-1;}

	//回転
	var rotate_no=chgflag*chg_v;
	//スケール
	var sclsdata=[1,1,1,.5,4,8];
	var scls=sclsdata[Math.floor(Math.random()*sclsdata.length)];
	//delay番号
	var delay_no=Math.floor(Math.random()*3);

	var sh=textlen-1;
	var k=0;
	var flag=-1;

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

		//addChild
		maintextcontainer.addChild(textChip[i]);
		//ポジション取得
		textPosx[i]=textChip[i].x;
		textPosy[i]=textChip[i].y;

		//全幅計算は上で行っている
		//maintext_W +=textChip[i].width;
		//if(i < textlen) {maintext_W +=text_spc;}

		//移動左右1、X方向のみ
		if (pattern_no == 0) {
			textChip[i].x=canvasWidth*chg_v;
			textChip[i].y=textPosy[i];
		}
		//移動左右2、Y方向ズレ
		if (pattern_no == 1) {
			textChip[i].x=canvasWidth/2*chg_v;
			textChip[i].y +=100*flag*chg_v*(chgflag2-1);
		}
		//移動上下
		if (pattern_no == 2) {
			textChip[i].x=textPosx[i];//その場
			textChip[i].y=canvasHeight/2*chg_v*(chgflag+1);
			if (chgflag == 1) {
				textChip[i].y *=flag;//上下交互
			}
		}
		//ランダム
		if (pattern_no == 3) {
			//globalToLocal
			var point=maintextcontainer.globalToLocal(Math.random()*canvasWidth,Math.random()*canvasHeight);
			textChip[i].x=point.x;
			textChip[i].y=point.y;
		}
		//文字列の中心から
		if (pattern_no == 4) {
			textChip[i].x=maintext_W/2;
			textChip[i].y=textPosy[i];//その場
		}
		//その場所から
		if (pattern_no == 5) {
			textChip[i].x=textPosx[i]+20*(chgflag-1);//その場少しずらす
			textChip[i].y=textPosy[i];//その場
		}

		textChip[i].rotation=rotate_no*180*(chgflag2-1);
		textChip[i].alpha=0;
		textChip[i].scaleX=scls;
		textChip[i].scaleY=scls;

		//delay
		delay_st[i]=100*i;//標準
		if (delay_no == 1) {delay_st[i]=20*i*i;}
		if (delay_no > 1) {delay_st[i]=Math.abs(i-sh/2)*150;}//150-200

		//交互遅延
		if (chgflag2 == 1) {
			if (flag == 1) {delay_st[i] +=1500;}
		}

		k ++;
		flag *=-1;
	}
	//delay逆転
	if (chgflag == 0) {
		delay_st.reverse();
	}

	//Tween
	for (var i=0; i < textlen; i++) {
		//Tween
		var twn=createjs.Tween.get(textChip[i])
		.wait(delay_st[i])
		.to({x:textPosx[i],y:textPosy[i],scaleX:1,scaleY:1,alpha:1,rotation:0},1000)
		.wait(100).to({scaleX:2,scaleY:2},50)
		.wait(100).to({scaleX:1,scaleY:1},200)
		.wait(500).call(textshadow)
		.call(finshmove);//MOVE終了
	}

}
//要素ごとのアニメ完了処理
function finshmove() {

	//全て完了
	if(mt_count == mt_all-1 ){
		allfinsh();//全て終了に進む
	}
	//0からカウント加算
	mt_count ++;

}

//全て終了
function allfinsh() {

	//遅延
	setTimeout(function() {

		//コンテナの中を削除
		maintextcontainer.removeAllChildren();
		//removeAllTweens必要なら
		createjs.Tween.removeAllTweens();
		//mainに戻る
		main();

	},6000);

}

//TEXT陰影処理
function textshadow() {
	//this.shadow=new createjs.Shadow("#000000",0,0,5);//黒
	this.shadow=new createjs.Shadow("#FFFFFF",-1,-1,2);//白ハイライト
}

//MOVEテキストインスタンスを作る
function createMoveText(size,font,color,rainbow,space,str) {

	var fontdata=size + " " + font;

	var chip=[];
	var len=str.length;
	var tpos_x=0;
	var tpos_y=0;

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

		//文字インスタンスを作る
		var t=new createjs.Text("",fontdata,color);
		//1文字入れる
		t.text=str.charAt(i);
		//幅高さ
		var w=t.getMeasuredWidth();
		var h=t.getMeasuredHeight();
		//原点中央
		t.regX=w/2;
		t.regY=h/2;
		//虹色
		if (rainbow) {
			t.color=createjs.Graphics.getHSL(i/len*360,100,50);//直接
		}
		//位置
		tpos_x +=w/2;//half
		t.x=tpos_x;
		t.y=tpos_y;//0
		//位置加算
		tpos_x +=(w/2+space);//half+space
		//大きさ重要
		t.width=w;
		t.height=h;
		//
		chip[i]=t;
	}
	//戻り配列
	return chip;
}

//部材エレメントキャプチャー
function get_captureimage() {

	//部材キャプチャー、面倒だがこれでもOK
	basecontainer.cache(0,0,canvasWidth,canvasHeight);//cacheする
	var elmImage=basecontainer.cacheCanvas;//エレメントcache取得
	basecontainer.uncache();//un-cacheする
	var canvas=createCaptureCanvas(canvasWidth,canvasHeight,backgroundimage,elmImage);//合成して画像に変換
	//表示層Bitmapに収容
	cacheImage.image=new createjs.Bitmap(canvas).image;

}

//クリックアクション1
function handleclick(event,no) {

	//1
	get_captureimage();
	cachecontainer.visible=true;
	captureOn=true;
	//案内テキスト
	text_set("キャプチャー画像を表示しています");

}
//クリックアクション2
function handleclick2(event,no) {

	//2
	cachecontainer.visible=false;
	captureOn=false;
	//案内テキスト
	text_set("キャプチャー画像クリア、Captureボタンを押してください");

}

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

//TEXT表示
function text_set (t) {
	if (text_use) {
		viewtext.text=t;
		stage.update();
	}
}

//------------------------------------------------------------------------
//create-Shapeボタン
function createShapeBtn (x,y,w,h,r,label,size,lc,backcolor,no) {

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

	//BTNコンテナ、黒back付き
	var btn=new createjs.Container();
	var back=new createjs.Shape();//背景
	var shape=new createjs.Shape();
	//Fill
	shape.graphics.beginFill(backcolor).drawRoundRect(x,y,w,h,r);
	shape.regX=w/2;
	shape.regY=h/2;

	var tx=new createjs.Text(label,font_v,lc);
	tx.maxWidth=w;
	tx.textAlign="center";
	tx.textBaseline="middle";
	tx.shadow=shadow;
	btn.addChild(shape,tx);

	//rollover
	btn.addEventListener("rollover",function (e) {
		shape.graphics.clear();
		shape.graphics.beginFill("#DAA520").drawRoundRect(x,y,w,h,r);
		stage.update();
	});
	//rollout
	btn.addEventListener("rollout",function (e) {
		shape.graphics.clear();
		shape.graphics.beginFill(backcolor).drawRoundRect(x,y,w,h,r);
		stage.update();
	});
	return btn;
}
//------------------------------------------------------------------------

//幅、高さ、画像
function createImgCanvas(w,h,patternimg) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,0,0,w,h);

	return canvas;
}


//幅、高さ、画像1画像2
function createCaptureCanvas(w,h,img,img2) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//背景
	//ctx.fillStyle="#000000";
	//ctx.fillRect(0,0,w,h);
	//合成
	ctx.drawImage(img,0,0,w,h);
	ctx.drawImage(img2,0,0,w,h);
	//
	return canvas;
}

//------------------------------------------------------------------------
//LinearGradientBox
//幅、高さ、色1、色2、色3、方向(x.y)、タイプ(2.3)
function createLineGradBox (w,h,color1,color2,color3,direction,type) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");

	//LinearGradient
	var gradient;
	if(direction == 'x') {
		gradient=ctx.createLinearGradient(0,h,w,h);
	}
	if(direction == 'y') {
		gradient=ctx.createLinearGradient(w,0,w,h);
	}
	if(direction == 'xy') {
		gradient=ctx.createLinearGradient(0,0,w,h);
	}
	if(type == 2) {
    		gradient.addColorStop(0,color1);
    		gradient.addColorStop(1,color2);
	}
	if(type == 3) {
    		gradient.addColorStop(0,color1);
		gradient.addColorStop(0.5,color2);
    		gradient.addColorStop(1,color3);
	}
	ctx.fillStyle=gradient;
	//FILL
	ctx.fillRect(0,0,w,h);

	return canvas;
}

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

//START

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

backgroundimage.onload=function() {
	init();
}
backgroundimage.onerror=function() {
	//代替画像
	backgroundimage=createLineGradBox(canvasWidth,canvasHeight,"#DD8FAB","#910D39","#DD8FAB","y",2);
	init();
}

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


CSS

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


/*日本語 createJS079b.css*/

#demo-wrap {
position:relative;
width:auto;
height:100%;
text-align:center;
}

#image-box {
/*position:absolute;*/
position:relative;
top:0;left:0;
width:640px;
height:300px;
padding:0;
margin:0 auto;
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;
}

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


簡単な説明


[ 簡単な説明の目次 ]



 

CreateJS キャプチャー画像 表示と 画像保存

▲[ 目次 ]


[説明図]

 

toDataURL()を利用すれば簡単にpng画像に変換出来ますし、CreateJSでのキャッシュを利用して画像化する事も出来ますが、直接「html5 Canvas処理」するほうが早く効率的のようです。


1. 直接「html5 Canvas処理」する方法。ステージ用途で処理が早い。
2. CreateJSでのキャッシュを利用する方法。ステージ以外の用途で処理が若干遅い。


2種類の方法でテストしてみます。


直接「html5 Canvas処理」する方法

▲[ 目次 ]


「html5 Canvas処理」を覚えなければなりませんが、最近は直接Canvasを処理する事が多くなりました、細やかな処理を出来るのが利点です。
CreateJSでまだ処理出来ないことなど、専用の関数を作りCanvasを処理するのには便利です。
多くは、Canvasに直接、画像、テキスト、図形を表示する処理ですからそう困難なことではありません。


ステージをキャプチャーして画像保存する

▲[ 目次 ]


ステージをキャプチャーするのが一番楽な方法ですが、但し、目的にそぐわない場合もあるかと思いますが......。
ステージのエレメントを指定して、drawImage()処理すれば画像同等のものがが得られます。
画像保存するには、toDataURL() を利用すれば簡単にpng画像に変換出来ますが、ブラウザによっては「保存ダイアログ」を表示出来ませんし、location.href も Security の関係か「IE」では機能しません。
よって <img /> で出力する事にします。ここではjQueryを利用しています。


ステージを指定して、.toDataURL() で画像に変換します。エレメントのIDが判っている場合に有効です。


画像化するのは、.toDataURL("image/png")を実行する時ですので、マシン環境にもよりますがクリックとの時間差が少々出ます。ここではグローバルなcacheImageに一旦保存しています。toDataURL()処理は一般的に結構時間がかかるしブラウザにより差が大きい。


ここでの、createImgCanvas()関数は、ステージを別「canvasエレメント」に書き出します。Canvas内部で利用できますが、画像ではありませんのでその後png画像に変換します。ステージ描画内容をコピーしている処理といえます。


ステージをキャプチャーして画像保存する「デモページ」です: DEMO 1



var cacheImage;

//ステージエレメントをcapture
function get_image() {

	//ステージエレメント指定
	var canvas=document.getElementById('mainCanvas');
	//キャプチャー画像変換
	cacheImage=createImgCanvas(canvasWidth,canvasHeight,canvas).toDataURL("image/png");

}

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

//幅、高さ、画像
function createImgCanvas(w,h,patternimg) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,0,0,w,h);

	return canvas;
}

htmlに表示しますが、「IE」で機能しないことが多いので <img /> で出力しています。Imageオブジェクト.onloadの形式をとった方が確実と思います。jQueryを利用します。


こちらで、.toDataURL("image/png")を実行する事も可能ですが、クリックとの時間差がより大きくなりますので止めて、保存値 cacheImage を使用した。



//jQuery
$("#download").click(function(e) {
	get_image();
	set_download2();
});

//LOAD/少しは早い
function set_download2() {

	var img_v=new Image();
	img_v.src=cacheImage;//保存値

	img_v.onload=function(){

    		//例 現在のウィンドウに出力/IEだめ;
		//location.href=img_v.src;
		//window.open(img_v.src,"","width=640,height=300,resizable=yes");//ブロックされる

		//表示 IEこちらはOK
		$("#download").html('<img />');
		$("#download").children("img").attr({src:img_v.src});
	};

}

画像を表示できましたので、マウス右クリックで保存できます。DiskTopにドラッグはブラウザによっては機能しません。
location.href、window.open、はブラウザにより対応がマチマチですので使用には確認が必要です。


例は掲示しませんが、ステージのキャッシュを取得することが出来ますから、下記の「CreateJSでのキャッシュを利用する方法」で処理する事も可能と思います。


● PNG画像以外での保存

jpeg画像で保存もできますが、ブラウザなどにより対応はまだマチマチです。今後時間の経過とともに多様になってゆくと思います。現時点では、PNG画像での保存が無難です。



.toDataURL("image/jpg")

PNG画像として保存しないで、内部で使用したい場合

▲[ 目次 ]


次の様に drawImage()処理をすれば、「画像result値」として保持出来ますので、表示する際はBitmapクラスを使用します。LOAD画像と同様に扱うことが出来ます。



//ステージキャプチャーエレメント取得
var canvas=document.getElementById('mainCanvas');
//ステージキャプチャー画像を保存
キャプチャー画像result値=createImgCanvas(canvasWidth,canvasHeight,canvas);

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

//幅、高さ、画像
function createImgCanvas(w,h,patternimg) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,0,0,w,h);

	return canvas;
}

● ステージキャプチャーを表示する


Bitmap画像インスタンス=new createjs.Bitmap(キャプチャー画像result値);
stage.addChild(Bitmap画像インスタンス);

ステージキャプチャーですので利用が限定されると予想されます。
「前ページ」の「画像分割アニメ」デモではこちらの方法を利用しています。


 

CreateJSでのキャッシュを利用する方法

▲[ 目次 ]


CreateJSで構成した、Stage、Bitmap、Shape、Container、などのエレメントはステージと違いIDが判りませんので別の方法で行います。指定の階層、インスタンスなどを処理できます、テストの結果わかりました。

Bitmap、Shape、Containerはキャッシュを取得できますので。それをCanvasエレメントの中でdrawImage()処理により合成できます。勿論png画像化して保存も可能です。

Canvasで表示するにはBitmapクラスに挿入すればよろしい訳です。下記の図がその処理の概念です。


 

「CreateJSでのキャッシュを利用する方法」の「デモページ」です: DEMO 2


drawImage()処理で位置を与える場合、デモ例のテキストアニメなどは位置の設定などが面倒ですから、別途コンテナでラップして、位置 00 で簡単に処理できるように工夫しました。
処理し易いように事前に階層を設計しておくことが大事なようです。


 

Bitmap、Shape、Container、の合成

▲[ 目次 ]


drawImage()処理するだけですから簡単ですが、キャッシュを取得する場合に事前に目的のクラスをキャッシュしなければなりませんがキャッシュすれば、アニメ画面などは変化しなくなります。


注意、CreateJSでは、キャッシュするとキャッシュが優先的に表示されます。


1. 事前に目的のクラスをキャッシュする。画像なら直接「result値」を入れることが出来る。
2. キャッシュを取得して、一旦保存する。
3. 保存したら目的のクラスのキャッシュをクリアする。(uncache)
4. 合成する。(createCaptureCanvas()関数処理)
5. Bitmapクラスに挿入して表示する。(Graphicsクラスでも利用できます)
6. 処理の仕方によっては必要な部分の画像データを得ることが出来ます。


● デモでの処理例

下の画像と上のテキストアニメを合成して、一番上の層にBitmapで表示する例である。下層画像はキャッシュを利用できるが、読み込み完了のImage()オブジェクトがあるからそれを使用する。


1. img、下層は画像のために事前に読み込んでいる、backgroundimage を利用した。
2. img2、上層はテキストアニメであるから、キャッシュを利用した。



先読みしている画像
backgroundimage

//部材エレメントキャプチャー
function get_captureimage() {

	//部材キャプチャー、面倒だがこれでもOK
	basecontainer.cache(0,0,canvasWidth,canvasHeight);//cacheする
	var elmImage=basecontainer.cacheCanvas;//エレメントcache取得
	basecontainer.uncache();//un-cacheする
	var canvas=createCaptureCanvas(canvasWidth,canvasHeight,backgroundimage,elmImage);//合成して画像に変換
	//表示層Bitmapに収容
	cacheImage.image=new createjs.Bitmap(canvas).image;

}

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

//幅、高さ、画像1画像2
function createCaptureCanvas(w,h,img,img2) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//背景
	//ctx.fillStyle="#000000";
	//ctx.fillRect(0,0,w,h);
	//合成
	ctx.drawImage(img,0,0,w,h);
	ctx.drawImage(img2,0,0,w,h);
	//
	return canvas;
}

● createCaptureCanvas()関数について

2層の合成用に作ったものですから、処理の次第によっては専用のものを作るか、returnした値をimgにセットして、新しい階層をimg2にセット、複数回処理すれば何層のものでも処理できます。

あるいは、下記の様に ctx.drawImage(....) を増やすなど方法はいくらでもあります。


	適当に増やす

	//合成
	ctx.drawImage(img,0,0,w,h);
	ctx.drawImage(img2,0,0,w,h);
	ctx.drawImage(img3,0,0,w,h);
	........

● 1つのコンテナに全てを収容した場合は、合成の必要はないので、次の関数を使えばよい。結構いろいろな用途に使えますので、便利だ。patternimg は画像、canvasエレメント、キャッシュです。


//幅、高さ、画像
function createImgCanvas(w,h,patternimg) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,0,0,w,h);

	return canvas;
}

上記の関数は当方が使用しているものですから、目的に合わせて補正も可能ですし、グラフイックで装飾も出来ます。これらは使用者の好みです。


 

画像キャッシュを利用する (非推奨)

▲[ 目次 ]


読み込み画像を「画像キャッシュ」をしてもよいが、余計な手間隙がかかるだけである。(別目的のためにある)
get_captureimage()を書き換えてみると以下の様になる。やはり画像は直接利用したほうが便利である。

動作はするが、一般的には下記のようには処理しないでしょう。



//部材エレメントキャプチャー
function get_captureimage() {

	//部材キャプチャー
	//背景画像Bitmap
	welcomeImage.cache(0,0,canvasWidth,canvasHeight);//cacheする
	var elmImage2=welcomeImage.cacheCanvas;//Bitmap cache取得
	welcomeImage.uncache();//un-cacheする

	//TEXTアニメ
	basecontainer.cache(0,0,canvasWidth,canvasHeight);//cacheする
	var elmImage=basecontainer.cacheCanvas;//エレメントcache取得
	basecontainer.uncache();//un-cacheする

	var canvas=createCaptureCanvas(canvasWidth,canvasHeight,elmImage2,elmImage);//合成して画像に変換
	//表示層Bitmapに収容
	cacheImage.image=new createjs.Bitmap(canvas).image;

}

▲[ 目次 ]


 

画像表示しないでメモリー上でキャッシュを処理

▲[ 目次 ]


上記の2つの方法は、どちらとも画像を表示して処理する方法ですが、ステージにaddChildしないでメモリー上で処理することも可能のようです。キャッシュのみほしいと言う場合もありますので、例として下記のような方法になります。


コンテナをステージに addChild していませんので表示はしません。あくまでもメモリー上での処理になります、以下の様に処理しました。contena=null が正しいか不明ですが、正常に処理しますので一応は正しいものと理解します。
コンテナを作るのは複数の部材を扱えるからです。実際の処理などは、下記ページを参照ください。
この部分は重要なため、2014/05/31 追記しました。



//仮のコンテナを作るがステージに addChild しない
var contena=new createjs.Container();

各種処理をする
ここでは、背景、ロゴ、テキストを作り addChild する

contena.addChild(back,logo,text);
//部材キャプチャー
contena.cache(0,0,accordionWidth,accordionHeight);//cacheする
保存容器=contena.cacheCanvas;//cache取得保存
contena.uncache();//un-cacheする

//保存したらコンテナをクリア(削除)する
contena=null;

保存容器である変数を目的に応じて処理すれば良い訳です。
この章の「デモ」はありませんが、実際に次のページで使用しました。「画像化処理」参照。


【参照】当方の記事: CreateJS アコーディオン、画面装飾HOVER(rollover)形式

 

▲[ 目次 ]


DEMOについて

クリックしてから、処理表示までの時間差などわかるようにアニメーションにしていますが、ブラウザ、マシン環境によっても差がでます。他にも色々な方法もあろうかと思いますが....


使用画像

使用画像は原則、使用者が用意ください。デモでは640x300の大きさを使用しました。
デモJSでは画像なしの場合は代替画像を作り表示します。


前ページで、テキストアニメーションの終了画面をキャプチャーして画像分割して使用しています。


【参照】当方の記事: CreateJS 画像分割とテキストアニメーションの組み合わせ (最新)

 

▲[ 目次 ]



一応、完動しますが全てテストです。効率化のため、予告無くJSなど修正する場合がありますので了承下さい。

CreateJSは結構「仕様」が変わりますので特に注意が必要です。


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧



[1]