forked from: CoverFlowもどきテスト FP10版
...
@author ...
// forked from mtok's CoverFlowもどきテスト FP10版
// forked from mtok's flash on 2009-2-3
package
{
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Point;
import flash.geom.Vector3D;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.display.BlendMode;
[SWF(width="465", height="465", backgroundColor="0x000000")]
/**
* ...
* @author ...
*/
public class Prototype002 extends Sprite
{
private var container:Sprite;
private var numSlide:int = 9;
private var selectedSlide:CoverFlowSlide;
private var slides:Array;
private var slideGap:Number = 50;
private var sortBuffer:Array;
public function Prototype002()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
private function addedToStage(e:Event):void
{
//stage setup
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.LEFT;
stage.addEventListener(Event.RESIZE, resizeHandler);
container = new Sprite();
sortBuffer = new Array();
slides = new Array();
addChild(container);
var i:int;
var sprite:Sprite;
for (i = 0; i < numSlide; i++) {
sprite = createSprite(100, 100);
sprite = CoverFlowSlide.createSlide(sprite);
sprite.addEventListener(Event.SELECT, slideSelectHandler);
container.addChild(sprite);
sprite.x = i * slideGap;
sprite.z = 0;
//container.graphics.beginFill(0x00ff00);
//container.graphics.drawCircle(sprite.x, 0, 3);
//container.graphics.endFill();
slides.push(sprite);
sortBuffer.push(new SortItem(sprite, 0));
}
container.y = (stage.stageHeight - sprite.height) * 0.5 + sprite.height * 0.125;
selectedSlide = container.getChildAt(int(numSlide * 0.5)) as CoverFlowSlide;
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
// perspective setup
resizeHandler();
}
private function resizeHandler(e:Event=null):void
{
var psp:PerspectiveProjection = new PerspectiveProjection();
psp.fieldOfView = 45;
psp.projectionCenter = new Point(stage.stageWidth*0.5, container.y + 25);
this.transform.perspectiveProjection = psp;
}
private function slideSelectHandler(e:Event):void
{
var s:CoverFlowSlide = e.target as CoverFlowSlide;
selectedSlide = s;
}
private function enterFrameHandler(e:Event):void
{
var center:Point = new Point(stage.stageWidth * .5, stage.stageHeight * .5);
centering(center);
var i:int;
var slide:CoverFlowSlide;
var tmp:Number;
var len:int = slides.length;
var offset:Number = 0;
for ( i = 0; i < len; i++) {
slide = slides[i] as CoverFlowSlide;
offset = updateLayouts(slide, center, offset);
}
sortSlides(center);
}
private function updateLayouts(slide:CoverFlowSlide, center:Point, offset:Number):Number {
var range:Number = 75;
var p:Point;
p = slide.localToGlobal(new Point(0, 0));
p = this.globalToLocal(p);
var dx:Number = center.x - p.x;
var angle:Number = 75;
if (dx > range) {
dx = range;
angle = -angle;
} else if (dx < -range) {
dx = -range;
angle = angle;
}else {
angle = (dx != 0) ? -angle * dx / range : 0;
}
var m1:Matrix3D = slide.transform.matrix3D;
var m2:Matrix3D = new Matrix3D();
m2.appendRotation(angle, Vector3D.Y_AXIS);
m2.appendTranslation(m1.position.x, m1.position.y, m1.position.z);
slide.transform.matrix3D = m2;
slide.z = -150 * (range - Math.abs(dx)) / range;
var index:int = slides.indexOf(slide);
dx = center.x - (container.x + index * slideGap);
var d:Number;
if ( dx * dx > (30*30)) {
d = 30 * dx / Math.abs(dx);
} else {
d = 30 * Math.sin(Math.PI * dx / 60); //しょうがないのでsinでごまかした。
}
slide.x = index * slideGap - d;
return slide.x;
}
private function sortSlides(center:Point):void {
var p:Point;
var len:int = sortBuffer.length;
var i:int;
var item:SortItem;
var slide:CoverFlowSlide;
var dx:Number;
for ( i = 0; i < len; i++) {
item = sortBuffer[i] as SortItem;
slide = item.data as CoverFlowSlide;
p = slide.localToGlobal(new Point(0, 0));
p = globalToLocal(p);
dx = p.x - center.x;
item.value = dx*dx;
}
sortBuffer.sortOn("value", Array.DESCENDING | Array.NUMERIC);
for (i = 0; i < len; i++) {
item = sortBuffer[i] as SortItem;
container.swapChildren(item.data, container.getChildAt(i));
}
}
private function centering(center:Point):void {
var slide:CoverFlowSlide = selectedSlide;
var index:int = slides.indexOf(slide);
var pos:Number = index * slideGap;
var delta:Number = center.x - (container.x + pos);
var absDelta:Number = Math.abs(delta);
if (absDelta < 1) {
//dispatchEvent();
return;
}
var maxSpeed:Number = 30;
var scroll:Number = 0.2 * (delta);
if (scroll > maxSpeed ) {
scroll = maxSpeed;
}
if (scroll < -maxSpeed) {
scroll = -maxSpeed;
}
container.x += scroll;
}
private function createSprite(w:Number, h:Number):Sprite {
var sp:Sprite = new Sprite();
var a:Number = 1;
sp.graphics.beginFill(0x0000cc, a);
sp.graphics.drawRect( 0, 0, w, h);
sp.graphics.endFill();
sp.graphics.beginFill(0xffffff, a);
sp.graphics.drawCircle( 50, 50, 45);
sp.graphics.endFill();
sp.graphics.beginFill(0x0000cc, a);
sp.graphics.drawCircle( 50, 50, 30);
sp.graphics.endFill();
return sp;
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.IBitmapDrawable;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.GradientType;
import flash.display.BlendMode;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.events.Event;
internal class CoverFlowSlide extends Sprite {
private var reflection:Bitmap;
private var space:Number = 0;
private var bgColor:uint;
public function CoverFlowSlide() {
reflection = new Bitmap();
addChild(reflection);
}
public static function createSlide(d:DisplayObject):CoverFlowSlide {
var slide:CoverFlowSlide = new CoverFlowSlide();
slide.addEventListener(MouseEvent.CLICK, slide.clickHandler);
slide.drawReflection(d);
return slide;
}
private function clickHandler(e:MouseEvent):void
{
trace('click');
dispatchEvent(new Event(Event.SELECT));
}
public function drawReflection(d:DisplayObject):void {
if (reflection.bitmapData) {
reflection.bitmapData.dispose();
}
reflection.bitmapData = new BitmapData(d.width, d.height, true, 0x00000000);
var mat:Matrix = new Matrix();
mat.d = -1;
mat.ty = d.height;
reflection.bitmapData.draw(d, mat);
mat.createGradientBox(d.width, d.height, -Math.PI/2);
var grad:Shape = new Shape();
grad.graphics.beginGradientFill(GradientType.LINEAR, [bgColor, bgColor], [1, 0.5], [62, 255], mat);
grad.graphics.drawRect(0, 0, d.width, d.height);
grad.graphics.endFill();
reflection.bitmapData.draw(grad, null, null, BlendMode.NORMAL);
addChild(d);
d.x = reflection.x = -d.width * 0.5;
d.y -= space * 0.5;
reflection.y = d.height + space * 0.5;
}
}
internal class SortItem {
public var value:Number;
public var data:*;
public function SortItem(data:*, value:Number):void {
this.data = data;
this.value = value;
}
}