Now loading...

5 月 14

Papervision3D2.0(Great White)の割と最近のドキュメントがアップされてる(2008/04/22)。2.0は現段階でアルファ版でオフィシャルなドキュメンが出るのは当分先っぽかったのでたすかった。早速Fluidで専用ブラウザー化してドックに追加しといた。Fluid大活躍!Great White API

[関連リンク]
public var むらけん:Flasher; ASDoc GrateWhite(PaperVision3D2.0)

Tags: ,

5 月 09

別ドメインの画像を読み込む場合のLoaderクラスについていくつかメモ、クロスドメインポリシーファイル(crossdomain.xml)の読み込み方法と画像ロード速度について。結果的には画像20枚2M程度だと気にするほどでもなかった。Loaderクラスの詳細はAS で別ドメインの画像を読み込むときの注意点 - てっく煮ブログが参考になる。まずLoaderクラスの重要な性質を列挙。

  • crossdomain.xmlの設定に無関係に画像のロードは可能。(その後の画像の扱いにかかわらず必ずload()を行う)
  • 画像を画像として扱う(ただ画像を表示する)場合にはcrossdomain.xmlによる許可は必要ない。つまりどこの画像であろうと表示は可能。
  • 画像をデータとして扱う(サイズを変更するetc.)場合にはcrossdomain.xmlの許可が必要。
  • デフォルトでcrossdomain.xmlを読まない。(URLLoaderクラスは読む)

Loaderクラスを用いて別ドメインの画像をデータとして扱う方法は以下の二種類。どちらもロード完了後、(crossdomain.xmlで許可されている場合)画像データにアクセスが可能になる。

  1. Security.loadPolicyFile()関数でcrossdomain.xmlを読み込ませ、swfファイルに許可があることを知らせてからロードを始める。(実際にはcrossdomain.xmlを読み込むまでロードは自動待機)
  2. //Ex., media.tumblr.com
    Security.loadPolicyFile("http://media.tumblr.com/crossdomain.xml");
    var loader:Loader = new Loader();
    var req:URLRequest = new URLRequest("http://media.tumblr.com/xxx.jpg");
    loader.load(req);
    
  3. LoaderContextクラスのcheckPolicyFileプロパティを用いて、ロードごとにcrossdomain.xmlを読むよう指示する。
  4. var context:LoaderContext = new LoaderContext(true);
    var loader:Loader = new Loader();
    var req:URLRequest = new URLRequest("http://media.tumblr.com/xxx.jpg");
    loader.load(req, context);
    

上記二種の違いは、ロード前にcrossdomain.xmlを読み込ませるか、ロードごとにcrossdomain.xmlを読み込ませるかの違いでなので、画像のロード数が増えると両者の実行速度に差がでてくるのではないかと予想される(Security.loadPolicyFile()を使った方が早そう)。実際に調べてみた。以下はFirefoxのキャッシュを消去してからmedia.tumblr.comの画像20枚(1.7M)を読み込ませた結果をFirebugで表示したもの。左列に読み込んだファイル名一覧、右側にそれぞれ表示完了までにかかった時間が表示されている。

  1. Security.loadPolicyFile()関数を用いた場合 (11.75s)
  2. Security.loadPolicyFile()関数を用いた場合

  3. LoaderContextクラスを用いた場合 (13.21s)
  4. LoaderContextクラスを用いた場合

Security.loadPolicyFile()関数で一回だけcrossdomain.xmlを読み込んだ場合の方が完了が早くなっているが、実験のインターネット環境がよくないのであまり信用しないでください。場合によってはLoaderContextクラスでロードごとにcrossdomain.xmlを読み込ませる場合の方が早かったりもしたのでなんともいえない。結論としては両者に大差なし。というかLoaderContextクラスを用いた場合でも二回目以降同じcrossdomain.xmlの読み込みはキャッシュ化されてるから差がでてないのかもしれない。面白いのは上記二つの方法でcrossdomain.xmlをロードするタイミングが異なること。Security.loadPolicyFile()関数を用いた場合全画像をロード後、LoaderContextクラスを用いた場合画像ロード前にcrossdomain.xmlが読み込まれていて、イメージと逆なので不思議。日本の安定している快適なインターネット環境で誰か実験するのを期待しつつ、以下実験のソースコード。

