とても良い話し

とても良い話しが ALT FACEs に。バスキュール x AKQA のネットミーティングの記録

以前作成した JavaScript の透明フロートレイヤー

前に MT アップデートした時に一式データが消えてしまったけど、101LAB さんに保管されてた、感謝。忘れないうちに貼付けておきます。

JavaScript
function FloatLayer() {
    this.initialize.apply(this, arguments);
};

FloatLayer.prototype = {

    initialize:function () {},

    add:function () {
        var container = document.createElement("div");
        $(container).attr("id", "floatLayer");
        $(container).css({margin:0, padding:0, background:"none"});
        $(document.body).append(container);
        var input = document.createElement("input");
        $(input).attr("type", "button");
        $(input).attr("value", "クリックで閉じる");
        $(container).append(input);
        $(input).click(function () {
            $("#floatLayer").remove();
        });

        if($.browser.msie) {
            if(!window.XMLHttpRequest || !document.compatMode.match(/CSS/i)) {
                $(container).css({position:"absolute", background:"#000000", filter: "alpha(opacity=50)"});
                this.optimizeScroll();
                $(window).scroll(this.optimizeScroll);
                this.optimizeSize();
                $(window).resize(this.optimizeSize);
            }
        } else {
            $(container).css({width:"100%", height:"100%", position:"fixed", left:0, top:0,
                background:"#000000", opacity: 0.5
            });
        }
    },

    optimizeScroll:function () {
        var scrollLeft = (document.compatMode.match(/CSS/i)) ?
                document.documentElement.scrollLeft : document.body.scrollLeft;
        var scrollTop  = (document.compatMode.match(/CSS/i)) ?
                document.documentElement.scrollTop : document.body.scrollTop;
        $("#floatLayer").css({
            left:scrollLeft,
            top:scrollTop
        });
    },

    optimizeSize:function () {
        var windowWidth = (document.compatMode.match(/CSS/i)) ?
            document.documentElement.clientWidth : document.body.clientWidth;
        var windowHeight = (document.compatMode.match(/CSS/i)) ?
            document.documentElement.clientHeight : document.body.clientHeight;
        $("#floatLayer").width(windowWidth);
        $("#floatLayer").height(windowHeight);
    }
};

var floatLayer = new FloatLayer();
floatLayer.add();

ActionScript 3 で抽象クラス

Java でいう abstract 修飾子がないので疑似実装するしかないですが、今までは getQualifiedClassName() 使ってクラス名を取得後、文字列で判別してました。でも前回のエントリーで constructor プロパティの有用性を知ったので、こちらを使っての実装法を考えてみました。

※ 09.04.09 追記:
Proxy を継承したクラスのインスタンスの場合で constructor プロパティを呼び出した場合、Object#constructor でなく Proxy#getProperty が優先的に呼ばれるので注意が必要です。Proxy クラスを継承したクラスには constructor のゲッターで自クラスの参照を返すことでこの問題を回避出来ます。

ActionScript
// AbstractClass
package
{
    public class AbstractClass
    {
        public function AbstractClass():void
        {
            if (Object(this).constructor == AbstractClass) {
                throw new Error("このクラスは抽象クラスなので直接インスタンス化できません.");
            }
        }
    }
}

// SubClass
package
{
    public class SubClass extends AbstractClass
    {
        public function SubClass():void
        {

        }
    }
}

こんな感じにしておけば、new AbstractClass() だとエラーになりますが、new SubClass() だとインスタンス化できます。className プロパティとかを実装したいのであれば、やっぱり getQualifiedClassName() を使わないといけませんが、そうでなければこの方法で十分な気がします。

この方法を考えてる時に constructor プロパティの取得法がいまいち分からなかったんですが、seyself さんから教えていただきました。ありがとうございます。

JavaScript で型判別

ActionScript 3 なら is 演算子で一発な型判別。JavaScript では is 演算子が使えないのでそうもいかず、typeof だと null が object として扱われる(Array とか自作クラスも同じ)し、instanceof ではすべてのクラスが Object のインスタンスとして判別されるため、この二つは役不足。なにか方法がないかと模索してみた結果、constructor プロパティで判別するのが良さそうです。

以下、テストコード。

JavaScript
function Test() {};
var test = new Test();

alert(test.constructor == Object); // false
alert(test.constructor == Test); // true
alert(null.constructor); // TypeError: null has no properties
alert(undefined.constructor); // TypeError: undefined has no properties

InternetExplorer, Firefox, Safari などのブラウザですべて同じ動作なので、これが試した限りでは一番確実っぽいです。他に良い方法があればコメント欄で教えてください。

ActionScript 3 での色々な文字列の扱い方

ActionScript 内で JavaScript を操作する時には ExternalInterface を使いますが、複雑なことをする時にはどうしても以下のような感じになります。

