MunsellPhotoViewer

Picasaから取得した画像をいろいろ並べて回転したりしてみた。

MunsellPhotoViewer – wonderfl build flash online

[sourcecode language=”as3″]
/*
* Picasaから簡単に画像を取ってこれるようにしたかったので。
*
* Picasa Web Albums query parameters reference
* http://code.google.com/intl/ja/apis/picasaweb/docs/2.0/reference.html#Parameters
*
* */
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.utils.Dictionary;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.easing.*;
import org.libspark.betweenas3.tweens.ITween;
import flash.filters.DropShadowFilter;
import flash.geom.Vector3D;
/**
* …
* @author umhr
*/
//[SWF(width = 465, height = 465, backgroundColor = 0x000000, frameRate = 30)]
public class Munsell2 extends Sprite {
private var _axis:Sprite;
private var _canvas:Sprite;
private var _paint:Sprite;
private var _source:Source;
private var _dic:Dictionary;
private var _t:ITween;
private var _isDown:Boolean;
private var _axisProxy:Object;
private var _countDown:int;
private var _currentSelect:int;
//private var _i_array:Array;

public function Munsell2():void {
stage.scaleMode = "noScale";
stage.align = "TL";
//trace(this.loaderInfo.url);
_isDown = false;
//stage.scaleMode = "noScale";
_source = new Source();
_source.addEventListener(Event.COMPLETE, onComp);
_source.load("tokyo", 50);

var gradientShape:GradientShape = new GradientShape(stage.stageWidth, stage.stageHeight);
gradientShape.draw();
this.addChild(gradientShape);

}

private function onComp(event:Event):void {
//this.addChild(_source.sprites[0]);
_axis = new Sprite();
_axisProxy = new Object();
_canvas = new Sprite();
_paint = new Sprite();
_dic = new Dictionary();
_axisProxy["z"] = 10000;
//_i_array = [];
var n:int = _source.proxy.length;
for (var i:int = 0; i < n; i++) {
_source.proxy[i].x = Math.sin(i / n * 2 * Math.PI*6) * 100*(1+Math.abs(Math.round((n / 2-Math.abs(i – n / 2))*0.1)));
_source.proxy[i].y = Math.round((i – n / 2)*0.1) * 100;
_source.proxy[i].z = Math.cos(i / n * 2 * Math.PI*6) * 100*(1+Math.abs(Math.round((n / 2-Math.abs(i – n / 2))*0.1)));
_source.proxy[i].rotationY = (i / n) * 360*6+90;
_axis.addChild(_source.proxy[i]);
_dic[_source.sprites[i]] = i;
_canvas.addChild(_source.sprites[i]);
//_i_array.push(i);
}
_axis.x = stage.stageWidth / 2;
_axis.y = stage.stageHeight / 2;
_axis.z = _axisProxy.z;
//_axis.rotationX = 45;
this.addChild(_axis);
this.addChild(_paint);
this.addChild(_canvas);
//onUpdate();
animation();
//atDown(null, 1);
}

private function animation():void {
this.addEventListener(Event.ENTER_FRAME, atEnter);
this.addEventListener(MouseEvent.MOUSE_DOWN, atDown);
}
private function atEnter(event:Event):void {

_countDown ++;
if(_isDown){
//
if (_countDown > 300 && Math.random() < 0.01) {
var swap0a:int = Math.floor(Math.random() * _source.proxy.length);
var swap0b:int = Math.floor(Math.random() * _source.proxy.length);
if (swap0a != swap0b && swap0a != _currentSelect && swap0b != _currentSelect) {
var swap1a:int = _source.distance[swap0a].i;
var swap1b:int = _source.distance[swap0b].i;
_source.distance[swap0a].i = swap1b;
_source.distance[swap0b].i = swap1a;
atDown(null, _currentSelect);
}
}

_axis.z = _axisProxy.z;
_axis.rotationY += 0.15;
}else {
_axis.rotationY += 0.3;
if(_countDown > 100){
atDown(null, int(_source.proxy.length*Math.random()));
_countDown = -200;
}
}
onUpdate();
}
private function atDown(event:Event = null, num:int = 0):void {
if (!_isDown) {
var t:ITween;
t = BetweenAS3.tween(_axisProxy, { z:1300 }, null, 2, Sine.easeInOut);
t.play();
}
if(event){
_countDown = 0;
}
_isDown = true;
var selectNum:int = event?_source.distance[_dic[event.target]].i:num;

var tweens:Array = [];

var n:int = _source.proxy.length;
for (var j:int = 0; j < n; j++) {
var i:int = _source.distance[j].i;
var nx:Number = Math.sin(i / n * 2 * Math.PI * 6) * 350 * (1 + Math.abs(Math.round((n / 2 – Math.abs(i – n / 2)) * 0.1)));
var ny:Number = Math.round((i – n / 2) * 0.03) * 200;
var nz:Number = Math.cos(i / n * 2 * Math.PI * 6) * 350 * (1 + Math.abs(Math.round((n / 2 – Math.abs(i – n / 2)) * 0.1)));
if(i == selectNum){
tweens.push(
BetweenAS3.serial(
BetweenAS3.tween(_source.proxy[j], { y:0 }, null, 1, Back.easeIn),
BetweenAS3.tween(_source.proxy[j], { z:0 }, null, 1, Back.easeOut),
BetweenAS3.tween(_source.proxy[j], { x:0 }, null, 1, Circ.easeOut)
)
);
tweens.push(BetweenAS3.tween(_source.distance[j], { d:0,r:0 }, null, 3, Back.easeIn));

}else {
if (i%2 == 0) {
nz *= 2.5;
nx *= 2.5;
//tweens.push(BetweenAS3.tween(_source.distance[j], { d:1,r:1 }, null, 3, Back.easeIn));
}
tweens.push(
BetweenAS3.serial(
//BetweenAS3.delay(BetweenAS3.tween(_source.sprites[i], { z:0 }, null, 0.3+Math.abs(selectNum-i)*0.01, Back.easeIn),Math.abs(selectNum-i)*0.01),
BetweenAS3.tween(_source.proxy[j], { y:ny }, null, 0.5+Math.abs(selectNum-i)*0.05, Back.easeOut),
BetweenAS3.tween(_source.proxy[j], { z:nz * 2 }, null, 0.5+Math.abs(selectNum-i)*0.05, Back.easeIn),
BetweenAS3.tween(_source.proxy[j], { x:nx * 2 }, null, 0.5+Math.abs(selectNum-i)*0.05, Back.easeOut)
)
);
tweens.push(BetweenAS3.tween(_source.distance[j], { d:1,r:1 }, null, 3, Back.easeIn));
}

//tweens.push(BetweenAS3.tween(_source.sprites[i], { x:(i – n / 2-(selectNum-n/2)) * 200 }, null, 3, Back.easeInOut));
}
if (_t != null) {
_t.stop();
}
_t = BetweenAS3.parallelTweens(tweens);
//_t.onComplete = function():void { trace("hoge",selectNum)};
_t.play();
_currentSelect = selectNum;
}
private function onUpdate():void {
var n:int = _source.proxy.length;
for (var j:int = 0; j < n; j++) {
var i:int = _source.distance[j].i;
var poz:Vector3D = _source.proxy[i].transform.getRelativeMatrix3D(_canvas).position;
_source.sprites[i].x = poz.x;
_source.sprites[i].y = poz.y;
_source.sprites[i].z = poz.z;
_source.sprites[i].rotationY = ((_axis.rotationY + _source.proxy[i].rotationY + 180) % 360 – 180) * _source.distance[i].d-_source.distance[i].r*90;
}
Utils2.zSort2(_canvas);
}
}
}

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.filters.DropShadowFilter;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.geom.Matrix;
class Source {
private var _photos:PicasaPhotos;
public var sprites:Array;
public var proxy:Array;
public var distance:Array;

private var _complete:Function = function(event:Event):void { };
private var _ioError:Function = function(event:Event):void { };

public function Source() { };

public function addEventListener(type:String, listener:Function):void {
this["_" + type] = listener;
}
public function load(keyword:String = "", num:int = 3, width:int = 320, height:int = 240, quality:String = "middle"):void {
_photos = new PicasaPhotos();
_photos.addEventListener(Event.COMPLETE, onComplete);
_photos.addEventListener(IOErrorEvent.IO_ERROR, function(event:Event):void { trace("無いよ") } );
_photos.load( { q:keyword, "max-results":num, imgmax:"128", imgor:"landscape" } );
}
private function onComplete(event:Event):void {
sprites = [];
proxy = [];
distance = [];
var n:int = _photos.loader.items.length;
var m:int = n*3;
for (var i:int = 0; i < m; i++) {

var bitmapData:BitmapData = new BitmapData(320 + 12, 240 + 12, true, 0x000000);
var temp:Bitmap = _photos.loader.getBitmap(String(i % n));
//if (!temp) { continue };
var b:Number = Math.max(320 / temp.width, 240 / temp.height);

var bg:Sprite = new Sprite();
bg.graphics.beginFill(0x000000, 0.8);
bg.graphics.drawRoundRect( 0, 0, bitmapData.width, bitmapData.height, 6, 6);
bg.graphics.endFill();
bitmapData.draw(bg);
bitmapData.draw(temp, new Matrix(b, 0, 0, b, 6, 6), null, null, new Rectangle(0, 0, 326, 246), true);

var tf:TextField = new TextField();
tf.defaultTextFormat = new TextFormat("_sans", 11);
tf.text = "Photo by " + _photos.credits[i % n];
tf.textColor = 0xFFFFFF;
tf.autoSize = "left";
tf.filters = [new DropShadowFilter(0)];
bitmapData.draw(tf, new Matrix(1, 0, 0, 1, 6, 4));

var bitmap:Bitmap = new Bitmap(bitmapData, "auto", true);
bitmap.x = -bitmap.width / 2;
bitmap.y = -bitmap.height / 2;
var sp:Sprite = new Sprite();
sp.addChild(bitmap);
sprites.push(sp);
proxy.push(new Sprite());

distance.push({"d":1,"i":i,r:0});
}
_complete(event);
}

}