package {
    import flash.display.Sprite;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    import flash.system.Security;

    public class LoadTest extends Sprite {
        public function LoadTest() {

            // 20 sexy images from media.tumblr.com
            var URLs:Array = [
            "http://media.tumblr.com/rJ6tpU7iW6y88so6TV84T1IG_500.jpg",
            "http://media.tumblr.com/z5Ki84RwK7e6bfe7zaGZCGUR_500.jpg",
            "http://media.tumblr.com/F2GLxhk3c6×444v1vma5BvIX_500.jpg",
            "http://media.tumblr.com/1gOzmif8i8oz2hz9GJ68aqBc_500.jpg",
            "http://media.tumblr.com/ky9cwXAKO8pyvjydMxesdNtr_500.jpg",
            "http://media.tumblr.com/7MmWU7n9s8l2gik4NKAlJjev_500.jpg",
            "http://media.tumblr.com/kcq2O9G2O8nggwncmiXj5Q8Z_500.jpg",
            "http://media.tumblr.com/5Vq1ESVSU8mn4n9raQLSFR6q_500.jpg",
            "http://media.tumblr.com/5Vq1ESVSU8mmwc4gekPbI9tl_500.jpg",
            "http://media.tumblr.com/0hxKQCklp2vdfmjiczTJn7v4_500.jpg",
            "http://media.tumblr.com/5Vq1ESVSU8mmtx38rZpmce95_500.jpg",
            "http://media.tumblr.com/0hxKQCklp2vdeqr003dmPyAo_500.jpg",
            "http://media.tumblr.com/0hxKQCklp4amrjwdD250Zy02_500.jpg",
            "http://media.tumblr.com/0hxKQCklp5kgx39bYjGWw6tB_500.jpg",
            "http://media.tumblr.com/0hxKQCklp6hoyaquSCmhzDXR_500.jpg",
            "http://media.tumblr.com/0hxKQCklp5xcqrjwzCIQggYR_500.jpg",
            "http://media.tumblr.com/0hxKQCklp6iz6is1QQJOQpi2_500.jpg",
            "http://media.tumblr.com/0hxKQCklp7swil3bMb5BHmae_500.jpg",
            "http://media.tumblr.com/FXGYbGlnr2pn7ftwSjgoCUtC_500.jpg",
            "http://media.tumblr.com/rJ6tpU7iW7smq0v5T9rpyo7w_500.jpg"];

            //loadModule1(URLs);
            loadModule2(URLs);

        }

        private function loadModule1(imgAry:Array):void{
            //Include crossdomain.xml from media.tumblr.com, once.
            Security.loadPolicyFile("http://media.tumblr.com/crossdomain.xml");

            var loaderAry:Array = new Array();

            for (var i:int=0; i<imgAry.length; i++){
                var loader:Loader = new Loader();
                var req:URLRequest = new URLRequest(imgAry[i]);
                loader.load(req);
                loader.contentLoaderInfo.addEventListener(Event.INIT,init);
                loaderAry.push(loader);
            }
        }

        private function loadModule2(imgAry:Array):void{
            var loaderAry:Array = new Array();

            for (var i:int=0; i<imgAry.length; i++){
                var loader:Loader = new Loader();
                var req:URLRequest = new URLRequest(imgAry[i]);

                //Include crossdomain.xml per image (i.e., 20 times)
                var context:LoaderContext = new LoaderContext(true);
                loader.load(req,context);
                loader.contentLoaderInfo.addEventListener(Event.INIT,init);
                loaderAry.push(loader);
            }
        }

        private function init(e:Event):void{
            addChild(e.target.content);
        }
    }
}

Tags: ,

5 月 02

ブログパーツでFLASHを別ドメインで表示させる時、読み込み外部ファイルがある場合はそのファイルのロケーションをURLで指定しないといけない(相対パス不可)。URLでの指定はディレクトリの変更があった場合に柔軟に対処できないので極力避けたい。じゃあSWFに埋め込んでしまおうと思い、XMLファイルの埋め込み方法で悩んだ。FlexのEmbedメタタグはデフォルトでXML形式のデータを理解しないので、形式を気にせずとりあえず読み込ませてその後XMLに強制変換してやる必要がある。

