POPSブログ

CreateJS BitmapData テキストパーティクル 2

281

  Category:  javascript2014/02/25 pops 

BitmapDataクラスを利用しテキストをBitmapDataで1ピクセルに分解して集合拡散を繰り返すTextパーティクルです。原則テキスト背景を描画しないで、処理の効率化を図ったものです。多少の問題点はありますが、一応作動します。
easeljs-0.7 でのテストです。

 

CreateJS BitmapData Textパーティクル 2 効率化テスト


原則、テキスト背景無しで作ります。パーティクルの作成で、背景が0x00000000 (つまり何もない状態)の時に除外して、パーティクルの数を減らしています。
よって、前回のものと比較して5-2倍のテキスト文字数でも処理出来ます。少し処理の効率化を図ったものです。

 

BitmapDataを扱いたいので kudox さんが配布されている BitmapDataクラス を使用しました。下記のページに詳細が有ります。サンプル、マニュアル(日本語)も完備されています。

【参照】kudox.jp記事: BitmapData for EaselJS ver1.00 リリースのお知らせ


 

DEMO


CreateJS BitmapData Textパーティクル 2 テスト、(createJS066.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>
<script type="text/javascript" src="js/bitmapdata-1.0.0.min.js"></script>

重要、バージョン違いでは動かない場合が有りますので必ず合わせて下さい。
尚、別途にkudoxさんの bitmapdata-1.0.0.min.js が必要です。

このデモでは、preloadjs-0.4.0.min.js tweenjs-0.5.0.min.jsは不要です。


HTML (HTML5)


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

JS

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


//日本語
//createJS066.js
//BitmapDataテキストパーティクル2
//easeljs-0.7用

//------------------------------------------------------
//初期設定
//タイマーの使用、true false
var timerUse=true;//true
//切り替えインターバルタイム値 2000-5000
var time=2000;

//canvasの大きさ
var canvasWidth=640;
var canvasHeight=300;
//文字BOXの大きさ
var textBoxWidth=400;
var textBoxHeight=60;

//パーティクルTextの種類 改行無しtrue、改行あり false
var textType=true;

//パーティクルOUTの使用 true false
var outUse=true;
//INパーティクル表示時間5000-10000
var pin_time=5000;

//パーティクルステージ内true、外false
var in_stage=false;
//内側、散らばす範囲 1-2
var range_v=1.5;
//外側、散らばす範囲 2-4
var range2_v=2.5;

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

//説明TEXT
var textUse=true;

//最初の画像0のこと
var textBox_no=0;
//TEXT数
var textBox_max;

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

//ステージ
var stage;
//コンテナ
var overcontainer;
//画像 Bitmapインスタンス
var welcomeImage,overImage;
//Text画像result
var textImage;

//説明TEXTインスタンス
var viewtext;

//Text画像保存容器
var assets=[];

//変数
var timerID=null;
//BitmapData
var bitmapdata;
var set_bmd;

//最大値
var bmd_max;
//位置補正値
var posX_v;
var posY_v;
var maxflag=0;
//Particle
var particles=[];

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

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

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

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

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

	//welcome画像層画像表示/必要なら下に画像を表示
	//画像層確保/Firefox対策
	welcomeImage=new createjs.Bitmap();
	stage.addChild(welcomeImage);
	//非表示
	welcomeImage.visible=false;

	//簡易Loader/Firefox対策
	var img=new Image();
	img.src="/main/images/flower03.jpg";
	img.onload=function() {
		//Bitmap流し込み
		welcomeImage.image=new createjs.Bitmap(img).image;
	}

	//overImage/BitmapData表示領域
	overcontainer=new createjs.Container();
	//最重要、BitmapDataは最初からなければならない
	set_bmd=new createjs.BitmapData(null,canvasWidth,canvasHeight);
	overImage=new createjs.Bitmap(set_bmd.canvas);
	overcontainer.addChild(overImage);
	stage.addChild(overcontainer);

	//簡易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);

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

	//遅延
	setTimeout(function() {

		//Textをセットするに進む
		set_textData();

	},2000);

}

