POPSブログ

CreateJS FlickrAPI「キーワード入力画面」付きのワード検索とImage()クロスドメイン画像表示

335

  Category:  javascript2014/12/27 pops 

キーワード検索により、FlickrAPIのデータをjQuery.getJSONで読み込み、サムネール画像をCreateJSで表示し「ドラッグ」可能にします。サムネール「クリック」で大きな画像を表示します。「キーワード入力画面」付きですので、条件を変えて再検索の操作が出来ます。easeljs-0.8.0で標準でクロスドメイン画像を表示出来ませんので(方法はあるが難しい)、javascriptのImage()メソッドを利用しました。
easeljs-0.8.0 でのテストです。

 

CreateJS FlickrAPI「キーワード入力画面」付きのキーワード検索画像表示テスト2

JSは基本的に「前ページ」のeaseljs-0.7.1用のものを改造しただけです。
easeljs-0.8より画像などの読み込みが変更なりましたが、クロスドメイン画像の表示が煩雑のようで、標準の形式では読み込めませんのでとりあえず javascriptのImage()メソッド で対処します。
多少、セキュリティ上問題はありますが、簡単に画像を読み込めます。


zu

 

DEMO (jQuery.getJSON処理)


CreateJS FlickrAPI「タグ入力画面」付きのタグ検索画像表示デモ

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


demo


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


 

HTML JS CSS


使用するライブラリ

easeljs preloadjs tweenjs

配布元 : CreateJS createjs.com


ライブラリの読み込み

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


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

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


jQuery処理用に、事前にjQuery1.8以上を読み込んでおくことが必要です。


HTML (HTML5)



<div id="demo-wrap">
	<div id="image-box" class="radius">
		<canvas id="mainCanvas" width="640" height="640"></canvas>
	<div id="searchPanel" class="">
		KEY <input type="text" id="searchBox" />
		表示数<select name="select">
		<option value="10">10</option>
		<option value="20">20</option>
		<option value="30">30</option>
		<option value="40">40</option>
		</select>
		<button id="searchButton">検索</button>
		<button id="cancelButton">中止</button>
	</div><div class="clear"></div>
	</div>
</div>

JS

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


//日本語
//createJS117.js
//Flickrサムネールドラッグ、キーワード検索入力形式 getJSON
//拡大表示とオーナーページにリンクテスト
//注意、new Image()読み込み方式
//easeljs-0.8.0 デモ用

//------------------------------------------------------
//初期設定

var tags_v="東北新幹線";
//シャッフルをするか/false
var shuffle=false;

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

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

//サムネールbtnの使用 useのこと
var thumbbtn_use="use";
//クリック専用ボタン
var hitbtn=true;//true false
//OWNER-LINKボタン
var ownerlink=true;//true false

//Loading AUTOの文字を表示するかuse
var text_use="use";
//Flickr画像のタイトル文字を表示するかuse
var titletext_use="use";

//表示スケール
var image_scale=1;//原則1未使用
//Flickr読み込み画像数、最大40位まで
var loadImage_len=10;//10-40

//サムネール
var btnR=5;//角丸半径 2-5

//画像manifestリスト空白
var manifest=[];

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

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

//ステージ
var stage;
//Loader
var loader;
//コンテナ
var container,loadingcontainer,progresscontainer;
var titlecontainer;
var btncontainer;
//画像
var welcomeImage,mainImage,backImage,topImage;
//Loading関連
var loadingShape,progressbar,progtext,bar_v;
//TEXT
var viewtext;
var titletext;
var ownertext;
//ROLLOVER-ACTION-LAY
var actionlay;

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

//読み込み画像result保存容器
var assets=[];//サムネールresult保存
var thumb_assets=[];//未使用
//読み込みイメージローダー
var imgloader;

//変数
var globalflag=false;
//loading変数
var loading=false;

//shadowフィルター
var shadow=new createjs.Shadow("#000000",0,0,4);
var once=true;//未使用
//サムネールボタン
var myBtn=[];
//OWNER-LINKボタン
var linkBtn;
var closeBtn;
var openBtn;
//ドラッグ判別
dragflag=false;

//移動Globalポジションデータ
var gpoint_x;
var gpoint_y;
var gangle;//角度
var gscale;//スケール

//jQuery
var search_panel;
var search_box;
var search_button;
var cancel_button;

