04-08-10

Flashに値やパラメータを送る方法まとめ

HTMLにswfファイルを貼り付けてブラウザで見るときに、場合によってはHTMLに書いておいた値やパラメータをFlashの変数に渡してあげたいときがあると思います。Flash内を更新したいときや、ちょっとした汎用性のあるコンテンツを作るときに、Flashアプリケーションがインストールされていない環境でも、Flashの更新をしたりする時に便利です。色々ある方法の中で一番シンプルな方法、swfobjectを使って、ActionScriptにどう書けばいいのか紹介します。

swfobjectを使ってパラメータを設定する場合

swfobjectの使い方はswfobject v2.xの使い方を参考にしてみてください。
Flashコンテンツの背景色を色々変更したいという例えで紹介します。HTMLに書くswfobjectの書き方のイメージはこんな感じにします。

<script type="text/javascript" src="swfobject.js"></script>
<script type="text/javascript">
<!--
var flashvars = {bgColor: "FF0000"};//←背景色
var params = {allowscriptaccess: "always"};
swfobject.embedSWF("flash.swf", "flashContent", "100", "100", "8", "", flashvars, params,attributes);
//-->
</script>

flashvarsに変数名「bgColor」を書いて、値である16進数の「FF0000」を書いてみました。
ではActionScriptではどのように書くか

ActionScript2.0以下でflashvarsを取得する場合

ステージ全部に収まるシェイプを作って、今回の例では100×100の正方形のMovieClipを作ってステージに配置します。インスタンス名を「bg」としました。第1フレームに下記のActionScriptを書きます。

var color_obj = new Color(bg);// カラーオブジェクトを作成する
var colorStr = "0x"+_root.bgColor;//ここがswfobjectで設定した値が入ります
color_obj.setRGB(colorStr);

厳密なことはわかりませんが、flashvarsに格納した値はFlash上では_rootに宙に浮いてて、それを_root.[変数]にしてあげるとポコ!ってはいる。そんなイメージにしてますボクはw

ActionScript3.0でflashvarsを取得する場合

ActionScript3.0になってから、そんな宙に浮いていた値のイメージが、ちゃんとScriptを書いて値を取りに行くことを書かなければいけなくなりました。swfに渡そうとする変数の値は、LoaderInfoクラスで取得することができます。

import flash.display.LoaderInfo

var params:Object = loaderInfo.parameters;
var bgColorStr:String = params["bgColor"];

params[flashvars]になるので、複数の値を取得する時は名前を指定してあげれば取得することができます。

03-01-10

crossdomain.xmlをルート以外の設置からでも認識させる方法

ActionScriptでクロスドメインを認識させる方法は、

Security.loadPolicyFile("http://mysite.com/crossdomain.xml");

↑たぶん、このようにスクリプトを書きます。

Security.loadPolicyFile("http://mysite.com/sitemap/crossdomain.xml");

↑状況によってはドキュメントルート直下に「crossdomain.xml」置けないときもあると思います。

ボクは事情により後者で設定してFlashを再生させると、、

Error #2044: ハンドルされていない SecurityErrorEvent : text=Error #2048: セキュリティサンドボックス侵害
(※これはFlash Debug Playerからのアラートです)

出た!出たよ!!出てしまったよ!!!(TOT)
そこでFlashTracerでログを追跡してどんなエラーが出ているかを調べてみました。
ここでクロスドメインの構造をサクッと説明しますが、ドキュメントルート以外のクロスドメインの方法は更に下のほうに書きます。

crossdomain.xmlの設置と記述方法

Flashのクロスドメイン問題はいにしえからある問題です。そもそもクロスドメインというのは、swfファイルを貼り付けているHTMLをからみて、外部ファイルをロードするときに、そのファイルが置いてある場所は、HTMLファイルとは違うドメインという状態のことを指します。つまり、FlashPlayerは他人のドメインを攻撃してしまわないようにしているわけです。でも、世の中には写真共有サービスがあったりRSSコンテンツがあったりAPIなんかもあります。そういった場合は、どこからでも情報を取得してもいいですよ。といった感じに許可をすることができます。その許可をするための設定ファイルが、「crossdomain.xml」にあたります。