import flash.display.GradientType;
import flash.display.Shape;
import flash.geom.Matrix;
class GradientShape extends Shape {
private var _matrix:Matrix = new Matrix();
private var _width:int;
private var _height:int;
private var _r:Number;
private var _tx:Number;
private var _ty:Number;
public function GradientShape(width:int = 465, height:int = 465) {
_width = width;
_height = height;
var w:Number = _width * 0.5;
var h:Number = _height * 0.5;
var r:Number = Math.sqrt(w * w + h * h);
_r = r * 2;
_tx = (_width – _r) * 0.5;
_ty = (_height – _r) * 0.5;
//init();
}
public function draw(rotation:Number = 0):void {
var radian:Number = (rotation + 90) * Math.PI / 180;
_matrix.createGradientBox(_r, _r, radian, _tx, _ty);
//_matrix.createGradientBox(_width, _height, radian);

this.graphics.clear();
this.graphics.beginGradientFill(GradientType.LINEAR, [0x002244, 0x000011, 0x002244], [1, 1, 1], [0,128, 255], _matrix);
this.graphics.drawRect(0, 0, _width, _height);
this.graphics.endFill();
}

}

/**
* …
* @author umhr
*/
import flash.events.Event;
import flash.system.LoaderContext;
import flash.system.Security;
class PicasaPhotos {
public var xmlLoader:MultiLoader;
public var loader:MultiLoader;
public var credits:Array = [];
private var _complete:Function = function(event:Event):void{};
private var _ioError:Function = function(event:Event):void{};
public function PicasaPhotos() {
Security.loadPolicyFile("http://photos.googleapis.com/data/crossdomain.xml");
xmlLoader = new MultiLoader("xml");
loader = new MultiLoader("photos");
}
public function addEventListener(type:String, listener:Function):void {
this["_" + type] = listener;
}
public function load(props:Object = null):void {
var defaultProps:Object = { "max-results":3, imgmax:"320", imglic:"creative_commons", kind:"photo", "start-index":"1"};

var xmlURL:String = "http://photos.googleapis.com/data/feed/base/all?alt=rss";

var p:String;
for (p in props) {
defaultProps[p] = props[p];
}

for (p in defaultProps) {
xmlURL += "&" + p + "=" + encodeURIComponent(decodeURIComponent(defaultProps[p]));
}
xmlLoader.add(xmlURL, { id:"xml", type:"text" } );
xmlLoader.addEventListener(Event.COMPLETE, loadIMG);
xmlLoader.start();
}
private function loadIMG(event:Event):void {
var myXML:XML = xmlLoader.getXML("xml");
default xml namespace = new Namespace("http://search.yahoo.com/mrss/");
var n:int = myXML.channel.item.length();
if (n == 0) {
atIoError(null);
return;
}
for (var i:int = 0; i < n; i++) {
var url:String = myXML.channel.item[i].group.content.@url;
loader.add(url, { context:new LoaderContext(true), id:String(credits.length), type:"image" } );
credits.push(myXML.channel.item[i].group.credit);
trace(url, myXML.channel.item[i].group.credit);
}
loader.addEventListener(Event.COMPLETE, atComp);
loader.start();
}
private function atIoError(event:Event):void {
_ioError(event);
}
private function atComp(event:Event):void {
_complete(event);
}
}

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.system.Security;
import flash.utils.Dictionary;
import flash.utils.ByteArray;
import flash.utils.getQualifiedClassName;
import flash.display.MovieClip;
class MultiLoader{
public static var IMAGE_EXTENSIONS:Array = ["swf", "jpg", "jpeg", "gif", "png"];
public static var TEXT_EXTENSIONS:Array = ["txt", "js", "xml", "php", "asp"];
public static const COMPLETE:String = "complete";
private var _listener:Function = function(event:Event):void{};
private var _loads:Dictionary;
private var _keyFromId:Dictionary;
private var _loadCount:int;
private var _itemsLoaded:int;
public var items:Array;
private var _binaryLoads:Dictionary = new Dictionary();
public function MultiLoader(name:String = ""){
_loads = new Dictionary();
_keyFromId = new Dictionary();
_itemsLoaded = 0;
items = [];
}
public function add(url:String, props:Object = null):void {
var loadingItem:LoadingItem = new LoadingItem();
loadingItem.url = url;
loadingItem.type = getType(url, props);
if(props){
if(props.context){
loadingItem.context = props.context;
}
if (props.id) {
_keyFromId[props.id] = url;
}
if (props.preventCache) {
loadingItem.preventCache = props.preventCache;
}
}
items.push(loadingItem);
}
private function getType(url:String, props:Object = null):String{
var result:String = "";
if (props && props.type) {
return props.type;
}
var i:int;
var extension:String;
var n:int = IMAGE_EXTENSIONS.length;
for (i = 0; i < n; i++) {
extension = IMAGE_EXTENSIONS[i];
if(extension == url.substr(-extension.length).toLowerCase()){
result = "image";
break;
}
}
if(result == ""){
n = TEXT_EXTENSIONS.length;
for (i = 0; i < n; i++) {
extension = TEXT_EXTENSIONS[i];
if(extension == url.substr(-extension.length).toLowerCase()){
result = "text";
break;
}
}
}
return result;
}

public function start():void{
var n:int = items.length;
for (var i:int = 0; i < n; i++) {
var type:String = items[i].type;
var url:String = items[i].url;
url += (items[i].preventCache)?"?rand=" + Math.random():"";
var uRLRequest:URLRequest = new URLRequest(url);
if(type == "image"){
_loads[items[i].url] = loadImage(uRLRequest, items[i].context);
}else if(type == "text"){
_loads[items[i].url] = loadText(uRLRequest);
}else if (type == "byteImage") {
byteImage(uRLRequest, items[i].context);
}else if(type == "binary"){
_loads[items[i].url] = loadBinary(uRLRequest);
}
}
}
public function addEventListener(type:String,listener:Function):void{
_listener = listener;
}
public function getBitmap(key:String):Bitmap{
key = keyMatching(key);
var bitmap:Bitmap;
try{
if (getQualifiedClassName(_loads[key].content) == "flash.display::MovieClip") {
var mc:MovieClip = _loads[key].content;
var bitmapData:BitmapData = new BitmapData(mc.width, mc.height);
bitmapData.draw(mc);
bitmap = new Bitmap(bitmapData);
}else {
//bitmap = _loads[key].content;
var bitmap2:Bitmap = _loads[key].content;
var bitmapData2:BitmapData = new BitmapData(_loads[key].content.width, _loads[key].content.height);
bitmapData2.draw(_loads[key].content);
bitmap = new Bitmap(bitmapData2);
}
}catch (e:*) {
//type == "binary"の場合
if(_binaryLoads[key]){
bitmap = _binaryLoads[key].content;
}
//bitmap = new Bitmap();
}
return bitmap;
}
public function getBitmapData(key:String):BitmapData{
key = keyMatching(key);
var bitmap:Bitmap = getBitmap(key);
var bitmapData:BitmapData = new BitmapData(bitmap.width, bitmap.height);
bitmapData.draw(bitmap);
return bitmapData;
}
private function loadImage(url:URLRequest, context:LoaderContext = null):Loader {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComp);
//loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
loader.load(url, context);
return loader;
}