//Textをセットする
function set_textData() {

	var w=textBoxWidth;
	var h=textBoxHeight;

	//改行無しText
	if(textType) {

		//TextData/TEXT付きcanvasを作る
		//幅、高さ、背景色、文字種、サイズ、文字色、陰影、ストリング
		assets[0]=createTextCanvasB (w,h,"rgba(0,0,0,0)","Arial","bold 32px","#FF1493",true,'PARTICLES WELCOME1');//ベタ陰影true
		assets[1]=createTextCanvasB (w,h,"rgba(0,0,0,0)","Arial","bold 32px","#FF7F50",false,'Particle Welcome2');//ベタ陰影false
		//幅、高さ、背景色、文字種、サイズ、文字色、虹色、ストリング
		assets[2]=createTextCanvasB3 (w,h,"rgba(0,0,0,0)","Arial","bold 32px","#FF0000",true,'PARTICLES WELCOME3');//虹色true
		assets[3]=createTextCanvasB3 (w,h,"rgba(0,0,0,0)","Arial","bold 32px","#C71585",false,'PARTICLES WELCOME4');//指定色false
		//幅、高さ、色、文字種、サイズ、文字色、陰影、ストリング
		assets[4]=createTextCanvasB2 (w,h,"rgba(0,0,0,0)","Arial","bold 32px","#00CED1",false,'PARTICLES WELCOME5');//アウトライン
		assets[5]=createTextCanvasB2 (w,h,"rgba(0,0,0,0)","Arial","bold 32px","#FFD700",true,'PARTICLES WELCOME6');//アウトライン
		//幅、高さ、色、文字種、サイズ、文字色1、文字色2、陰影、ストリング
		assets[6]=createTextCanvasB4 (w,h,"rgba(0,0,0,0)","Arial","bold 32px","#7CFC00","#000000",false,'PARTICLES WELCOME7');//グラデTEXT
		assets[7]=createTextCanvasB4 (w,h,"rgba(0,0,0,0)","Arial","bold 32px","#FFFFFF","#DC143C",true,'PARTICLES WELCOME8');//グラデTEXT
	
	}

	//簡易改行複数Text
	//幅、高さ、枠色、文字種、サイズ、文字色、ストリング
	if(!textType) {
		//TextData/TEXT付きcanvasを作る
		assets[0]=createMultipleTextB (w,h,"#FFA500","Arial","bold 15px","#FFFFFF","複数テキスト表示用、改行したように¥n見せることが出来ますが¥n単に表示が可能な程度だ");
		assets[1]=createMultipleTextB (w,h,"rgba(0,0,0,0)","Arial","13px","#C71585","ページ表示後、IN、OUTの集合拡散を繰り返す、¥nテキストパーティクル(画像同等)を実行します。¥n複数のテキストを表示は出来ますが、自動で改行は出来ませんので¥n単に表示が可能な程度だ。");
		assets[2]=createMultipleTextB (w,h,"rgba(0,0,0,0)","Arial","12px","#FFFFFF","表示状況を確認しながら文字の大きさなどで調整します。¥nそんな程度で調整など結構面倒になりますし、¥n余り実用的では有りません。..............");
		assets[3]=createMultipleTextB (w,h,"#48D1CC","Arial","12px","#FFFFFF","CreateJSのTextクラスを使用していません。キャンバスに文字を並べていますので¥n多少の位置調整など可能になります。¥nブラウザにより見え方が違う場合が有ります。");
		assets[4]=createMultipleTextB (w,h,"#CCCCCC","Arial","12px","#FFFFFF","IN OUTの集合拡散を繰り返す複数テキストパーティクルを実行します。¥n改行したように見せることが出来ますが¥n単に表示が可能な程度だ。¥n表示状況を確認しながら文字の大きさなどで調整します。");
		assets[5]=createMultipleTextB (w,h,"rgba(0,0,0,0)","Arial","10px","#FFFFFF","IN OUTの集合拡散を繰り返す複数テキストパーティクルを実行します。¥n複数テキスト表示用、改行したように見せることが出来ますが¥n単に表示が可能な程度だ。¥n表示状況を確認しながら文字の大きさなどで調整します。");
		assets[6]=createMultipleTextB (w,h,"#FFA500","Arial","bold 13px","#FFFFFF","複数テキスト表示用、改行したように¥n見せることが出来ますが¥n単に表示が可能な程度だ");
		assets[7]=createMultipleTextB (w,h,"#FFA500","Arial","bold 12px","#C71585","複数テキスト表示用、改行したように¥n見せることが出来ますが¥n単に表示が可能な程度だ");

	}

	//画像数計算
	textBox_max=assets.length;

	//particle作成
	make_particle();

}