たとえば、自分のサイト「http://mysite.com」というサイトに表示させるFlashコンテンツが「http://hoge.com」というサイトにあるRSSをロードするとします。この場合、クロスしてますよね。hoge.comサイトは、mysite.comがRSSをロードしてもいいよ!と許可をする為に、「crossdomain.xml」をドキュメントルートの場所においてあげます。アドレスは

「http://hoge.com/crossdomain.xml

このようになります。実際に、この「crossdomain.xml」の中に何が書かれているか、

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="http://mysite.com"/>
</cross-domain-policy>

4行目にある記述で「http://mysite.com」と書いていると、「http://hoge.com」のRSSは「http://mysite.com」からのみロードができる。という事になります。

例えば、「http://mysite.com」を含むサブドメインにも許可をする場合は、「*.mysite.com」と書きます。

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*.mysite.com"/>
</cross-domain-policy>

全てのサイトからのアクセスを許可をする場合は、「*」だけを書きます。この設定はセキュリティに詳しい方に一回相談したほうがいいかもしれません。

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>

ココからFlashのはなし

実際にFlashで設定するSecurityメソッドは、「crossdomain.xml」がドキュメントルートに設置されてて、かつ、その内容の設定で問題なければ、わざわざクロスドメインポリシーファイルをロードする必要はありません。

Security.loadPolicyFile("http://hoge.com/crossdomain.xml");

↑このようにドキュメントルートにある「crossdomain.xml」をロードする記述はする必要がない。ということです。

んじゃ、どういったときにSecurityメソッドを使って「crossdomain.xml」をロードするのかというと、ドキュメントルートとは違う階層にある「crossdomain.xml」ファイルをロードするときに使います。例えば、ドキュメントルートであるhtdocsに、サブドメインごとにディレクトリを分けているとします。「content1」というディレクトリには外部からアクセスして欲しくないけど、「content2」というディレクトリにあるファイルは別のドメインからアクセス可能とするときに、「content2」にクロスドメインポリシーファイルを設置します。その時に、Flash側で書くスクリプトは、

Security.loadPolicyFile("http://hoge.com/content2/crossdomain.xml");

↑と書いて、ポリシーファイルをロードさせると、Flashは「content2」以下にあるコンテンツを表示させることができます。

FlashPlayer10からの仕様変更

前述のように、ドキュメントルートとは違う場所の「crossdomain.xml」を取得できてましたが、FlashPlayerのバージョン10からクロスドメインの設定ルールに少し変更が加えられ、かならずドキュメントルートの「crossdomain.xml」を最初に参照する使用に変更されました。もしドキュメントルートに「crossdomain.xml」がない場合、たとえ「http://hoge.com/content2/crossdomain.xml」ここの場所に設定ファイルを置いていても「Error #2044: ハンドルされていない SecurityErrorEvent : text=Error #2048: セキュリティサンドボックス侵害」といったエラーが出てしまいます。

エラー : http://hoge.com/content2/rss.xml のリソースに対する、http://mysite.com/content.swf の要求者からの要求は、ポリシーファイルのアクセス権がないため拒否されました。
※FlashDebugPlayerのログ例

ドキュメントルートにメタポリシーファイルを設定する

「crossdomain.xml」は、セキュリティポリシーを設定する記述のほかに、セキュリティポリシー設定ファイルを管理するメタポリシーとしても使うことができます。つまり、ポリシーファイルのポリシーファイルということですね。これをドキュメントルートに設定すれば、FlashPlayer10以上でも、ドキュメントルート以外の「crossdomain.xml」をロードすることができます。その中の記述に、site-controlタグを記述し、permitted-cross-domain-policiesをallにすると、全てのディレクトリーの「crossdomain.xml」をロードすることを許可することを意味します。