//flickr
var flickrthumbs=[];
var flickrImages=[];
var flickrLinks=[];
var flickrTitles=[];
var flickrOwners=[];
//成功番号保存
var flickrNos=[];
//
var flickr=false;
var flickrW=[];//小
var flickrH=[];
var flickrbigW=[];//大
var flickrbigH=[];
var loadItem=0;

//ロード数保存
var keep_len=loadImage_len;

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

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

	//インスタンス化
	search_panel=$("#searchPanel");
	search_box=$("#searchBox");
	search_button=$("#searchButton");
	cancel_button=$("#cancelButton");

	//検索ボタンclickイベント
	search_button.click(function(){search_start();});
	//キャンセルボタンclickイベント
	cancel_button.click(function(){search_cancel();});
	//value初期値代入
	search_box.val(tags_v);
	//非表示
	search_panel.addClass("hidden");

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

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

	//welcome画像層画像表示
	welcomeImage=new createjs.Bitmap("/main/images/flickr_back.jpg");//640x640
	stage.addChild(welcomeImage);

	//ステージサムネールコンテナ、あとで作る
	btncontainer=new createjs.Container();
	btncontainer.x=0;
	btncontainer.y=0;
	//サムネールコンテナをステージにaddChild
	stage.addChild(btncontainer);
	btncontainer.visible=false;//非表示
	
	//コンテナに上下画像層配置/中央補正
	container=new createjs.Container();
	container.x=canvasWidth/2;
	container.y=canvasHeight/2;
	//下、透過黒バック挿入
	backImage=new createjs.Bitmap(createColorCanvas (canvasWidth,canvasHeight,'rgba(0,0,0,0.7)'));
	backImage.regX=canvasWidth/2;
	backImage.regY=canvasHeight/2;
	//上、空
	topImage=new createjs.Bitmap();
	container.addChild(backImage,topImage);
	stage.addChild(container);
	container.visible=false;

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

	//ProgressBar
	progresscontainer=new createjs.Container();
	progressbar=new createjs.Shape();
	progtext=new createjs.Text("0","12px Arial","#FFFFFF");
	progtext.x=0;
	progtext.y=15;
	progtext.maxWidth=80;
	progtext.textAlign="center";
	progtext.shadow=shadow;//shadow
	//alpha
	progressbar.alpha=0.5;

	//bar_v判定tickを設定(butt round)
	//90度是正-Math.PI/2
	progressbar.tick=function (){
		if(bar_v > 0) {
			progressbar.graphics.clear();
			progressbar.graphics.setStrokeStyle(8,"butt").beginStroke("#FF69B4");
			progressbar.graphics.arc(0,0,40,-Math.PI/2,Math.PI*2*bar_v-Math.PI/2);
			progtext.text=Math.floor(bar_v*100);
			stage.update();
		}
	}
	//addChild
	progresscontainer.x=canvasWidth/2;
	progresscontainer.y=canvasHeight/2;
	progresscontainer.addChild(progressbar,progtext);
	stage.addChild(progresscontainer);
	progresscontainer.visible=false;//非表示

	//レーヤー
	titlecontainer=new createjs.Container();
	//Overlayを作るを作る
	var overLay=new createjs.Shape();
	overLay.graphics.beginFill('rgba(0,0,0,0.5)').drawRect(0,0,canvasWidth,50);
	//簡易TITLE-TEXT
	//文字、サイズ、フォント、色、X、Y、maxWidth、lineHeight、Align、Baseline、name、陰影
	titletext=createText("","12px","Arial","#FFFFFF",20,20,canvasWidth-40,20,"left","bottom","text",true);
	//簡易OWNER-TEXT
	ownertext=createText("","12px","Arial","#FFFFFF",20,40,canvasWidth-40,20,"left","bottom","text",true);
	//
	titlecontainer.addChild(overLay,titletext,ownertext);
	titlecontainer.y=canvasHeight-50
	stage.addChild(titlecontainer);
	titlecontainer.visible=false;

	//アクションレーヤー
	actionlay=new createjs.Shape();
	actionlay.graphics.beginFill('rgba(0,0,0,0.01)').drawRect(0,0,canvasWidth,canvasHeight);//透過
	stage.addChild(actionlay);

	//アクション変更/ステージアクション少しへんだ
	actionlay.addEventListener('rollover',function(){
		titlecontainer.visible=true;
	});
	actionlay.addEventListener('rollout',function(){
		titlecontainer.visible=false;
	});
	//アクションレーヤー非表示
	actionlay.visible=false;

	//クローズボタン
	//X、Y、幅、高さ、角丸半径、背景色、ラベル、番号
	closeBtn=createTextbtn2 (0,0,50,20,5,"#AAAAAA","CLOSE",0);
	closeBtn.x=canvasWidth-30;
	closeBtn.y=15;
	closeBtn.cursor="pointer";
	stage.addChild(closeBtn);
	//クリックアクション設定
	closeBtn.addEventListener("click",closeBtnhandle);
	closeBtn.visible=false;

	//INPUT-OPENボタン
	//X、Y、幅、高さ、角丸半径、背景色、ラベル、番号
	openBtn=createTextbtn2 (0,0,50,20,5,"#AAAAAA","INPUT",0);
	openBtn.x=canvasWidth-30;
	openBtn.y=15;
	openBtn.cursor="pointer";
	stage.addChild(openBtn);
	//クリックアクション設定
	openBtn.addEventListener("click",openInputhandle);
	openBtn.visible=false;

	//簡易TEXT
	viewtext=createText("Flickr","12px","Arial","#FFFFFF",20,15,canvasWidth-40,20,"left","bottom","text",true);
	stage.addChild(viewtext);

	//データ件数表示
	if(flickr) {set_text(" Flickr読み込みデータ件数: "+loadItem);}
	stage.update();

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

	//調整
	setTimeout(function() {

		//スタート
		set_text("");
		//検索窓表示
		set_input();

	},1000);//1000-3000

}

