2010年12月アーカイブ

画像が固定(更新なし)のスライドショー的なものを作っていて、外部swfにひとまとめにして、そこから画像を取り出そうと考えてみた。

画像はphoto.swfに入れて、そのライブラリのプロパティでリンケージを設定して「photo0」のようにクラス名をつけておく。それで書き出すだけ。

で、取り出しはSWFをロードするクラスに書きます。

package {
import flash.events.EventDispatcher;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.MovieClip;
import flash.net.URLRequest;
import flash.events.Event;

import flash.system.LoaderContext;
import flash.system.ApplicationDomain;

import flash.events.ProgressEvent;


public class SwfLoader extends Loader {
var flg_play:Boolean;
var func_complete:Function;

private var cont:LoaderContext;

//コンストラクタ
function SwfLoader(url:String,isPlay:Boolean,func_comp:Function = null) {
flg_play = isPlay;
func_complete = func_comp;

//各種イベント定義
this.contentLoaderInfo.addEventListener(Event.INIT,onInit_swf);
this.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaded_swf);
this.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoadProgress_swf);
//for URL
var urlReq:URLRequest = new URLRequest(url);

cont = new LoaderContext();
cont.applicationDomain = ApplicationDomain.currentDomain;
this.load( urlReq, cont);
}

//-----Event.INIT
function onInit_swf(evt:Event):void {
//ロード中は再生しないよう停止
var info:LoaderInfo = LoaderInfo(evt.target);
var mc:MovieClip = info.content as MovieClip;
mc.stop();
}

//swf:ロード継続
private function onLoadProgress_swf(e:ProgressEvent):void {
//継続イベント:送信(ProgressEvent.PROGRESSを引き継ぐ)
dispatchEvent(e);
}

//-----Event.COMPLETE
function onLoaded_swf(evt:Event):void {
try {
//指定関数の呼び出し(LoaderInfo.contentを渡す)
var info:LoaderInfo = LoaderInfo(evt.target);
var mc:MovieClip = info.content as MovieClip;

//再生の有無
if (flg_play) {
mc.play();
} else {
mc.stop();
}

if (func_complete != null) {
func_complete(mc);
}

} catch (err:TypeError) {
trace(err.message);
}
}

public function getImage():Loader {
return this;
}

public function checkClass(ClassName:String):Class {
var cl:Class;
//アプリケーションドメインに指定したクラスがあるか
if (cont.applicationDomain.hasDefinition(ClassName)) {
//取得したクラスをClass型変数に代入
cl = cont.applicationDomain.getDefinition(ClassName) as Class;
trace("外部SWFファイルから"+ClassName+"クラスをインポートしました");
} else {
trace("外部SWFファイルには"+ClassName+"クラスは存在しません");
}

return cl;
}


}
}

本体側では、こんな感じにswfをロードして・・・

import SwfLoader;

var swf_content:SwfLoader;

//画像用swf:ロード
function loadContent_img():void {
var url:String = "photo.swf";
var flg_play:Boolean = false;
swf_content = new SwfLoader(url,flg_play);
swf_content.addEventListener(ProgressEvent.PROGRESS, checkLoad_font);

this.addChildAt(swf_content,1);
}

SwfLoaderのcheckClass()という関数を使って、外部swfからBitmapDataを取得します。

//ビットマップ取得
function getBitmap_img(no:int):Bitmap {
var name_bmp:String = "photo" + String(no);
var imgClass:Class = swf_content.checkClass(name_bmp);
if (imgClass != null) {
var img:BitmapData = new imgClass(stage.stageWidth,stage.stageHeight);
var bmp:Bitmap = new Bitmap(img);
}

return bmp;
}

納品先での画像差し替えが不要で、定期的に一括更新かけるような場合は便利かも。作例はこちら


下記のサイトを参考にさせていただきました。


たまたま仕事でもらったflaファイルに"00"〜"09"までのフレームラベルがついていたので、何気なく単純にフレーム制御しようとしたらフレーム番号に移動してしまった。例えば・・・

this.gotoAndStop("07")

と書くと、フレーム番号7に移動するといった具合。

でテストしてみました。1フレーム目に・・・

this.stop();

goFrame("07")

function goFrame(st:String):void {
this.gotoAndStop(st);
}

と書き、任意(フレーム番号7以外)のフレームラベルを"07"にして、1〜100フレームのライムラインに