<!--ドキュメントルートに設定するメタポリシーファイル例-->
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all" />
</cross-domain-policy>
<!--ルートから「content2」ディレクトリの「crossdomain.xml」の記述例-->
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*.mysite.com"/>
<!--*.mysite.comからの通信を許可をする-->
</cross-domain-policy>

ActionScriptには下記とかく。

Security.loadPolicyFile("http://hoge.com/content2/crossdomain.xml");

クロスドメインでのエラーが出た場合の確認方法

一番単純なのは、外部画像やXMLなど、別ドメインから取得する場合、そのドメインのルートに「crossdomain.xml」があるかどうか確認してください。youtubeのクロスドメインは「http://www.youtube.com/crossdomain.xml」こうなります。ページが真っ白でしたらブラウザの「ソースを見る」で記述が確認できると思います。Flashコンテンツを制作しているなかで、もし、クロスドメイン設定ファイルがなければサーバーの管理者に問い合わせて、設置してもらうようにお願いする必要があります。詳しい「crossdomain.xml」の説明に関してはAdobeのデベロッパーセンターページに詳しく載ってます。
http://www.adobe.com/jp/devnet/articles/crossdomain_policy_file_spec.html

10-24-09

ActionScriptでスペクトラムのサンプル

spectrum
※↑リンク先はポップアップします。音量に気をつけてください。
ここにあったスペクトラムのサンプルをちょこっと改造。コピペしてmp3のパスを書き換えたらとりあえず動きました。ByteArrayクラスがバイナリデータを読み取ったり操作したりすることができるみたいです。
▼参考サイト
ByteArray

http://livedocs.adobe.com/flex/3_jp/langref/flash/utils/ByteArray.html

Flash 9 Sound Spectrum!

http://theflashblog.com/?p=181

SoundMixer.computeSpectrum() stretchFactor変化デモ

http://dev.ekndesign.com/2008/02/16/soundmixercomputespectrum-stretchfactor%E5%A4%89%E5%8C%96%E3%83%87%E3%83%A2/

▼サンプルダウンロード
spectrum.zip

▼このエラーが出たときは、mp3ファイルのパスが間違っていると思います。

Error #2044: ハンドルされていない IOErrorEvent : text=Error #2032: ストリームエラー。
	at spectrum_fla::MainTimeline/frame1()
var s:Sound = new Sound();
var sc:SoundChannel;
var ba:ByteArray = new ByteArray();
var array:Array;

s.load(new URLRequest("my.mp3"));
sc = s.play(0,1000);

this.addEventListener(Event.ENTER_FRAME, spectrum);

var a:Number = 0;
var al:Number = 0;

function spectrum(event:Event) {
	a = 0;
	al = 0;
	graphics.clear();
	SoundMixer.computeSpectrum(ba,true,0);
	for (var i=0; i < 180; i=i+10) {
		a = ba.readFloat();
		al = Number(a.toFixed(3));
		var num:Number = a*360;
		graphics.lineStyle(num/15,0x003333|(num << 8),al);
		graphics.drawCircle(stage.stageWidth/2,stage.stageHeight/2,i);
	}
}

10-20-09

ActionScriptのトゥイーン制御ライブラリTweenerの使い方

Tweener(トゥイーナー)とは

例えば、1秒かけてX座標に100pxゆるやかにだんだん加速しながら移動後に、”テスト”と出力する場合。

//ActionScript2
import caurina.transitions.Tweener;
Tweener.addTween([instance],{_x:100, time:1, transition:'easeOutQuint', onComplete:handler});
function handler(){
	trace("テスト");
}