//make-particle
function make_particle () {

//textBox_no=4;

	//画像分割数
	bmd_max=textBoxWidth*textBoxHeight;

	//位置補正値中央
	posX_v=(canvasWidth-textBoxWidth)/2;
	posY_v=(canvasHeight-textBoxHeight)/2;


	//保存Canvasテキスト要素代入
	textImage=assets[textBox_no];
	//色取得のためBitmapData変換
	bitmapdata=new createjs.BitmapData(textImage);

	//Particle
	particles=[];
	var pixel_max=0;//ピクセル数

	//overImage bitmapdata保存処理
	var k=0;
	for (var i=0;i < textBoxWidth;i++) {
		for (var j=0;j < textBoxHeight;j++) {

			//要素の色を取得保存
			var color=bitmapdata.getPixel32(i,j);

			//透明は除く
			if(!color == 0x00000000) {
				var rs=Math.random()*(360);
				var rv=Math.random()*100;
				//中心補正
				if (in_stage) {
					//内/補正に違いあり適当に補正する
					var x=((Math.random()*canvasWidth*2)-canvasWidth/2)*range_v;
					var y=((Math.random()*canvasHeight*2)-canvasHeight+textBoxHeight)*range_v;
				}
				if (!in_stage) {
					//外適当計算
					var x=Math.floor(Math.cos(rs)*(canvasWidth*0.85+rv*range2_v))+canvasWidth/2;
					var y=Math.floor(Math.sin(rs)*(canvasWidth*0.85+rv*range2_v))+canvasHeight/2;
				}
				//パーティクルを作る
				particles[pixel_max]=new Particle(1,x,y,i+posX_v,j+posY_v,x,y,color);//ID付き
				pixel_max ++;
			}

			k ++;

		}
	}

	//着色部分のみを最大処理数とする
	bmd_max=pixel_max;
	//画像表示に進む
	draw();
}

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

	set_text("IN / pixel: "+bmd_max);
	maxflag=0;

	//particle処理はmake_particleに移動

	//Ticker
	createjs.Ticker.addEventListener('tick',move_particles);
}

//集合particles-IN
function move_particles (event) {

	//BitmapData canvasクリア
	set_bmd.clearRect(0,0,canvasWidth,canvasHeight);

	var k=0;
	for (var i=0;i < bmd_max;i++) {

		var p=particles[k];

		//ID
		var id=p.id

		//現在値
		var x=p.x;
		var y=p.y;

		//集合位置
		var sx=p.sx;
		var sy=p.sy;

		//集合速度
		x +=(sx-x)*.1;
		y +=(sy-y)*.1;

		//接近
		if (Math.abs(x-sx) < 0.5 && Math.abs(y-sy) < 0.5) {
			if(id) {
				p.id=0;
				x=sx;y=sy;
				maxflag ++;
			}
		}

		//要素の色を付ける
		if (x > 0) {
			set_bmd.setPixel32(x,y,p.color);
		}

		//保存
		p.x=x;
		p.y=y;

		k ++;

	}

	//setPixelのupdate
	set_bmd.updateContext();

	//終了
	if (maxflag >= bmd_max) {
		finsh_move();
	}

}