this.stop();

trace("---",this.currentFrame);

と書いて実行。

結果は、やはりフレーム番号に移動。どうも数字のみのフレームラベルは数値として見なされてしまう模様。"7"でも"007"でも結果は一緒でした。AS2でも確認しましたが、結果は同じです。

ちなみに"00"の場合はフレーム移動せず、エラーにもなりませんでした(AS3.0ではフレームラベルが存在しないとエラーが出る)。

普段は必ず「英字」又は「英字+数字」のフレームラベルをつけるクセがついてるので、こんなことにはならないのですが、一応メモとして残しておきます。


つい最近知りました。Tweenerでフィルタ効果が使えるんですねえ(笑)。

フィルタ用のライブラリ(caurina.transitions.properties.FilterShortcuts)をimportして初期化してやるだけ。もっと早く知ってれば、自前でちくちく書かなくてもよかったのに。よく見ればTweenerのヘルプに載ってるし...。


this.stop();

import caurina.transitions.Tweener;
import caurina.transitions.properties.FilterShortcuts;

FilterShortcuts.init();


//title_mc:ブレで登場

Tweener.addTween( title_mc, 
{_Blur_blurX:100,_Blur_blurY:0, 
_Blur_quality:2,time:0, transition:"linear"});

Tweener.addTween( title_mc, 
{_Blur_blurX:0,_Blur_blurY:0, 
_Blur_quality:2,time:1.5, transition:"easeOutCubic",onComplete:goNext});


//次のフレームへ
function goNext():void {
this.gotoAndPlay(this.currentFrame+1);
}

ちなみにカラーをいじる場合は、ColorShortcutsを同じように使います。

this.stop();

import caurina.transitions.Tweener;
import caurina.transitions.properties.ColorShortcuts;

ColorShortcuts.init();

Tweener.addTween(BG_mc,
 {_tintBrightness:0,time:2,transition:"easeOutQuad",onComplete:goNext});


下記のサイトを参考にさせていただきました。
今更だけど「全角●●文字まで」って入力制限があって、単に文字数だと全角も半角も1文字になってしまうので、関数を書いてみました。

文字をエンコードしてみて1文字なら半角、2文字以上なら全角3文字を越えたら全角・・・っていう判断です。String.length()は改行コードも1文字にカウントするので、改行コードは統一した上で除外(半角カナが3文字の場合があるので修正)。

これが最善かはわかりませんが...。みんなどうやってるんだろう?


//半角相当での文字数を調べる(改行コードは除外)
function xGetCharLength(str:String):int {
//改行コード統一
var val:String = str.replace("\r\n","\r").replace("\n","\r");

var array:Array = new Array();
var count_char:int = 0;
for (var i:int = 0; i<val.length; i++) {
//改行コードは除外
if (val.charCodeAt(i) != 13) {
                        if (escapeMultiByte(val.charAt(i)).length > 1) {
if (escapeMultiByte(val.charAt(i)).length > 3) {
count_char += 2;
} else {
count_char+=1;
}
}
}

return count_char;
}

[2010.12.16 訂正]
野中さんのご指摘を受けて、訂正しました。野中さんが書かれた文字数チェックはこちら。
ずっと前に個人的にメモってたんだけど、今日「あれ?」となったので改めてココに書いておきます。

---------------------------------------------

TextFieldのフォーマットを設定するときに、getTextFormat,setTextFormatを使う。
でもテキストがないTextFieldだとフォーマットが適用されない。その場合は、defaultTextFormatを使う。
要は・・・

・setTextFormat>テキストがある場合
・defaultTextFormat>テキストがない場合

ということらしい。

//テキストフォーマット:設定(テキストあり)
function xSetTextFormat(txt:TextField):void {
var tf:TextFormat = txt.getTextFormat();

tf.color = "0xff0000" 

//空のテキストに対しては、
//defaultTextFormatを使うこと。
txt.defaultTextFormat = tf;
}


//テキストフォーマット:設定(テキストなし)
function xSetTextFormat2(txt:TextField):void {
var tf:TextFormat = txt.getTextFormat();

tf.color = "0xff0000" 

//入力済みテキストに対しては、
//setTextFormatを使うこと。
txt.setTextFormat(tf);
}


このアーカイブについて

このページには、2010年12月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2010年10月です。

次のアーカイブは2011年1月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。