//INPUT
function set_input() {

	set_text("キーワードを入力して「検索」ボタンを押してください。表示数選択可(10-40)、複数は半角スペースを入れる。");
	//表示
	search_panel.removeClass("hidden");
}
//INPUT-handle
function openInputhandle () {

	//OPEN-BTN
	openBtn.visible=false;
	set_input();

}
//searchキャンセル
function search_cancel () {

	set_text("");
	//非表示
	search_panel.addClass("hidden");
	//INPUT-OPENボタン
	openBtn.visible=true;
}

//searchスタート
function search_start() {

	//非表示
	search_panel.addClass("hidden");

	//ロード数補正
	loadImage_len=keep_len;

	//flickrクリア
	flickrthumbs=[];
	flickrImages=[];
	flickrLinks=[];
	flickrTitles=[];
	flickrOwners=[];

	flickr=false;
	flickrW=[];//小
	flickrH=[];
	flickrbigW=[];//大
	flickrbigH=[];
	loadItem=0;

	//jQuery value値取得
	//load数変更
	var len=$("select[name='select']").val()*1;
	if(loadImage_len !=len) {loadImage_len=len;}

	//Key用
	tags_v=search_box.val();//Keyで検索
	set_text("Flickr検索中 [ " + tags_v + " ]");

	//Flickr検索実行
	getFlickrData();//Flickr

}
//FlickrDataのセット
function set_flickrSearchData() {

	//INPUT-OPENボタン
	openBtn.visible=true;
	//読み込み画像result保存容器配列などクリア
	assets=[];//使用
	thumb_assets=[];//未使用
	myBtn=[];
	//サムネール階層クリア
	btncontainer.removeAllChildren();

	//flickr-Data読み込み成功、画像ロードに進む
	if(flickr) {

		viewtext.x=20;
		viewtext.y=15;

		//flickrのmanifestリスト作成
		manifest=[];
		for (var i=0; i < flickrthumbs.length; i++) {

			var src=flickrthumbs[i];
			var id="image";

			manifest.push({
				src:src,
				id:id
			});

		}

		set_text("Loading Now!");
		bulkload();
	}
	//失敗
	if(!flickr) {
		viewtext.x=100;
		viewtext.y=canvasHeight/2;
		var mass="Flickrの読み込み失敗、表示出来ませんので停止します!";
		if(loadImage_len == 0) {mass="key検索結果が有りません、表示出来ませんので停止します!";}
		set_text(mass);
	}

	//openBtn表示
	openBtn.visible=true;

}

//progressBar2
function progress(v) {
	//0-1
	bar_v=v;
}

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

	set_text("Loading Now!");

	//ProgressBar-Listener設定
	createjs.Ticker.addEventListener('tick',progressbar.tick);

	//Loading
	loadingcontainer.visible=true;
	loading=true;//loading表示判定
	//ProgressBar
	bar_v=0;
	progresscontainer.visible=true;//表示

	//画像マルチローダーに進む
	imageload_count=0;
	multiLoader();

}