//OUT拡散
function out_set () {

	maxflag=0;

	//ここで拡散位置を計算しても良い

	set_text("OUT");
	//OUT表示に進む
	//パーティクルステージ内
	if (in_stage) {createjs.Ticker.addEventListener('tick',out_particles);}
	//パーティクルステージ外
	if (!in_stage) {createjs.Ticker.addEventListener('tick',out_particles2);}

}

//拡散内部用particles-OUT
function out_particles (event) {

	//BitmapData canvasクリア
	set_bmd.clearRect(0,0,canvasWidth,canvasHeight);

	var len=particles.length;
	var k=0;
	for (var i=0;i < len;i++) {

		var p=particles[k];

		//ID
		var id=p.id;
		//現在値
		var x=p.x;
		var y=p.y;
		var ox=p.ox;
		var oy=p.oy;

		//適当な拡散
		x +=(p.ox-x)*.02;
		y +=(p.oy-y)*.02;

		//接近
		if (Math.abs(ox-x) < 100 && Math.abs(oy-y) < 100) {
			if(id == 0) {
				p.id=1;
				x=ox;y=oy;
				maxflag ++;
				len --;
				particles.splice(i,1);
				len=particles.length;
				//消す
				set_bmd.setPixel32(x,y,0x00000000);
			}
		}

		//要素の色を付ける
		if (id == 0) {
			if (x > 0) {
				set_bmd.setPixel32(x,y,p.color);
			}
		}

		//保存
		p.x=x;
		p.y=y;

		k ++;
	}

	//setPixelのupdate
	set_bmd.updateContext();

set_text(""+len);

	//終了
	if (len == 0){finsh_out();}

}


//拡散外部用particles-OUT
function out_particles2 (event) {

	//canvasクリア
	set_bmd.clearRect(0,0,canvasWidth,canvasHeight);

	var len=particles.length;
	var k=0;
	for (var i=0;i < len;i++) {

		var p=particles[k];

		//現在値
		var x=p.x;
		var y=p.y;
		var ox=p.ox;
		var oy=p.oy;

		//適当な拡散
		x +=(x-p.ox)*.02;
		y +=(y-p.oy)*.02;

		//要素の色を付ける
		if (x > 0 && Math.abs(x-p.ox) > 10) {
			set_bmd.setPixel32(x,y,p.color);
		}

		//保存
		p.x=x;
		p.y=y;

		//ステージの外に出た
		if ((x <= 0) || (x > canvasWidth) || (y < 0) || (y > canvasHeight)) {
			len --;
			particles.splice(i,1);
			len=particles.length;
		}

		k ++;
	}

	//setPixelのupdate
	set_bmd.updateContext();

set_text(""+len);

	//終了
	if (len == 0){finsh_out();}

}

//move完了
function finsh_move () {

	set_text("finsh-IN");
	createjs.Ticker.removeEventListener('tick',move_particles);

	if (!outUse) {
		finshtween ();
	}
	if (outUse) {
		//INパーティクル表示時間
		setTimeout(function() {
			out_set();
		},pin_time);
	}

}

//out完了
function finsh_out () {

	//パーティクルステージ内
	if (in_stage) {createjs.Ticker.removeEventListener('tick',out_particles);}
	//パーティクルステージ内外
	if (!in_stage) {createjs.Ticker.removeEventListener('tick',out_particles2);}

	//TWEENなし
	finshtween ();

}

//全て完了
function finshtween () {

	set_text("FINISH");

	//少し遅延
	setTimeout(function() {

		//タイマー次ぎ開く
		if (timerUse) {
			set_timer();
		}
	},500);

}

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

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

	//次ぎの番号
	textBox_no +=1;
	if (textBox_no > (textBox_max-1)) {textBox_no=0;}

	set_text("AUTO");

	//パーティクル計算に戻る
	make_particle ();

}