埋め込みに使用する MIME タイプは application/octet-stream として指定する必要があります。これにより、バイトデータは、解釈されずにそのまま埋め込まれます。

mx.core.ByteArrayAsset (Flex 3)- adobe

ソース内部で型を変換できるタイプのデータだったらなんでもいけるっぽい。XMLデータ埋め込みの例は以下の通り。

package {
    public class myClass{

        [Embed(source="mydata.xml", mimeType="application/octet-stream")]
        private var myData:Class;

        public function myClass(){
            var myXML:XML = new XML(new myData());
        }
    }
}

Tags: , ,

4 月 29

Keith PetersのBIT-101 Blogで配布されている画像等を魚眼レンズのように歪ませるカスタムクラスが手軽で面白い。例えばこの画像が

Hay Bails - Full Panoramic
Hay Bails - Full Panoramic on Flickr - Photo Sharing!

こうなる。

Hay Bails - Polar Distorted

歪ませるターゲットはDisplayObjectを継承していれば何でもOKなので、例えばテキストなんかにも適用できる。変形のターゲットを決めて(下の例の場合 var img:Bitmap)、render関数を用いて書き出し用BitmapData(下の例の場合 var bmpd:BitmapData)にレンダリングするだけ。面白いのはrender関数の第四引数の選び方。trueで画像の上側を円中心(例の写真の場合、空側を円中心)、falseで円外側に書き出す。ここの選び方で出来上がったイメージの雰囲気がガラっとかわる。

package {
    import flash.display.Sprite;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import com.bit101.PolarDistort;

    public class PolarDistortDemo extends Sprite{

        [Embed(source="img/panoramic.jpg")]
        private var IMG:Class;

        public function PolarDistortDemo(){
            var img:Bitmap = new IMG();
            var pd:PolarDistort = new PolarDistort(img);
            var bmpd:BitmapData = new BitmapData(400,400,true,0x00FFFFFF);
            pd.render(bmpd,0,0,true);
            addChild(new Bitmap(bmpd));
        }
    }
}

Tags:

4 月 26

理想的にはクラス内のプロパティは全てprivateにして、クラス外部からプロパティに直接アクセスさせず、かわりにgetter/setterメソッドと呼ばれる関数を用いてプロパティの参照や変更を行うことがOOPで推奨されてるらしい。直接アクセスされて不都合がある理由はよくわからんが、こういった慣例には従っておいた方がよいだろう。

オブジェクト指向プログラミングを実践する際には、クラスのプロパティに直接アクセスすることは推奨されません。クラスではよく、特定のプロパティの読取り用のアクセスに”get”メソッド、書込み用のアクセスに”set”メソッドを定義するということが行われます。

FN0311009 - 黙示的なget/setメソッド - Flash : テクニカルノート

ところでこのsetter/getterメソッドで使う関数名、なんと操作したいプロパティ名と同じ関数名をつけれない。これじゃ使い物にならんがな、と思ってたけどKeith Petersがプロパティ名の頭にアンダースコア(”_”)をつける方法で解決してた。例えばmessageというプロパティにsetter/getterメソッドを用いる場合、こんな感じ。

package{
    public class SomeClass{

        private var _message:String;

        public function SomeClass(){
            //Some codes here.
        }

        public function set message(s:String):void{
            _message = s;
        }

        public function get message():String{
            return _message;
        }
    }
}

これで、クラス外部でこのプロパティ値を変更したい場合はsetter関数経由で

var sc:SomeClass = new SomeClass();

//same as sc.message("Shut the fuck up!!");
sc.message = "Shut the fuck up!!";

クラス外部でこのプロパティ値を参照したい場合はgetter関数経由で

//same as trace(sc.message());
trace(sc.message);

なるほど、getter/setterメソッドを用いる場合のプロパティにはアンダースコアを付けるように決めてしまえば、以下のようにソースを見て混乱することもないし、しかもAS2をやってる人には馴染み深いしね。いいチップだ。

getter メソッドと setter メソッドは便利ですが、多用しすぎるとコードの保守が困難になる場合もあるので注意が必要です。

adobe - getter メソッドと setter メソッドについて

Tags: ,


Now loading...