//画像マルチローダー
function multiLoader() {

	//ProgressBar描画
	progress(imageload_count/loadImage_len);

	//画像Load終了判定
	if(imageload_count < loadImage_len) {
		//読み込み
		getLoadImage();
	} else {
		//終了
		multicomplete();
	}
}
//new Image()の実行
function getLoadImage() {

	//new Loader
	var image_loader=new Image();
	image_loader.onload=function() {

		//読み込みOK
		//サムネール大きさ取得
		flickrW.push(image_loader.width);
		flickrH.push(image_loader.height);
		//サムネールobject保存
		assets.push(image_loader);
		//次画像のロード
		imageload_count ++;
		multiLoader();
	}
	image_loader.onerror=function() {

		//NGは100x66代替画像を入れて次画像のロードに進む
		assets.push(createColorCanvas(100,66,"#CCCCCC"));
		flickrW.push(100);
		flickrH.push(66);
		imageload_count ++;
		multiLoader();
	}
	//URL
	image_loader.src=manifest[imageload_count].src;
}

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

	//Bar修正
	progress(1);
	//画像数確認、再計算
	image_max=assets.length;
	//簡易TEXT
	set_text("Loading End!")
	//loading EventListenerは削除しない
	//非表示
	loadingcontainer.visible=false;
	loading=false;//loading表示判定

	//OWNER-LINKボタン
	if(ownerlink) {

		//X、Y、幅、高さ、角丸半径、背景色、ラベル、番号
		linkBtn=createTextbtn2 (0,0,90,20,5,"#AAAAAA","OWNER-LINK",0);
		linkBtn.x=canvasWidth-50;
		linkBtn.y=canvasHeight-15;
		linkBtn.cursor="pointer";
		stage.addChild(linkBtn);
		//クリックアクション設定
		linkBtn.addEventListener("click",ownerlinkhandle);
		linkBtn.visible=false;

	}

	//set_text(" " + image_max + "件の検索結果を表示します。");
	set_text(" [検索結果DATA数]/ " + loadItem + " [表示数] " + loadImage_len + "件の検索結果を表示します。");

	//画像があれば
	if (image_max) {

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

			//progress非表示
			progresscontainer.visible=false;

			//簡易TEXTクリア
			set_text("");
			//thumbBtnのセット
			set_thumbBtn();//停止

		},delay_speed);
	}

}

//thumbBtnのセット
function set_thumbBtn() {

	//サムネールボタンを作る
	for (var i=0; i < image_max; i++) {

		//サムネールの大きさ
		var btnW=flickrW[i];
		var btnH=flickrH[i];
		//番号受け渡し
		var no=i;

		//アクションつきサムネール
		//X、Y、幅、高さ、角丸半径、色、HitBTN、HitBT色、画像、番号
		myBtn[i]=createDragThumbCenterbtn(0,0,btnW,btnH,btnR,"#FF0000",hitbtn,'rgba(0,0,0,0.01)',assets[i],no);//透過0.01

		//ランダム配置
		if(image_max > 1) {
			myBtn[i].x=Math.floor(Math.random()*(canvasWidth-btnW))+btnW/2;
			myBtn[i].y=Math.floor(Math.random()*(canvasHeight-btnH))+btnH/2;
		} else {
			//1つ場合中央に補正
			if(image_max == 1) {myBtn[i].x=canvasWidth/2;myBtn[i].y=canvasHeight/2;}
		}

		//傾ける/6以下は0に補正
		var angl=Math.floor(Math.random()*120)-60;
		if(Math.abs(angl) < 6) {angl=0;}
		myBtn[i].rotation=angl;

		//ボタン判別用のidを書き込む、未使用
		myBtn[i].id=i;
		//myBtn addChild
		btncontainer.addChild(myBtn[i]);

	}

	//FadeIn
	btncontainer.alpha=0;
	btncontainer.visible=true;//表示
	//TWEENの実行
	var tw=createjs.Tween.get(btncontainer)
	.to({alpha:1},1000);

}

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

	globalflag=true;

	//MODE 0-1
	var mode=Math.floor(Math.random()*2);

	//imgloader画像をそのまま使用
	mainImage=imgloader;
	topImage.image=new createjs.Bitmap(mainImage).image;

	//上画像更新画像Bitmap挿入、中央補正なし回転は出来ない
	topImage.regX=flickrbigW[image_no]/2;
	topImage.regY=flickrbigH[image_no]/2;

	//スケール計算
	gscale=flickrW[image_no]/flickrbigW[image_no];

	//サムネールインスタンス位置角度で補正
	//移動位置Global-Point
	topImage.x=gpoint_x;
	topImage.y=gpoint_y;
	topImage.rotation=gangle;
	topImage.scaleX=topImage.scaleY=gscale;
	topImage.alpha=0;

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

}

