[Away3D]カバーフロー風味(youtube api)
Away3D GOLD対応記念
上下左右キーで移動
画面ダブルクリックで該当のyoutubeへリンク
/**
* Copyright fumix ( http://wonderfl.net/user/fumix )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/sZpD
*/
package {
import flash.events.IOErrorEvent;
import away3d.containers.ObjectContainer3D;
import away3d.containers.View3D;
import away3d.debug.AwayStats;
import away3d.entities.Mesh;
import away3d.lights.PointLight;
import away3d.materials.TextureMaterial;
import away3d.materials.lightpickers.StaticLightPicker;
import away3d.primitives.PlaneGeometry;
import away3d.textures.BitmapTexture;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.easing.Expo;
import org.libspark.betweenas3.tweens.ITween;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.ui.Keyboard;
[SWF(frameRate="60")]
public class Index extends View3D {
// ----------------------------------------
// CLASS CONSTANTS
// ----------------------------------------
private const APIURL : String = 'http://gdata.youtube.com/feeds/api/videos?start-index=1&max-results=50&orderby=viewCount&alt=json&vq=';
private const KEYWORD : String = 'AKB48';
private static const MARGIN_X : Number = 65;
// ----------------------------------------
// VARIABLES
// ----------------------------------------
private var _w : int;
private var _h : int;
private var _jsonObject : Object;
private var _jsonObjectLength:int;
private var _imageArray : Array;
private var _planeArr : Array;
private var MAX_PLANE : uint;
private var _currentPlane : Number;
private var tween : ITween;
private var _title : TextField;
private var source:BitmapData = new BitmapData(465, 465, false, 0x000000);
// METHODS
public function Index() : void {
if (stage) _initialize();
else addEventListener(Event.ADDED_TO_STAGE, _initialize);
}
/**
* _initialize
*/
private function _initialize(e : Event = null) : void {
removeEventListener(Event.ADDED_TO_STAGE, _initialize);
Wonderfl.disable_capture();
//addChild(new Bitmap(source));
// 背景設定
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
//タイトル表示
_title = new TextField();
_title.autoSize = TextFieldAutoSize.CENTER;
_title.textColor = 0xFFFFFF;
_title.y = 150;
addChild(_title);
// youtubeから検索結果のjsonをロード
var urlLoader : URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, urlLoadCompleteHandler);
urlLoader.load(new URLRequest(APIURL + KEYWORD));
}
private function urlLoadCompleteHandler(event : Event) : void {
_jsonObject = JSON.parse(event.currentTarget.data);
_jsonObjectLength = _jsonObject['feed']['entry'].length;
_imageArray = new Array();
for (var i : String in _jsonObject['feed']['entry']) {
var thumbURL : String = _jsonObject['feed']['entry'][i]['media$group']['media$thumbnail'][0]['url'];
var title : String = _jsonObject['feed']['entry'][i]['title']['$t'];
var url : String = "http://www.youtube.com/watch?v=" + String(_jsonObject['feed']['entry'][i]['id']['$t']).replace('http://gdata.youtube.com/feeds/api/videos/', '');
// 画像のロード
var pict:Picture = new Picture(thumbURL,title,url);
pict.addEventListener(Event.COMPLETE, loadCompleteHandler);
pict.addEventListener('error', IOErrorHandler);
}
}
private function IOErrorHandler(event:Event) : void {
if(_imageArray.length >= _jsonObjectLength){
//3D周り初期化
_init3D();
}
}
private function loadCompleteHandler(event : Event) : void {
_imageArray.push(Picture(event.target));
if(_imageArray.length >= _jsonObjectLength){
//3D周り初期化
_init3D();
}
}
private function _init3D() : void {
// ライト
var light:PointLight = new PointLight();
light.z = -500;
light.specular = 0;
light.fallOff = 900;// 減衰が終了する距離
light.radius = 400;// 減衰を開始する距離
scene.addChild(light);
var lightPicker:StaticLightPicker = new StaticLightPicker([ light ]);
_planeArr = new Array();
//Planの作成
for (var i : int = 0; i < _imageArray.length; i++) {
//テクスチャ設定
var bm:Bitmap = Picture(_imageArray[i]).bm;
//平面作成
var p:ObjectContainer3D = _createPlane(bm,lightPicker);
//3Dシーンに追加
scene.addChild(p);
//配列に参照を保存
_planeArr.push(p);
}
//カメラの座標
camera.z = -500;
MAX_PLANE = _imageArray.length;
//Planeの位置更新
_currentPlane = Math.floor(MAX_PLANE / 2);
_movePlane(_currentPlane);
//stats設定
addChild(new AwayStats(this));
stage.addEventListener(Event.RESIZE, resizeHandler);
stage.addEventListener(Event.ENTER_FRAME, _updateHandler);
stage.addEventListener(KeyboardEvent.KEY_DOWN, _stageKeybordHandler);
stage.addEventListener(MouseEvent.DOUBLE_CLICK, onMouseClick);
}
private function onMouseClick(event : MouseEvent) : void {
navigateToURL(new URLRequest(Picture(_imageArray[_currentPlane]).url),"_blank");
}
private function resizeHandler(event : Event) : void {
this.width = stage.stageWidth;
this.height = stage.stageHeight;
}
private function _movePlane(id:int) : void {
var tweens:Array = new Array();
for (var i : int = 0; i < MAX_PLANE; i++) {
//対象のPlane
var p:ObjectContainer3D = _planeArr[i];
//移動値の初期化
var targetX:Number = 0;
var targetZ:Number = 0;
var targetRot:Number = 0;
var item_w:int = 180;
//X座標の計算
targetX = MARGIN_X * (i - id);
//中央より左
if(i<id){
targetX -= item_w*0.8;
targetZ = item_w;
targetRot = -60;
//中央より右
}else if(i>id){
targetX += item_w*0.8;
targetZ = item_w;
targetRot = 60;
//中央
}else{
targetX += 0;
targetZ = 0;
targetRot = 0;
}
//角度のアニメーション
tweens.push(BetweenAS3.to(p, {rotationY: targetRot},0.5,Expo.easeOut));
//位置のアニメーション
tweens.push(BetweenAS3.to(p, {x:targetX,z:targetZ},0.9,Expo.easeOut));
}
// 不要なトゥイーンは停止
if(tween && tween.isPlaying)
tween.stop();
//まとめてトゥィーン開始
tween = BetweenAS3.parallelTweens(tweens);
tween.play();
}
private function _createPlane(bm : Bitmap,light:StaticLightPicker) : ObjectContainer3D {
var w:Number = bm.width;
var h:Number =bm.height;
var textureSize:int = 256;
var bmd:BitmapData = new BitmapData(textureSize, textureSize,false,0xff0000);
var sp:Sprite = new Sprite();
bm.smoothing =true;
bm.width = bm.height = textureSize;
sp.addChild(bm);
bmd.draw(sp);
var scaleWidth:Number;
var scaleHeight:Number;
if(w > h){
scaleWidth = 1.0;
scaleHeight = h/w;
}else{
scaleWidth = w/h;
scaleHeight = 1.0;
}
//テクスチャ
var texture:BitmapTexture = new BitmapTexture(bmd);
//マテリアル
var mat:TextureMaterial = new TextureMaterial(texture);
mat.lightPicker = light;
//平面
var plane:Mesh = new Mesh(new PlaneGeometry(300*scaleWidth,300*scaleHeight,1,1,false),mat);
var planes:ObjectContainer3D = new ObjectContainer3D();
planes.addChild(plane);
return planes;
}
/**
* エンターフレーム
*/
private function _updateHandler(e : Event) : void {
_interaction();
_draw();
}
/**
* インタラクションの反映
*/
private function _interaction() : void {
_movePlane(_currentPlane);
_title.text = Picture(_imageArray[_currentPlane]).title;
_title.x = stage.stageWidth / 2 - _title.textWidth / 2;
}
/**
* 描画
*/
private function _draw() : void {
render();
// renderer.queueSnapshot(source);
}
/**
* キーボード制御
*/
private function _stageKeybordHandler(event : KeyboardEvent) : void {
switch(event.keyCode){
case Keyboard.UP:
_currentPlane --;
break;
case Keyboard.LEFT:
_currentPlane --;
break;
case Keyboard.DOWN:
_currentPlane ++;
break;
case Keyboard.RIGHT:
_currentPlane ++;
break;
default:
}
if(_currentPlane >= MAX_PLANE) _currentPlane = MAX_PLANE - 1;
if(_currentPlane < 0) _currentPlane = 0;
}
}
}
import flash.events.IOErrorEvent;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLRequest;
import flash.system.LoaderContext;
class Picture extends EventDispatcher {
public var bm:Bitmap;
public var title:String;
public var url:String;
public function Picture(thumbURL:String,_title:String,_url:String) {
title = _title;
url = _url;
// 画像のロード
var loader : Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadCompleteHandler);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, IOErrorHandler);
loader.load(new URLRequest(thumbURL), new LoaderContext(true));
}
private function IOErrorHandler(event : IOErrorEvent) : void {
dispatchEvent(new Event('error'));
}
private function loadCompleteHandler(event : Event) : void {
bm = Bitmap(event.target.content);
dispatchEvent(new Event(Event.COMPLETE));
}
}