private function onIOError(e:IOErrorEvent):void
{
//onComp(null);
trace("onIOError",e.target.url);
}
private function byteImage(url:URLRequest, context:LoaderContext = null):void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadBytes);
loader.load(url, context);
function loadBytes(event:Event):void {
_loads[url.url] = new Loader();
_loads[url.url].contentLoaderInfo.addEventListener(Event.COMPLETE, onComp);
_loads[url.url].loadBytes(event.target.bytes);
}
}
public function getBinary(key:String):ByteArray {
var byteArray:ByteArray;
try {
byteArray = _loads[keyMatching(key)].contentLoaderInfo.bytes;
}catch (e:*) {
//type == "binary"の場合
byteArray = _loads[keyMatching(key)].data;
}

return byteArray;
}

public function getText(key:String):String {
key = keyMatching(key);
return key?_loads[key].data:key;
}
public function getXML(key:String):XML {
return new XML(getText(key));
}
private function keyMatching(key:String):String {
return _loads[key]?key:_keyFromId[key];
}
private function loadText(url:URLRequest):URLLoader{
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onComp);
loader.load(url);
return loader;
}
private function loadBinary(url:URLRequest):URLLoader{
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, loadBytes);
loader.dataFormat = "binary";
loader.load(url);
return loader;
function loadBytes(event:Event):void {
_binaryLoads[url.url] = new Loader();
_binaryLoads[url.url].contentLoaderInfo.addEventListener(Event.COMPLETE, onComp);
_binaryLoads[url.url].loadBytes(event.target.data);
}
}
private function onComp(event:Event):void {
_itemsLoaded ++;
if (_itemsLoaded == items.length) {
_itemsLoaded = 0;
_listener(event);
}
}
public function get itemsTotal():int{
return items.length;
}
public function get itemsLoaded():int{
return _itemsLoaded;
}
public function get loadedRatio():Number {
return _itemsLoaded / items.length;
}
}