//フェードアニメ完了
function finshtween () {

	closeBtn.visible=true;
	//アニメ作業中である
	globalflag=false;

	//少し遅延させる
	setTimeout(function() {

		//FlickrTitle
		set_titletext("TITLE: "+flickrTitles[image_no]);
		set_ownertext("OWNER: " + flickrOwners[image_no]);
		//パーツオープン
		partsCtrl(true);


	},500);

}

//tickステージ
function tick() {
	stage.update();
}

//VIEWTEXT
function set_text(t) {
	if (text_use == 'use') {
		viewtext.text=t;
	}
}
//TITLETEXT
function set_titletext(tt) {
	if (titletext_use == 'use') {
		titletext.text=tt;
	}
}
function set_ownertext(tt) {
	if (titletext_use == 'use') {
		ownertext.text=tt;
	}
}

//BtnClick/on/parent
function handleclick (event,no) {

	//ドラッグmoveしたときはアニメしない
	if (dragflag) {return}

	//OPEN-BTN
	openBtn.visible=false;
	//on
	var hit_no=no;

	//親インスタンス位置角度取得
	var instance=event.target.parent;
	//Point/btncontainerコンテナ基準Globalを修正保存
	//btncontainer原点左上
	var point=btncontainer.localToGlobal(instance.x,instance.y);
	//Global-Point/修正
	gpoint_x=point.x-canvasWidth/2;
	gpoint_y=point.y-canvasHeight/2;
	//角度取得
	gangle=instance.rotation;

	//指定番号の画像LOAD
	imageLoad(flickrImages[hit_no],hit_no);

}
//ジャンプボタン
function ownerlinkhandle (event) {
	//open
	window.open(flickrLinks[image_no],null);//blank
	//location.href=flickrLinks[image_no];//使い難い
	return false;
}

//ドラッグListener/アクション専用層に設定した
function press(event) {
	var instance=event.target.parent;
	//ドラッグ開始
	dragflag=false;//move判定
	mousePoint=instance.globalToLocal(event.stageX,event.stageY);
	//直接eventでは無くinstanceに
	instance.addEventListener("pressup",stopdrag);
	instance.addEventListener("pressmove",drag);
	//重ね順を一番上にする
	btncontainer.setChildIndex(instance,image_max-1);
}
function stopdrag(event) {
	var instance=event.target.parent;
	instance.removeEventListener("pressup",stopdrag);
	instance.removeEventListener("pressmove",drag);
}
function drag(event) {
	dragflag=true;//動いた時のみtrue
	var instance=event.target.parent;
	var offset=instance.localToGlobal(mousePoint.x,mousePoint.y);
	instance.x +=event.stageX-offset.x;
	instance.y +=event.stageY-offset.y;
	stage.update();
}

//クローズクリックアクション
//BtnClick/on
function closeBtnhandle (event) {

	partsCtrl(false);

	//TWEENの実行/先のGlobalポイントに戻る
	var tw=createjs.Tween.get(topImage)
	.to({x:gpoint_x,y:gpoint_y,scaleX:gscale,scaleY:gscale,rotation:gangle,alpha:0},speed*0.75)
	.wait(500)
	.call(function() {
		//画像コンテナ非表示
		container.visible=false;
		//OPEN-BTN
		openBtn.visible=true;
	});
}

//パーツ表示切り替え、open=trueで表示
function partsCtrl (open) {

	//ボタン
	closeBtn.visible=open;
	//OWNER-LINK
	if (ownerlink) {
		linkBtn.visible=open;
	}
	//アクションレーヤー
	actionlay.visible=open;

}