//タイマー
function set_timer() {

	//タイマー再セット
	if (timerUse) {

		//一旦切ってからセット
		clearTimeout(timerID);
		//切り替えインターバルタイム
		timerID=setTimeout(next_set,time);
	}

}

//VIEWTEXT
function set_text(t) {

	if (textUse) {
		viewtext.text=t;
		stage.update();
	}
}

//------------------------------------------------------
//TEXT付きcanvasを作る
//幅、高さ、色、文字種、サイズ、文字色、陰影、ストリング
function createTextCanvasB (w,h,c,font,fsize,fcolor,shadow,text) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.fillStyle=c;
	ctx.fillRect(0,0,w,h);

	var font_v=fsize +" "+ font;

	ctx.fillStyle=fcolor;
	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	//Textに陰影
	if (shadow) {set_shadow (ctx,"#000000");}
	ctx.fillText(text,w/2,h/2);

	return canvas;
}
//アウトラインTEXT付きcanvasを作る
//幅、高さ、色、文字種、サイズ、文字色、陰影、ストリング
function createTextCanvasB2 (w,h,c,font,fsize,fcolor,shadow,text) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.strokeStyle=c;
	//アウトライン
	ctx.strokeRect(0,0,w,h);

	var font_v=fsize +" "+ font;

	ctx.strokeStyle=fcolor;
	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	//Textに陰影
	if (shadow) {set_shadow (ctx,"#000000");}
	//文字アウトライン
	ctx.strokeText(text,w/2,h/2);

	return canvas;
}

//虹色TEXT付きcanvasを作る3
//幅、高さ、色、文字種、サイズ、文字色、虹色、ストリング
function createTextCanvasB3 (w,h,c,font,fsize,fcolor,rainbow,text) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.fillStyle=c;
	ctx.fillRect(0,0,w,h);

	var font_v=fsize +" "+ font;

	ctx.font=font_v;
	ctx.textAlign="left";
	ctx.textBaseline="middle";

	var len=text.length;
	var spc=-5;//-5 0 +2 位の範囲で文字間隔補正狭める/標準0
	var all_tw=ctx.measureText(text).width;//文字全幅
	var tw=Math.floor((w-(all_tw-spc*-1*len))/2);//初期位置中央是正
	//var tw=5;//左指定
	
	var rainbowColor;//虹色
	for(var i=0;i < len;i++) {

		var t=text.charAt(i);
		var tm=ctx.measureText(t).width;
		//虹色
		if (rainbow) {
			rainbowColor=createjs.Graphics.getHSL(i/len*360,100,50);//直接
			ctx.fillStyle=rainbowColor;
		} else {
			ctx.fillStyle=fcolor;
		}

		//Textに陰影
		set_shadow (ctx,"#000000");

		ctx.fillText(t,tw,h/2);

		tw =tw+tm-spc*-1;

	}

	return canvas;
}

//グラデーションTEXT付きcanvasを作る4
//幅、高さ、色、文字種、サイズ、文字色1、文字色2、陰影、ストリング
function createTextCanvasB4 (w,h,c,font,fsize,fcolor1,fcolor2,shadow,text) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.fillStyle=c;
	ctx.fillRect(0,0,w,h);

	//上指定色下黒グラデーション
	var gradient=ctx.createLinearGradient(0,0,0,h);
	//上
	//16進カラーをrgbの形式に変換1
	var rgbArr=toRgb(fcolor1);
	//旨くしないとエラーになるGraphics.getRGB利用した面倒
	gradient.addColorStop(0.0,createjs.Graphics.getRGB(rgbArr[0],rgbArr[1],rgbArr[2]));//OK
	//下
	//16進カラーをrgbの形式に変換2
	var rgbArr=toRgb(fcolor2);
	gradient.addColorStop(1.0,createjs.Graphics.getRGB(rgbArr[0],rgbArr[1],rgbArr[2]));//OK
	ctx.fillStyle=gradient;

	var font_v=fsize +" "+ font;

	ctx.fillStyle=gradient;
	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";

	//Textに陰影
	if (shadow) {set_shadow (ctx,"#555555");}
	ctx.fillText(text,w/2,h/2);

	return canvas;
}