ActionScript
ExternalInterface.call(
    "function ()" +
    "{" +
        "var temp = 'test';" +
        "temp += 'string';" +
        "alert(temp);" +
    "}"
);

これだと文字列の連結が多すぎで分かりにくくなってしまうんですが、ActionScript は CDATA セクションを文字列として扱うためこんなやり方もあります。

ActionScript
ExternalInterface.call(<![CDATA[
    function ()
    {
        var temp = "test";
        temp += "string";
        alert(temp);
    }
]]>);

AS3 での Singleton パターン実装

AS3 での Singleton パターン実装はなかなか面倒くさいやり方が多いですが、ちょっとシンプルな実装法を思いついたので紹介します。

ActionScript
package
{
    public class Singleton
    {
        private static var _instance:Singleton = new Singleton();

        public function Singleton():void
        {
            if (_instance)
            {
                throw new ArgumentError("Singleton クラスは外部からインスタンス化できません.");
            }
        }

        public static function get instance():Singleton
        {
            return _instance;
        }
    }
}

※ 08.10.23 追記:
コンストラクタ内部で _instance = this をしていましたが、コメントを受けて修正しました。

内部で最初に new してしまっておくだけなんですが、今まで思いつきませんでした。問題になりそうな点があったらコメントお願いします。

FlashDevelop on Mac (Linux) の可能性が出てきた?

ネットサーフィン(って最近聞かないですね)してたら気になる情報が。

Mono 2.0 がリリースされたことにより FlashDevelop on Mac (Linux) の可能性が出てきたっぽいです。要は FlashDevelop は .NET で作られてるので、Mac 上で .NET が動かせる Mono により移植出来るようになったと。実際に Linux 上で動いている FlashDevelop の画像もあるので期待出来そうですね。

ただ、最初のリンク内で FlashDevelop 開発者の Mika さんがコメントされているように、肝心な構文解析やエディタ部分のエンジンが .NET ではないため、そこの移植はセカンドチーム(募集中?)次第みたいです。

エディタの善し悪しで作業効率が全然違うので、FlashDevelop on Mac が出来たら FlashDevelop on VMWare Fusion なんかとっととサヨナラするぐらい個人的にはテンション上がります。最後に、りちゃさん情報ありがとうございました!

Pixel Bender で放射状ブラー(ズーム&回転)

困った beinteractive さんの発言を受けて Pixel Bender で放射状ブラーを作ってみました。パラメータいじれるようにと思って Flex Builder に初挑戦してみたんですが、これのせいで余計に時間が掛かってしまった・・・。

放射状ブラーのデモ
放射状ブラーのデモ(※ 要 Flash Player 10)

関連ファイルはスパークプロジェクトの RadialBlur に一式上げてます。簡単に説明をすると、対象のピクセル間近 9 つのポイントをサンプリング&加重移動平均法を使って平滑化し、ピクセル色として適用しています。Pixel Bender はループ処理とか関数が使えない(Flash Player 向けの場合)ので、同じような文章が並んでかなり不格好ですが・・・。Pixel Bender の更なるバージョンアップに期待。

あと、Saqoosha さんも同じ事に挑戦されてました。違うアプローチで面白い。

WordPress へ移行

WordPress へ移行しました。これからはちゃんとエントリーを・・・していけたらいいな。

[Flash Player 10 #7] シェーダ (Pixel Bender) を使った頂点計算の最適化 2

前回のエントリーでは複雑なことをしてシェーダにデータを渡そうとしていましたが、Saqoosha さんからコメント欄で教えていただいた boostworthyisryantaylor というサイトの情報(ShaderJob クラスなど)を元に、シェーダでの頂点情報の計算に成功しました。

フレームレートが 20 を切る分割数を計測(Z ソートは今回無し)

従来の通りの頂点計算 => 分割数 75、頂点数 5625
シェーダを使った頂点計算 => 分割数 80、頂点数 6400

こんな感じで、望んでいたような劇的な変化はありませんでした。自分の環境は普通の MacBook ですので GPU は搭載されていませんが、GPU がある環境では wmode を gpu とかにすれば結果は変わってくるんでしょう。試してないですが。

従来の通りの頂点計算デモはこちら
シェーダを使った頂点計算デモはこちら

※ 要 Flash Player 10
※ 左右キーで分割数、上下キーで視野角を変更できます。

boostworthyisryantaylor さんでも書かれているように、現在はバグなのか、ShaderInput に Vector.<number> を渡すとエラーになるので ByteArray で渡しています(ドキュメントでは渡せると書いてあります)。この問題が直れば幾分は良くなるでしょうが、あまり期待はできないのかも。引き続き、調査は続けていくつもりです。とりあえずは Vector.<number> が渡せるようになるのを待つつもりですが。

http://www.libspark.org/svn/as3/Astro/VertexShader_01/
に今回のコードを上げましたので必要な方はチェックアウトしてください。