AS3で背景イメージ等のオブジェクトを全画面表示する「screenFit」クラス

screenFit

screenFit

ActionScript3.0で背景イメージ等のオブジェクトを全画面に表示する「screenFit」クラスを作成しました。

サンプルではオブジェクトのオリジナル縦横比を無視して全画面にフィットさせていますが、デフォルトではオブジェクトのオリジナル縦横比を保持します。

下記のボタンより、ソースのダウンロード及びサンプルの閲覧ができます。

Sample Download

【使用例】

scope(DisplayObjectContainer)を、オリジナルの縦横比を保持して全画面表示


var $screenFit:screenFit = new screenFit(
stage,
scope
);

scope(DisplayObjectContainer)を、オリジナルの縦横比を無視して 1:1.6のアスペクト比で全画面表示(フルスクリーン時には無条件で全画面にフィットさせる)


var $screenFit:screenFit = new screenFit(
stage,
scope,
false,
1.6,
stage.displayState == StageDisplayState.FULL_SCREEN
);

【パラメータ説明】

stage


stageへの参照を渡す
[Stage][省略不可]

$scope


全画面表示する対象オブジェクト
[DisplayObject][省略不可]

aspectReferenceSource


オリジナルの縦横比を保持する
[規定値:true][省略可]

aspect


アスペクト比の指定
[規定値:1.6][省略可]

absolutelyFit


アスペクト比を無視して全画面にフィットさせる
[規定値:false][省略可]

ソースコード

import jp.atziluth.gui.screenFit;


package jp.atziluth.gui{
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.display.Stage;
import flash.geom.Point;
public class screenFit extends Sprite {
private var _stage:Stage;
private var sw:uint;
private var sh:uint;
private var $scope:DisplayObjectContainer;
private var aspectReferenceSource:Boolean;
private var aspect:Number;
private var absolutelyFit:Boolean;
public function screenFit(
stage:Stage,
$scope:DisplayObjectContainer,
aspectReferenceSource:Boolean=true,
aspect:Number=1.6,
absolutelyFit:Boolean=false
):void {
if ($scope == null) {
throw new ArgumentError(
"screenFit クラスのターゲットが存在しません。"
);
return;
}
this._stage = stage;
this.$scope = $scope;
this.aspectReferenceSource =
aspectReferenceSource;
this.aspect = aspect;
this.absolutelyFit = absolutelyFit;
init();
}
private function init():void {
sw = _stage.stageWidth;
sh = _stage.stageHeight;
if (absolutelyFit) {
$scope.width = sw;
$scope.height = sh;
} else {
if (aspectReferenceSource) {
aspect = $scope.width / $scope.height;
}
$scope.width = sw;
$scope.height = sw / aspect;
if ($scope.height < sh) {
$scope.height = sh;
$scope.width = sh * aspect;
}
centering($scope);
}
/*
trace("$scope.x: "+$scope.x+" | "+
"$scope.y: "+$scope.y+" | "+
"$scope.width: "+$scope.width+" | "+
"$scope.height: "+$scope.height+" | "+
"aspectReferenceSource: "+
aspectReferenceSource+" | "+
"aspect: "+aspect+" | "+
"absolutelyFit: "+absolutelyFit
);
*/

}
private function centering(
$scope:DisplayObjectContainer
):void {
if ($scope.width >= sw) {
$scope.x = (sw-$scope.width)/2;
}
if ($scope.height >= sh) {
$scope.y = (sh-$scope.height)/2;
}
}
}
}

サンプルソースコード】

Sample.as


package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.StageDisplayState;
import flash.system.Capabilities;
import jp.atziluth.gui.screenFit;
public class Sample extends MovieClip {
private var scope:_Sample=new _Sample();
public function Sample():void {
super();
this.addEventListener(
Event.ADDED_TO_STAGE, init
);
}
private function init(e:Event):void {
this.removeEventListener(
Event.ADDED_TO_STAGE, init
);
this.addChildAt(scope,0);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(
Event.RESIZE, initResize
);
layout();
}
private function initResize(e:Event=null):void {
layout();
}
private function layout():void {
var $screenFit:screenFit = new screenFit(
stage,
scope,
false,
aspect(),
stage.displayState ==
StageDisplayState.FULL_SCREEN
);
}
private var sw:uint = stage.stageWidth;
private var sh:uint = stage.stageHeight;
private var userResolutionX:uint =
Capabilities.screenResolutionX;
private var userResolutionY:uint =
Capabilities.screenResolutionY;
private function aspect():Number {
var $aspect:Number;
if (stage.displayState ==
StageDisplayState.FULL_SCREEN) {
userResolutionX =
Capabilities.screenResolutionX;
userResolutionY =
Capabilities.screenResolutionY;
$aspect =
getSourceAspect(
userResolutionX,
userResolutionY
);
} else {
sw = stage.stageWidth;
sh = stage.stageHeight;
$aspect = getSourceAspect(sw,sh);
}
return $aspect;
}
private function getSourceAspect(
screenResolutionX:Number,
screenResolutionY:Number
):Number {
return Number(
screenResolutionX/screenResolutionY
);
}
}
}

【懸念事項】

ステージの幅を取得するため、引数に stageへの参照を渡さなくてはならないのが不便に感じています。

あらかじめドキュメントクラス等から public Objectにステージの幅と高さを代入しておけば省略可能になると思うのですが、単体のクラスファイルではそうもいきません。

他の stageを参照するクラスファイルに関しても同様の処理が必要になっているので、この辺りもっと良い方法はないかと頭を抱えています。

また、今回のクラスファイルに関しては Singleton/staticで充分に実現可能なような気もしています。

もし良い方法をご存知の方がおりましたら、こちらのコメント欄か info[at]atziluth.jp宛のメールでご教示いただければ嬉しいです。

Download