import flash.net.URLRequest;
import flash.system.LoaderContext;
class LoadingItem{
public var url:String;
public var preventCache:Boolean;
public var type:String;
public var status:String;
public var context:LoaderContext;
public function LoadingItem(){};
}

//Dump
import flash.utils.getQualifiedClassName;

//zSort
import flash.display.DisplayObjectContainer;
import flash.geom.PerspectiveProjection;
import flash.geom.Point;
import flash.geom.Vector3D;
import flash.geom.Matrix;
class Utils2 {
public function Utils2():void { };
//shuffle
static public function shuffle(num:int):Array {
var _array:Array = new Array();
for (var i:int = 0; i < num; i++) {
_array[i] = Math.random();
}
return _array.sort(Array.RETURNINDEXEDARRAY);
}
//Dump
static public function dump(obj:Object, isTrace:Boolean = true):String {
var str:String = returnDump(obj)
if (isTrace) {
trace(str);
}
return str;
}
static public function returnDump(obj:Object):String {
var str:String = _dump(obj);
if (str.length == 0) {
str = String(obj);
}else if (getQualifiedClassName(obj) == "Array") {
str = "[\n" + str.slice( 0, -2 ) + "\n]";
}else {
str = "{\n" + str.slice( 0, -2 ) + "\n}";
}
return str;
}

static public function traceDump(obj:Object):void {
trace(returnDump(obj));
}

//zSort
static private function _dump(obj:Object, indent:int = 0):String {
var result:String = "";

var da:String = (getQualifiedClassName(obj) == "Array")?”:’"’;

var tab:String = "";
for ( var i:int = 0; i < indent; ++i ) {
tab += " ";
}

for (var key:String in obj) {
if (typeof obj[key] == "object") {
var type:String = getQualifiedClassName(obj[key]);
if (type == "Object" || type == "Array") {
result += tab + da + key + da + ":"+((type == "Array")?"[":"{");
var dump_str:String = _dump(obj[key], indent + 1);
if (dump_str.length > 0) {
result += "\n" + dump_str.slice(0, -2) + "\n";
result += tab;
}
result += (type == "Array")?"],\n":"},\n";
}else {
result += tab + ‘"’ + key + ‘":<‘ + type + ">,\n";
}
}else if (typeof obj[key] == "function") {
result += tab + ‘"’ + key + ‘":<Function>,\n’;
}else {
var dd:String = (typeof obj[key] == "string")?"’":"";
result += tab + da + key + da + ":" + dd + obj[key] +dd + ",\n";
}
}
return result;
}
static public function zSort2(target:DisplayObjectContainer):void {
if(!target.root){return};
var n:int = target.numChildren;
var array:Array = [];
var reference:Array = [];
for (var i:int = 0; i < n; i++) {
if (target.getChildAt(i).transform.matrix3D) {
var poz:Vector3D = target.getChildAt(i).transform.getRelativeMatrix3D(target.root.stage).position;
var point:Point = target.root.stage.transform.perspectiveProjection.projectionCenter;
array[i] = poz.subtract(new Vector3D(point.x, point.y, -target.root.stage.transform.perspectiveProjection.focalLength)).length;
reference[i] = target.getChildAt(i);
}
}
var temp:Array = array.sort(Array.NUMERIC | Array.RETURNINDEXEDARRAY);
for (i = 0; i < n; i++) {
if (target.getChildAt(i).transform.matrix3D) {
target.setChildIndex(reference[temp[i]],0);
if(reference[temp[i]].numChildren > 2){
zSort2(reference[temp[i]]);
}
}
}
//return;
for (i = 0; i < n; i++) {
if (target.getChildAt(i).transform.matrix3D) {
target.getChildAt(i).visible = (target.getChildAt(i).transform.getRelativeMatrix3D(target.root.stage).position.z > -400);
}
}
}
}

[/sourcecode]