//------------------------------------------------------
//TEXT付きcanvasを作る/簡易改行用
//幅、高さ、色、文字種、サイズ、文字色、ストリング
function createMultipleTextB (w,h,c,font,fsize,fcolor,text) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//ctx.fillStyle=c;
	//ctx.fillRect(0,0,w,h);

	ctx.strokeStyle=c;
	//アウトライン枠
	ctx.strokeRect(0,0,w,h);

	var font_v=fsize +" "+ font;

	ctx.fillStyle=fcolor;
	ctx.font=font_v;
	//ctx.textAlign="left";;
	ctx.textBaseline="top";

	var textList=text.split('¥n');
	var lineHeight=ctx.measureText("国").width;
	textList.forEach(function(text,i){
    		ctx.fillText(text,5,5+lineHeight*i,w*0.9);
  	});

	return canvas;
}
//------------------------------------------------------
//Textに陰影
function set_shadow (ctx,color) {

	//RGB変換
	rgbArr=toRgb(color);

	//Textに陰影
	//影の色オフセット距離ぼかし量
	//ctx.shadowColor="rgb(0,0,0)";

	//Graphics.getRGB利用した
	ctx.shadowColor=createjs.Graphics.getRGB(rgbArr[0],rgbArr[1],rgbArr[2]);//OK
	ctx.shadowOffsetX=0;
	ctx.shadowOffsetY=0;
	ctx.shadowBlur=3;
}

//変換は配列で返すナントカ使える
function toRgb(bc) {
	bc=bc.replace("#","");
	var rgbArr=[];
	rgbArr[0]=parseInt(bc.slice(0,2),16);
	rgbArr[1]=parseInt(bc.slice(2,4),16);
	rgbArr[2]=parseInt(bc.slice(4,6),16);
	return rgbArr;
}

//------------------------------------------------------
//Particleクラス
var Particle=(function () {
	function Particle(id,x,y,sx,sy,ox,oy,color) {
		this.id=id;
		this.x=x;
		this.y=y;
		this.sx=sx;
		this.sy=sy;
		this.ox=ox;
		this.oy=oy;
		this.color=color;
	}
	var p=Particle.prototype;
	p.id=0;
	p.x=0;
	p.y=0;
	p.sx=0;
	p.sy=0;
	p.ox=0;
	p.oy=0;
	p.color=0x00000000;
	return Particle;
}());

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

//START
init();

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


CSS

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