//imageLoader/1枚Load
function imageLoad(imgurl,no) {

	loadingcontainer.visible=true;
	loading=true;
	viewtext.text="Loading Now";

	imgloader=new Image();
	imgloader.onload=function() {
		//読み込みOK
		image_no=no;
		viewtext.text="";
		loadingcontainer.visible=false;
		loading=false;
		//WH
		flickrbigW[image_no]=imgloader.width;
		flickrbigH[image_no]=imgloader.height;

		//画像コンテナ表示
		container.visible=true;
		//画像表示
		setTimeout(function() {
			draw();
		},500)
	}
	imgloader.onerror=function() {
		//NG
		viewtext.text="ERROR";
		loadingcontainer.visible=false;
		loading=false;
	}
	imgloader.src=imgurl;
}

//文字center/middle
//文字、サイズ、フォント、色、X、Y、maxWidth、lineHeight、Align、Baseline、name、陰影
function createText (text,size,font,color,x,y,maxw,lineh,align,bline,txname,shadowf) {

	//TEXT
	var font_v=size + " " + font;
	var tx=new createjs.Text(text,font_v,color);
	tx.x=x;
	tx.y=y;
	tx.maxWidth=maxw;
	tx,lineHeight=lineh;
	tx.textAlign=align;
	tx.textBaseline=bline;
	tx.name=txname;//name挿入
	//shadow
	if(shadowf) {
		tx.shadow=new createjs.Shadow("#000000",0,0,4);
	}

	return tx;
}

//create-サムネールドラッグボタン
//X、Y、幅、高さ、角丸半径、色、HitBTN、HitBT色、画像、番号
function createDragThumbCenterbtn (x,y,w,h,r,acolor,btn_make,btncolor,img,no) {

	//BTNコンテナ
	var btn=new createjs.Container();
	btn.x=x;
	btn.y=y;
	var s=new createjs.Shape();
	//角丸画像挿入
	s.graphics.beginBitmapFill(img).drawRoundRect(x,y,w,h,r);//画像
	s.name="graphic";//name挿入
	//原点移動、グラフイックを容易にするため
	s.regX=w/2;
	s.regY=h/2;

	//アクション専用層
	var hits=new createjs.Shape();
	hits.graphics.beginFill(btncolor).drawRoundRect(x,y,w,h,r);//透過ボタン
	hits.name="click";//name挿入
	hits.regX=w/2;
	hits.regY=h/2;
	hits.cursor="pointer";
	//クリックアクション
	hits.on("click",handleclick,null,false,no);
	//ドラッグアクション/アクション専用層に
	hits.addEventListener("mousedown",press);
	btn.addChild(s,hits);
	btn.shadow=shadow;

	return btn;
}

//文字ボタン
//X、Y、幅、高さ、角丸半径、背景色、ラベル、番号
function createTextbtn2 (x,y,w,h,r,color,label,no) {

	//BTNコンテナ
	var btn=new createjs.Container();
	btn.x=x;
	btn.y=y;
	l=new createjs.Text(label,"12px Arial","#FFFFFF");
	l.maxWidth=w;
	l.textAlign="center";
	l.textBaseline="middle";
	l.name="text";//name挿入
	var s=new createjs.Shape();
	s.graphics.beginFill(color).drawRoundRect(x,y,w,h,r);
	s.name="back";//name挿入
	s.regX=w/2;
	s.regY=h/2;
	btn.addChild(s,l);
	btn.shadow=shadow;

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

//色付きcanvasを作る
function createColorCanvas (w,h,c) {
	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);
	return canvas;
}

//FlickrCanvas
function createFlickrCanvas(w,h,img,img_w,img_h,scale_v,backcolor) {

	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.fillStyle=backcolor;
	ctx.fillRect(0,0,w,h);
	ctx.translate(w/2,h/2);
	ctx.drawImage(img,-(img_w*scale_v)/2,-(img_h*scale_v)/2,img_w*scale_v,img_h*scale_v);

	return canvas;
}