TweenerはActionScript3.0とActionScript2.0で使用する事ができ、インスタンスに対して「だんだんゆっくり止まる」「どんどん勢いよく移動」「びょーんびょーん(?)」と、いろんなイージングが設定できるトウィーン制御ライブラリです。とても簡単なScriptで実現できます!

導入手順

▼まずはGoogle Codeに公開されているライブラリをダウンロード。
配布元:http://code.google.com/p/tweener/
ダウンロードしたzipファイルを解凍すると、「caurina」というフォルダができると思います。それをflaファイル直下、またはFlashの環境設定でクラスパスを追加します。これで準備は完了しました。

Tweenerの使い方サンプルを簡単に説明

import caurina.transitions.Tweener;

この1行は、Tweenerを使うために、ダウンロードしたTweenerライブラリをimportする記述です。ライブラリを管理している環境によって左右されますが、Flashの実行ファイルがある場所に「caurina」フォルダーを置いたら、「caurina」からの階層になります。

Tweener.addTween([instance],{

この1行の[instance]は、トゥイーンして動かしたいインスタンス名をいれます。[] ←括弧は必要ないので、例えば、「myInstance」というインスタンス名のムービークリップを動かすとした時の最初の1行は、

Tweener.addTween(myInstance,{

このようになります。

Tweenerの書き方、ActionScript3.0

import caurina.transitions.Tweener;
Tweener.addTween([instance],{
	x:100,
	y:100,
	scaleX:1,
	scaleY:1,
	rotation:0,
	alpha:1,
	time:1,
	delay:0,
	transition:'easeOutQuint',
	_blur_blurX:20,
	_blur_blurY:20,
	_blur_quality:3,
	_color:0x330066,
	onComplete:onCompleteHandler,
	_bezier:[{x:115,y:115},{x:200,y:200},{x:285,y:285}]
});

Tweenerの書き方、ActionScript2.0

import caurina.transitions.Tweener;
Tweener.addTween([instance],{
	_x:100,
	_y:100,
	_scale:1,
	rotation:0,
	_alpha:1,
	time:1,
	delay:0,
	transition:'linear',
	_color:0xffffff,
	onComplete:onCompleteHandler,
	_bezier:[{x:115,y:115},{x:200,y:200},{x:285,y:285}]
});

トゥイーンの逆再生

import caurina.transitions.Tweener;
Tweener.removeTweens([instance],{
	_x:100,
	_y:100,
	_scale:1,
	rotation:0,
	_alpha:1,
	time:1,
	delay:0,
	transition:'linear',
	_color:0xffffff,
	onComplete:onCompleteHandler,
	_bezier:[{x:115,y:115},{x:200,y:200},{x:285,y:285}]
});

Tweenerのパラメータ

パラメータは必要に応じて足したり減らすことができます。

x:100,  //移動後のX座標
y:100,  //移動後のY座標
scaleX:1,  //X座標への大きさ
scaleY:1,  //Y座標への大きさ
rotation:0,  //回転
alpha:1,  //透明度
time:1,  //何秒かけるか
delay:0,  //トゥイーン開始までの待ち時間
transition:'easeOutQuint',  //トゥイーンのトランジション
_blur_blurX:20,  //X座標へのぼかし
_blur_blurY:20,  //Y座標へのぼかし
_blur_quality:3,  //ぼかしのクオリティ
_color:0x330066,  //着色
onComplete:onCompleteHandler,  //トゥイーン後の処理
_bezier:[{x:115,y:115},{x:200,y:200},{x:285,y:285}]  //ベジェ曲線状にトゥイーンする通過点

エラーコード

## [Tweener] Error: The property 'x' doesn't seem to be a normal object property of [object Object] or a registered special property.

例えばコレの場合だと、「The property ‘x’」プロパティのXが間違ってますよ。ということですね。これが出たときは、「_x」と「x」の記述違いでした。AS2とAS3とではアンダーバーがいるいらないがありますので、コピペしたサンプルでエラーがでたら、プロパティを見てみましょう。

トゥイーンする動きのトランジションチートシート

どういう動きでトゥイーンするか、transitionに設定する名前が載っているチートシートです。「transition」のパラメータに「easeInSine」とか「easeInOutSine」をコピペしてつかってください。

10-14-09

Flashのボタンアクションでマウスカーソルを矢印にする方法

ActionScript2を相変わらず使っています。制作業界はもうActionScript3が主流なんですかね。。
ボタンの上にボタンが来るようなコンテンツを作るとき、下のボタンが反応してしまう時があります。それ以外のときでも、onRollOverハンドラで動くモノの上にマウスカーソルを持ってくると、人差し指カーソルになってしまい、矢印カーソルのままにしたい時があります。

そんな時に使うのがuseHandCursorです。マウスカーソルが人差し指になってほしくない所にMovieClipをおいて、そのMovieClipに対してuseHandCursor = false;としてあげるとマウスカーソルは矢印のままになります。ただし、そのMovieClipにonRelease、onRollOverなどのイベントハンドラを設定していることが条件です。

mc.useHandCursor = false;
mc.onRollOver = function(){
 trace("ほげほげ")
}

10-02-09

ActionScriptでXMLのキャッシュ対策

Flashコンテンツを更新する際、XMLなど外部ファイルにデータを持たせて、それを更新するようなパターンがあります。メリットとしては、Flashアプリケーションを触らなくても更新でき、CMSとの連携もとれたりして非常に便利ではありますが、ActionScriptが複雑になり、Flashコンテンツの制作時間が長くなってしまうデメリットもあります。

XMLを更新したはずなのに、Flashの中身が変更されていない。という時がありました。ほとんどの場合ブラウザがキャッシュしているXMLが残ったまま、更新されたXMLを読みに行かないというのが原因です。のです。確認するときにブラウザのキャッシュを消せばいいのですが、お客さまにわざわざキャッシュを消させるわけにはいきません。^-^;

そこで今回は、ActionScriptでXMLのキャッシュを残さない方法を紹介します。残さないというより、FlashがXMLをロードする時に常に違うファイルとしてブラウザに認識させる方法。という言い方のほうが正しいです。

var myXML:XML = new XML();
myXML.load("hoge.xml"+"?noCache="+new Date().getTime());

XMLファイルにアクセスするパスに、?引数で現在の時間を付け足しています。サーバーへのアクセスは、[hoge.xml?noCache=1254463831798]こんな感じになり、ブラウザは1秒前とは違うファイルと認識して新たにXMLを取得、キャッシュを見に行くことはなくなるということです。特にXMLファイルの中身を書き消したりすることはありませんのでご安心を。
コンテンツが更新されない!とパニックを起こされる前に事前に対策しておいたほうがいいですねー!

09-25-09

外部画像ファイルにsetMask();すると「セキュリティ Sandbox 違反」というアラート

どういうときに起きたか

外部にある、jpgやgifファイルをFlashが読み込んで表示させるコンテンツはよくあります。例えば、その時画像が、画像専用のサーバーにあって、swfファイルとは別のドメインにあるとします。普通に画像を読み込むだけでは問題ないのですが、その読み込んだ画像に対してsetMaskメソッドを使うと、下記のようなアラートが出ました。

*** セキュリティ Sandbox 違反 ***
SecurityDomain 'http://image.www.hoge.co.jp/hoge.gif' が互換性のないコンテキスト 'file:///C/hoge.swf' にアクセスを試みました。

おそらく原因は、

setMask();メソッドが、外部画像を読み込んだMovieClipに対してマスクをかけるのではなく、なにか見えない力で外部画像がマスクをとりにいっている。そういうイメージなのかもしれません。つまりクロスドメインなんでしょうね。

解決方法

ActionScriptで下記を追加すると一発で直りました。

System.security.allowDomain("*");

いやぁ~いろいろ難しいですねーw ^-^;