/*日本語createJS066.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:#000000;
}

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

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


簡単な説明


[説明図]

 

簡単なBitmapData画面での1ピクセル単位、setPixel32着色テキストパーティクル集合拡散サンプルです。
少々効率的に変更しましたが、全てが解決した訳では有りません。(一応動作します)


1. テキスト背景が有りませんので効率的ですが、文字が読み難くなります。
2. 文字が読み難い時、テキストに陰影を付ければ、読み易くなりますがその分要素が増え重く成ります。(他のコンテンツ実行えの影響、環境、などを考慮して決定します、文字数を減らすのも方法です)
3. 合計パーティクル数は、最大、10000-20000 個位が適正と思います。(動作状況をみて判断下さい)
4. アウトライン描画の場合、描画に不具合が出る場合があります。(Fontの問題なので防げない)
5. 文字Y方向の位置がブラウザにより微妙に違います。(背景が無いので判らないでしょう)
6. 問題点、などは以前のままです、詳細は前頁参照下さい。
7. 一応 easeljs-0.7.1でも可動します。


描画したテキストのみパーティクル処理

背景無しですから、着色している部分のみパーティクル処理するように判定しました。処理数が減りますのでその分文字数を増やせることになります。但しテキスト背景(0x00000000以外の着色)を付ければ当然処理数は増えます。
ほんの少し変えただけです。他は殆んど変更無し。


//make-particle
function make_particle () {

	略す

	//Particle
	particles=[];
	var pixel_max=0;//ピクセル数

	//overImage bitmapdata保存処理
	var k=0;
	for (var i=0;i < textBoxWidth;i++) {
		for (var j=0;j < textBoxHeight;j++) {

			//要素の色を取得保存
			var color=bitmapdata.getPixel32(i,j);

			//透明は除く
			if(!color == 0x00000000) {

				略す

				//パーティクルを作る
				particles[pixel_max]=new Particle(1,x,y,i+posX_v,j+posY_v,x,y,color);//ID付き
				pixel_max ++;
			}

			k ++;

		}
	}

	//着色部分のみを最大処理数とする
	bmd_max=pixel_max;
	//画像表示に進む
	draw();
}

強いて言えば、通常の画像も処理出来ます。以前のものは透明の部分も「パーティクル」化していましたので、あたかも「透明人間」がウロチョロしている状態でした。(見えませんけど!)
「007は2度死ぬ」ならぬ「透明人間は2度消える」でしょうか。何となくアクション映画になって来ます。


一行テキスト背景の指定

原則、透明 rgba(0,0,0,0) を指定します。テキスト背景色を設定する場合は16進の色(#000000など)を指定します。
陰影は、true false で指定出来ます。



透明例
//幅、高さ、背景色、文字種、サイズ、文字色、陰影、ストリング
assets[0]=createTextCanvasB (w,h,"rgba(0,0,0,0)","Arial","bold 32px","#FF1493",true,'PARTICLES WELCOME1');//ベタ陰影true

ベタ背景色設定例
assets[0]=createTextCanvasB (w,h,"#FF0000","Arial","bold 32px","#FFFFFF",true,'PARTICLES WELCOME1');//ベタ陰影true

半透過背景色設定例
assets[0]=createTextCanvasB (w,h,"rgba(0,0,0,0.5)","Arial","bold 32px","#FFFFFF",false,'PARTICLES WELCOME1');//ベタ陰影false

改行テキストの設定

文字数が多いと重く成るために、陰影、背景は有りませんので、原則、テキスト色で読み易く調整します。
陰影を付けたい場合は、スクリプトを修正下さい。但し重くなり動作の保障は有りませんんので、文字数を減らすなどの調整と確認が必要です。

将来、マシン環境が向上して、キャンバス処理も進化すれば問題なくなるでしょう。


改行する箇所に「改行文字(¥n)」を挿入下さい。ブラウザにより表示が異なりますので確認の必要が有ります。

実際には「改行文字」で改行はしませんので、それを目安に改行したかの様に処理しています。



枠に色を付ける
//幅、高さ、枠色、文字種、サイズ、文字色、ストリング
assets[0]=createMultipleTextB (w,h,"#FFA500","Arial","bold 15px","#FFFFFF","改行文字とテキスト");

透明枠にする
assets[0]=createMultipleTextB (w,h,"rgba(0,0,0,0)","Arial","bold 15px","#FFFFFF","改行文字とテキスト");

勿論、陰影を付けるように修正しても構いません。


Canvas要素でテキストを作る

テキストは、CreateJS Textクラスを利用してはいません。
Canvas要素を利用してテキストを装飾しています。それ故, スクリプトは「HTML5 Canvas仕様」で書きますので注意下さい。性質はPNG画像と同等に成ります(簡単にいえば、画像を作っている)。
この場合、陰影はテキストのみに有効ですが、書き方、設定場所が悪いと描画しませんので注意下さい。
尚、陰影を軽くするために「オフセット距離ぼかし量」は小さくしています。


改造などで新しいデザイン文字を作り楽しんでください。



//TEXT付きcanvasを作る
//幅、高さ、色、文字種、サイズ、文字色、陰影、ストリング
function createTextCanvasB (w,h,c,font,fsize,fcolor,shadow,text) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.fillStyle=c;
	ctx.fillRect(0,0,w,h);

	var font_v=fsize +" "+ font;

	ctx.fillStyle=fcolor;
	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	//Textに陰影
	if (shadow) {set_shadow (ctx,"#000000");}
	ctx.fillText(text,w/2,h/2);

	return canvas;
}

//Textに陰影
function set_shadow (ctx,color) {

	//RGB変換
	rgbArr=toRgb(color);

	//Textに陰影
	//影の色オフセット距離ぼかし量
	//ctx.shadowColor="rgb(0,0,0)";

	//Graphics.getRGB利用した
	ctx.shadowColor=createjs.Graphics.getRGB(rgbArr[0],rgbArr[1],rgbArr[2]);//OK
	ctx.shadowOffsetX=0;
	ctx.shadowOffsetY=0;
	ctx.shadowBlur=3;
}

● Text陰影の注意点

Text陰影を付ける場合は、テキストを描画する fillText() などの前に「陰影処理」を実行してください。
設定位置が悪いと、陰影処理はなされません。


//Textに陰影
if (shadow) {set_shadow (ctx,"#000000");}//OK
ctx.fillText(text,w/2,h/2);

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

これは順序が違い、ダメ
ctx.fillText(text,w/2,h/2);
if (shadow) {set_shadow (ctx,"#000000");}//ダメ

「HTML5 Canvas仕様」は戸惑う場合がある。中身は個人で自由に変更してください。


パーティクルOUTを使用しない場合

パーティクル「OUT」を使用しない場合は当然「IN」のみの処理になります。切り替え時、別段特別な事はしていませんので、パッと切り替わります。
表示時間は、下記「切り替えインターバルタイム値」で設定出来ます。値は随意。



//切り替えインターバルタイム値
var time=2000;

パーティクル層下の背景画像 [重要]

現在「デモ」では、パーティクルを表示するBitmapData層の下にステージ大の背景画像を表示しています。
何らかの原因で画像を取得出来ない場合、Firefoxで「パーティクルを表示しない」重大エラーになります。(原因不明、確認できているのはFirefoxのみ...他にも在るかも知れない?)


よって下記のごとく、画像を取得出来た時のみ表示する様に「画像エラー処理」をしています。


//welcome画像層画像表示/必要なら下に画像を表示
//画像層確保/Firefox対策
welcomeImage=new createjs.Bitmap();
stage.addChild(welcomeImage);
//表示
welcomeImage.visible=true;

//簡易Loader/Firefox対策
var img=new Image();
img.src="/main/images/flower06.jpg";
img.onload=function() {
	//Bitmap流し込み
	welcomeImage.image=new createjs.Bitmap(img).image;
}

これ以外に、色々と改造して画像と組み合わせた時に、似通った現象が起きる場合も想定されます。このような現象は「IE9」でも想定されます。何らかの解決は可能ですが、「原因不明」の事象に対する対策ですので厄介です。


振る舞い、問題点など

前ページのものと処理などほぼ同じですから、振る舞い、問題点などは下記記事を参照下さい。

【参照】当方の記事: CreateJS BitmapData Textパーティクル


不具合の修正

まだ発生していない不具合など判明した場合はその時点で修正します。判らないでそのままになる場合も有ります。
このサイトの性格上、シラン振りして「こっそり修正」なども有ります。大変無責任な事ですネ!


各種設定

JSの先頭をご覧下さい。


案内用TEXT表示

画面の推移毎に状態など表示しています、削除下さい。(または、textUse=false で表示しない)


使用画像

背景用画像、640x300、必要な場合。



 

これらの改造などは自由です。


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

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


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]