//簡単なLOADING3
function loadingIndicator3 () {

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

	//描画データ
	var alpha_v=1;//透明度
	var alphaback;

	var cx,cy;
	var numNeedles=12;
	var innerR=15;
	var outerR=10;
	var cAngle=-Math.PI/2;
	var nAngle;

	//ライン描画
	nAngle=Math.PI*2/numNeedles;
	for (var i=0; i < numNeedles; i++){

		//回転補正
		rotateflag=cAngle -=nAngle;
		//透明度を描画毎に変更
		if (i > 0) {alpha_v -=0.05;}

		//#CCCCCC
		alphaback=createjs.Graphics.getRGB(204,204,204,alpha_v);
		cx=Math.cos(cAngle)*innerR;
		cy=Math.sin(cAngle)*innerR;
		graphics.beginStroke(alphaback).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;
}

//jQuery-getJSON
function getFlickrData(){

	//https重要
	var FlickrAPI="https://api.flickr.com/services/rest/?jsoncallback=?";

	//データ数指定
	var perpage=100;//シャッフル
	if(!shuffle) {perpage=loadImage_len;}

	$.getJSON(FlickrAPI,{

		method:"flickr.photos.search",
		api_key:"32dbd23f3f7e6d0ae494b99eebb57c93",
		per_page:perpage,
		extras:"owner_name",
		text:tags_v,
		format:"json"
	})
	.done(function(data){

		//var json_text=JSON.stringify(data);
		//$("#logtext").text(json_text);

		flickr=false;
		var photos=data.photos.photo;
		//検索item数エラー処理
		var item_len=photos.length || 0;
		loadItem=item_len;//データ数保存
		//補正
		if(item_len < loadImage_len){loadImage_len=item_len;}

		//DATAがあれば
		if(item_len > 0) {

			//シャッフル配列に数字を入れる
			if(shuffle) {
				var arr_no=[];
				for(var i=0; i < photos.length; i++){
					arr_no.push(i);
				}
				//配列をシャッフル/0はエラー
				arr_no.sort(function() {return Math.random()-0.5;});
			}

			for(var i=0; i < photos.length; i++){

				var no=i;//シャッフル無し
				//シャッフル
				if(shuffle) {
					no=arr_no[i];
				}

				var farmId=photos[no].farm;
				var serverId=photos[no].server;
				var id=photos[no].id;
				var secret=photos[no].secret;
				var title=photos[no].title;
				var owner=photos[no].owner;
				var ownername=photos[no].ownername;

				var thumb_url="https://farm" + farmId + ".staticflickr.com/"+ serverId +"/" + id + "_"+ secret +"_t.jpg";
				var img_url="https://farm" + farmId + ".staticflickr.com/"+ serverId +"/" + id + "_"+ secret +"_z.jpg";
				var link_url="https://www.flickr.com/photos/" + owner +"/" + id;

				//画像保存
				flickrthumbs.push(thumb_url);
				flickrImages.push(img_url);
				flickrTitles.push(title);
				flickrLinks.push(link_url);
				flickrOwners.push(ownername);
				//定量break
				if(i == loadImage_len-1){break;}

			}
			flickr=true;

		} else {
			flickr=false;
			loadImage_len=0;
		}

		set_flickrSearchData();

	})
	.fail(function(){
		flickr=false;
		set_flickrSearchData();
	});
}

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

//START
window.onload=function() {
	init();

}

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


CSS

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


/*日本語 createJS117.css*/

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

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

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

#searchPanel{
position:absolute;
left:10px;
top:25px;
display:block;
width:auto;
height:25px;
padding:2px 5px 0 5px;
text-align:left;
font-size:12px;
color:#FFFFFF;
background-color:#555555;
float:left;
}
#image-box .hidden {
display:none;
}
#searchBox{
width:180px;
}

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


 

簡単な説明


[説明図]

zu

 

photos.search メソッドのキーワード検索ビューアー


flickrAPIの photos.search メソッド を利用し、キーワード検索します。原則、JSON形式のデータを得ます。


1. クロスドメイン画像をCanvas表示していますので、セキュリティ上問題があります。
(信頼の於けるサイトで無ければ、画像取得は行わないことが肝要です)
2. クロスドメイン画像のため、Canvas表示の際にCreateJS処理で問題が出ます。
(一応解決していますが、詳細などは「前ページ」などを参照ください。)


キーワード検索とタグ検索の違い

写真登録のある、オーナーページの文章内(登録タグを含む)に、検索キーワード文字があるか検索しているようです。
キーワード検索では、OR AND の検索指定は有りませんので出来ません。
「複数キーワード」の場合は「AND検索」しているようです。「複数キーワード」は「半角スペース」で区切ります。


タグ検索JSとの変更点
タグ検索JSを修正しました。主に、下記部分の変更ですから簡単に切り替えが可能です。


HTML radioボタンを削除
<input type="radio" name="radio" value="any" checked="checked"> OR <input type="radio" name="radio" value="all"> AND

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

