●swf と同じディレクトリに、img フォルダを設け、その中に、180*120のサムネイル11枚(ps1.jpg,ps2.jpg,,,,ps11.jpg)、および、480*360の表示写真11枚(p1.jpg,p2.jpg,,,,,p11.jpg)を格納しておく。
(枚数、サイズは任意であるが、それに応じてscroptの係数を変更する必要がある。)
●fla ファイルのプロパティタブでクラス名を記入する(ここではphotoviewer29) |
package {
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.display.Shape;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.geom.Matrix;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import flash.events.Event;
import flash.filters.GlowFilter;
import flash.events.MouseEvent;
//ステージの設定
[SWF(width=680, height=380, frameRate=12, backgroundColor=0x000000)]
//クラス
public class photoviewer29 extends Sprite {
//グローフィルターのインポート・設定(写真の枠取り)
var glow1:GlowFilter = new GlowFilter(0xffffff,0.6,5,5,8,3,true);
var glow2:GlowFilter = new GlowFilter(0xff0000,0.6,3,3,8,3,true);
var glow3:GlowFilter = new GlowFilter(0xffffff,0.8,16,16,8,1,true);
//各種変数の定義
var num = 11;//写真枚数
var speed:Number;//マウスに反応して運動する時の角速度
var diff:Number = 0;//フレームごとのspeedの増分
var rd:Number;//各パネルの表示角
var rotY:Number = 60;//rotation角度
var depth:Number;//深度
var ps_w:Number = 200;//サムネイルの幅
var ps_h:Number = 150;
var p_w:Number = 480;//写真の幅
var p_h:Number = 360;
var blackScreen:Shape;//ステージを覆う矩形
var l_mc:MovieClip;//写真ロード用ムービークリップ
var groupRadius:Number = 300;//サムネイル群表示半径
var ka = [];//深度管理用関数で使用する配列類
var kb = [];
var kc = [];
var kd = [];
var ke = [];
//コンストラクタ、サムネイルインスタンスの作成
public function photoviewer29() {
for (var i:uint=1; i<=num; i++) {
var mc = new MovieClip();
var in_mc = new MovieClip();
addChild(mc);
mc.addChild(in_mc);
mc.filters = [glow1];
in_mc.x = - ps_w / 2;
in_mc.y = - ps_h / 2;
loadPic(in_mc,"ps",i);
mc.name = "mc" + i;
mc.num = i;
mc.buttonMode = true;
mc.addEventListener(MouseEvent.ROLL_OVER, rOver);
mc.addEventListener(MouseEvent.ROLL_OUT, rOut);
mc.addEventListener(MouseEvent.CLICK, loadlargePic);
}
setSlide();
addEventListener(Event.ENTER_FRAME, flowSlide);
}
//サムネイルロールオーバー、アウト
private function rOver(event:MouseEvent):void {
event.target.filters = [glow2];
}
private function rOut(event:MouseEvent):void {
event.target.filters = [glow1];
}
//サムネイル配置の初期設定
private function setSlide():void {
for (var i:uint=1; i<=num; i++) {
var mc = MovieClip(getChildByName("mc" + i));
mc.rd = (i-1)/num*2*Math.PI + Math.PI*3/2;
mc.yPosition = - Math.sin(mc.rd);
mc.pos = i;
arrangeSlide(mc);
}
}
//サムネイルの配置、変形処理、深度調節
private function arrangeSlide(mc):void {
var a = -Math.sin(mc.rd)*(2-Math.sin(mc.rd))/3;
var b = 0;
var c = 0;
var d = (2-Math.sin(mc.rd))/3;
var mcx = stage.stageWidth / 2 + groupRadius * Math.cos(mc.rd);
var mcy = stage.stageHeight/2-groupRadius*(stage.stageHeight/2-mouseY)/stage.stageHeight/2*(Math.sin(mc.rd));
var myMatrix:Matrix = new Matrix(a,b,c,d,mcx,mcy);
mc.transform.matrix = myMatrix;
mc.rotationY = rotY * Math.cos(mc.rd + Math.PI);
mc.rotationX = rotY*(stage.stageHeight/2-mouseY)/stage.stageHeight/2;
depthControll();
setChildIndex(mc,ke[mc.pos-1]);
}
//サムネイルのマウス位置に反応した毎フレーム毎の動き
private function flowSlide(event:Event) {
for (var j:uint=1; j<=num; j++) {
var f_mc:MovieClip = MovieClip(getChildByName("mc" + j));
f_mc.rd += 0.0003*(stage.stageWidth/2 - mouseX);
f_mc.yPosition = - Math.sin(f_mc.rd);
arrangeSlide(f_mc);
if (Math.sin(f_mc.rd) > 0) {
f_mc.scaleY *= -1;
} else {
f_mc.scaleY *= 1;
}
}
}
//拡大写真のロード・表示
private function loadlargePic(event:MouseEvent):void {
var c_mc = event.currentTarget as MovieClip;
var n = c_mc.num;
l_mc = new MovieClip();
addChild(l_mc);
l_mc.buttonMode = true;
l_mc.filters = [glow3];
l_mc.x = stage.stageWidth / 2 - p_w / 2;
l_mc.y = stage.stageHeight / 2 - p_h / 2;
loadPic(l_mc,"p",n);
blackScreenDraw();
l_mc.addEventListener(MouseEvent.CLICK, removePic);
}
//拡大写真の除去
private function removePic(event:MouseEvent):void {
blackScreen.graphics.clear();
removeChild(l_mc);
}
//写真の読み込み
private function loadPic(load_mc:MovieClip,Size:String,n:Number):void {
var mcLoader:Loader = new Loader ;
load_mc.addChild(mcLoader);
//var m = n + 1;
var url:String = "img/" + Size + n + ".jpg";
var urlReq:URLRequest = new URLRequest(url);
mcLoader.load(urlReq);
}
//深度管理用関数
private function depthControll():Array {
for (var i:uint=0; i<num; i++) {
var f = i + 1;
var o_mc = MovieClip(getChildByName("mc" + f));
var currentyPosition = o_mc.yPosition;
ka[i] = [currentyPosition,i];
}
kb = ka.sortOn([0],[Array.NUMERIC]);
for (var j:uint=0; j<num; j++) {
kc[j] = [kb[j][1],j];
}
kd = kc.sortOn([0],[Array.NUMERIC]);
for (var k:uint=0; k<num; k++) {
ke[k] = kd[k][1];
}
return ke;
}
//ステージを覆う矩形の描画(半透明ブラックスクリーン)
private function blackScreenDraw():void {
blackScreen = new Shape();
var gr = blackScreen.graphics;
gr.beginFill(0x000000,0.6);
gr.drawRect(0,0,stage.stageWidth,stage.stageHeight);
gr.endFill();
addChild(blackScreen);
setChildIndex(blackScreen,1);
}
}
} |
var a = -Math.sin(mc.rd)*(2-Math.sin(mc.rd))/3;
var b = 0;
var c = 0;
var d = (2-Math.sin(mc.rd))/3;
var mcx = stage.stageWidth / 2 + groupRadius * Math.cos(mc.rd);
var mcy = stage.stageHeight/2-groupRadius*(stage.stageHeight/2-mouseY)/stage.stageHeight/2*(Math.sin(mc.rd));
var myMatrix:Matrix = new Matrix(a,b,c,d,mcx,mcy);
Matrix のパラメーター、a(横方向)、d(縦方向)は、拡大・縮小の係数で、(2-Math.sin(mc.rd))/3 は向こうに行くほど小さくなるように設定
mcx はx座標で、ステージ中央を中心に円形となるように均等角度で配置
mcy はy座標で、ステージ中心とマウスの縦方向の差に応じてサムネイルが上下するように設定
mc.rotationY = rotY * Math.cos(mc.rd + Math.PI);
サムネイルが両脇に行くにしたがって大きく縦軸に関して回転するように設定
mc.rotationX = rotY*(stage.stageHeight/2-mouseY)/stage.stageHeight/2;
サムネイルが上下に振れた距離に応じて傾くように設定
if (Math.sin(f_mc.rd) > 0) {
f_mc.scaleY *= -1;
} else {
f_mc.scaleY *= 1;
}
奥の半円に配置されたサムネイルが rotationX の効果で上下反転するので、それを元に戻す |