一枚の横長の絵をいくつかにスライス分割し(ここでは偶数に分割)、分割絵の交互に異なった符号の角度で rotationY を適用すると、屏風絵のような形状となる。 これを利用したスライドショーの作成である。 絵の切り替えには、表示されている屏風絵が折れて閉じ、次の絵が開いて現れるようにした。
なお、絵の分割には、絵の部分を BitmapData.copyPixels を使って、部分のBitmapを作り、これをムービークリップにaddChildする方法を取った。 なお、分割数は、4,6,8をランダムに発生させたが、4枚目の絵は、4枚の絵を張り合わせているので、常に4分割にした。
ここでは単純なスライドショーにしているが、もちろん、送りボタンのクリックで切り替えるタイプなどにも応用可能である。 |
package {
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.filters.GlowFilter;
import flash.utils.Timer;
import flash.events.TimerEvent;
//ステージの設定
[SWF(width=400, height=200, frameRate=24, backgroundColor=0x000000)]
//クラス
public class slideshow_byobu extends Sprite {
var img:Array = new Array("hakone.jpg","byodoin.jpg","daisen.jpg","mitaki.jpg");
var devideNum:Number;//屏風絵分割数
var xc:Number = stage.stageWidth / 2;
var yc:Number = stage.stageHeight / 2;
var pc:Number;//中央のパーツ絵番号(真ん中の右)
var imageW:Number;//絵全体の幅
var imageH:Number;//絵全体の高さ
var bmd:BitmapData;//絵のビットマップデータ
var closedAngle:Number = 90;//閉まった時の回転角
var openedAngle:Number = 40;//開いた時の回転角
var interval:Number = 3000;//表示間隔(秒)
var glow:GlowFilter = new GlowFilter(0x996600,1.0,2,2,8,3,true);
var container:MovieClip;//パーツ絵をすべて収納するMC
var n:Number = 0;//屏風絵番号
var loader:Loader;
//コンストラクタ
public function slideshow_byobu():viod {
loadImg("img/"+img[n]);
}
//外部画像の読み込み
private function loadImg(url):void {
loader = new Loader();
loader.load(new URLRequest(url));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,generateBmp,false, 0, true);
}
//ビットマップデータに変換
function generateBmp(event:Event):void {
imageW = loader.width;
imageH = loader.height;
bmd = new BitmapData(imageW,imageH);
bmd.draw(loader);
createByobu();
}
//屏風絵の作成(分割)
private function createByobu():void {
container = new MovieClip();
addChild(container);
if (n == 3) {
devideNum = 4;
} else {
devideNum = Math.floor(Math.random() * 3 + 2) * 2;
}
pc = Math.floor(devideNum / 2);
for (var i:uint=0; i<devideNum; i++) {
var part_mc = new MovieClip();
container.addChild(part_mc);
part_mc.y = yc - imageH / 2;
var part_bmd = new BitmapData(imageW / devideNum,imageH);
part_bmd.copyPixels(bmd,new Rectangle(imageW/devideNum*i,0,imageW/devideNum,imageH),new Point(0,0));
var part_bmp = new Bitmap(part_bmd);
part_bmp.x = - imageW / devideNum / 2;
part_mc.addChild(part_bmp);
part_mc.filters = [glow];
part_mc.No = i;
part_mc.x = xc;
part_mc.targetx = xc +imageW / devideNum/2*(1- (1-Math.cos(Math.PI*openedAngle/180))) +(imageW/devideNum-imageW/devideNum*(1-Math.cos(Math.PI*openedAngle/180)))*(i-pc);
if (i % 2) {
part_mc.cAngle = closedAngle;
part_mc.oAngle = openedAngle;
} else {
part_mc.cAngle = - closedAngle;
part_mc.oAngle = - openedAngle;
}
part_mc.rotY = part_mc.cAngle;
part_mc.rotationY = part_mc.rotY;
part_mc.addEventListener(Event.ENTER_FRAME, opening);
}
bmd.dispose();
loader = null;
}
//屏風絵を開く
private function opening(event:Event):void {
var mc:MovieClip = event.target as MovieClip;
mc.x += (mc.targetx - mc.x)/8;
mc.rotY += (mc.oAngle - mc.rotY)/8;
mc.rotationY = mc.rotY;
if (Math.abs(mc.oAngle - mc.rotY) < 0.5) {
mc.rotY = mc.oAngle;
mc.rotationY = mc.rotY;
mc.removeEventListener(Event.ENTER_FRAME, opening);
stay(mc);
}
}
//屏風絵の静止表示
private function stay(mc):void {
mc.mcTimer = new Timer(interval);
mc.mcTimer.addEventListener(TimerEvent.TIMER, stayInterval);
mc.mcTimer.start();
function stayInterval(event:TimerEvent):void {
mc.mcTimer.stop();
mc.removeEventListener(TimerEvent.TIMER, stayInterval);
closing(mc);
}
}
//屏風絵を閉じ、次の画像表示へ
private function closing(mc):void {
mc.addEventListener(Event.ENTER_FRAME, closeByobu);
function closeByobu(event:Event) {
mc.x += (xc - mc.x)/7;
mc.rotY += (mc.cAngle - mc.rotY)/7;
mc.rotationY = mc.rotY;
if (Math.abs(mc.cAngle - mc.rotY) < 0.2) {
mc.rotY = mc.cAngle;
mc.rotationY = mc.rotY;
mc.removeEventListener(Event.ENTER_FRAME, closeByobu);
if (mc.No > devideNum - 2) {
removeChild(container);
container = null;
if (n++ > img.length - 2) {
n = 0;
}
loadImg("img/"+img[n]);
}
}
}
}
}
} |
part_bmd.copyPixels(bmd,new Rectangle(imageW/devideNum*i,0,imageW/devideNum,imageH),new Point(0,0));
全体画像のビットマップデータを分割図(四角形)の大きさ切り分け、 i 番目のpart_bmd(ビットマップデータ)にコピーする。
var part_bmp = new Bitmap(part_bmd);
part_mc.addChild(part_bmp);
切り分けたbmdを分割ビットマップとしてムービークリップにaddChildする。
part_mc.targetx = xc +imageW / devideNum/2*(1- (1-Math.cos(Math.PI*openedAngle/180))) +(imageW/devideNum-imageW/devideNum*(1-Math.cos(Math.PI*openedAngle/180)))*(i-pc);
屏風が開いた時に各部分図が行くべきx座標値で、rotationYで回転がかかった時に横幅が縮むのを補正している。
|