JS tagmodeの部分を削除
var tagmode_v="any";
tagmode_v=$("input[name='radio']:checked").val();

---------------------------------------------------------
tag_mode:tagmode_vを削除
tags:tags_vをtext:tags_vに変更

$.getJSON(FlickrAPI,{

	method:"flickr.photos.search",
	api_key:"32dbd23f3f7e6d0ae494b99eebb57c93",
	per_page:100,
	extras:"owner_name",
	text:tags_v,
	format:"json"
})

以下の説明は、「前ページのタグ検索説明」とまったく同じです。


画像のロードは、javascriptのImage()メソッドで

画像のロードは、javascriptのImage()メソッドで行っていますので、基本的にpreloadjsの読み込みは不要です。追加の処理などでpreloadjsが必要な場合は其の限りでは有りません。


1. 複数画像を読み込みできるようにしました。1枚目をロードしたら次の画像をロードする仕組みです。
2. 画像ロード失敗の場合は、代替画像を挿入します。(現実には、ほとんどないでしょう)
3. Image()は<img>タグで読み込んでいる処理と同様ですから、外部ドメイン画像でも表示できる訳です。
4. 単純ですから、読み込みは結構早いです。


● エラーの場合に代替画像を入れる処理
記述、方法などは外にも色々とあると思いますが、.....



//画像マルチローダー
function multiLoader() {

	//ProgressBar描画
	progress(imageload_count/loadImage_len);

	//画像Load終了判定
	if(imageload_count < loadImage_len) {
		//読み込み
		getLoadImage();
	} else {
		//終了
		multicomplete();
	}
}
//new Image()の実行
function getLoadImage() {

	//new Loader
	var image_loader=new Image();
	image_loader.onload=function() {

		//読み込みOK
		//サムネール大きさ取得
		flickrW.push(image_loader.width);
		flickrH.push(image_loader.height);
		//サムネールobject保存
		assets.push(image_loader);
		//次画像のロード
		imageload_count ++;
		multiLoader();
	}
	image_loader.onerror=function() {

		//NGは100x66代替画像を入れて次画像のロードに進む
		assets.push(createColorCanvas(100,66,"#CCCCCC"));
		flickrW.push(100);
		flickrH.push(66);
		imageload_count ++;
		multiLoader();
	}
	//URL
	image_loader.src=manifest[imageload_count].src;
}

● エラーの場合に代替画像を入れない処理
この場合はエラーのサムネールの表示をスキップできる利点があります。
但し、他の読み込み済みデータなどと保存順番が合わなくなります。ここでは省略しますが、何らかの事後処理が必要です。


	image_loader.onerror=function() {

		//NGはカウントだけを加算する
		imageload_count ++;
		multiLoader();
	}

設定の変更点

easeljs-0.7.1用のものと比較して、次の点が違います。


ProgressBarの描画にprogressイベントを利用せず、読み込み画像数を計算して変化させています。



//ProgressBar描画
progress(imageload_count/loadImage_len);

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

//progressBar2
function progress(v) {
	//0-1
	bar_v=v;
}

シャッフルの設定

JSの先頭で設定できるようにしました。
シャッフルが turu ならば、最大100の画像データを取得して(検索の結果では取得件数は変わる)、表示指定件数分をランダムに表示します。
Canvas表示の場合、大変重いので多くのサムネールを表示出来ないために「少し変化を付ける」ためのアイデアです。Canvas表示では無くHtmlでの表示のほうが有利です。
逆にシャッフルが turu ならば、常に表示指定件数分のみの画像しかロードしないために、表示画像に変化が少ない。


//シャッフルをするか/false
var shuffle=false;

セキュリティ上の問題が多い

クロスドメインの読み込みは画像に限らず制約が多いし、CreateJS標準では徹底して表示出来ない仕組みになっている。(easeljs-0.8.0リリースから10日余りのため、まだ方法などは模索中、少々時間がかかりそうだ)
この点は納得するのだが、Flickr画像はクロスドメインに成らざるを得ない。信頼して取得する外ないと思います。


easeljs-0.7.1 でのテスト、「キーワード入力画面」付き「キーワード」検索の場合は「前ページ」記事を参照ください。

【参照】当方の記事: CreateJS FlickrAPI photos.search メソッドのキーワード検索画像表示



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

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


 

以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]