[AS]カーソル位置(フォーカス)をスクリプトで制御する方法

できないのか?、と思ったらあっさりできたのでメモ。

FocusManagerクラスのsetFocusメソッドで楽勝でした。

以下、サンプルのドキュメントクラス。
赤い四角をクリックすると、2個のテキストフィールドにカーソルが行ったり来たりします。

package  {
	
	import fl.managers.FocusManager;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	
	/**
	 * ...
	 * @author 393
	 */
	public class FocusTest extends Sprite {
		
		private var count:uint;
		private var tf0:TextField;
		private var tf1:TextField;
		
		public function FocusTest() {
			
			//テキストフィールドのセット
			setText();
			//フォーカスチェンジ用ボタンのセット
			setBtn();
		}
		//ボタンの定義
		private function setBtn():void{
			var btn:Sprite = new Sprite();
			var btnG:Graphics = btn.graphics;
			btnG.beginFill(0xFF0000);
			btnG.drawRect(0, 0 , 100, 30);
			btnG.endFill();
			addChild(btn);
			btn.buttonMode = true;
			btn.y =  100;
			
			btn.addEventListener(MouseEvent.CLICK, xClick);
		}
		//クリック時の処理
		private function xClick(e:MouseEvent):void {
			var fm:FocusManager = new FocusManager(this);
			var tf:TextField;
			count++;
			if (count % 2) {
				tf = tf0;
			} else {
				tf = tf1;
			}
			fm.setFocus(tf);
		}
		//
		private function setText():void{
			tf0 = new TextField();
			tf1 = new TextField();
			tf0.type = tf1.type = TextFieldType.INPUT;
			tf0.border = tf1.border = true
			tf0.autoSize = tf1.autoSize = "left";
			tf1.y = 30;
			
			addChild(tf0);
			addChild(tf1);
			tf0.text = "test0";
			tf1.text = "test1";
		}
		
	}
	
}

※ただし、注意がひとつ。
このままドキュメントクラスに設定してパブリッシュしただけだと以下のエラーがでます。

1172: 定義 fl.managers:FocusManager が見つかりません。

何で見つからないんだよーと思ったのですが・・・
どうもflaのライブラリにユーザーインターフェースのコンポーネントが存在していない駄目っぽい。
たとえば、ラジオボタンとかチェックボックスとかがライブラリにあればOK。
(ライブラリにいれば、ステージからは削除しちゃってもOK)
コンポーネント用のクラスってことなのかいな。
そういえばVIDEOの方でもそんな感じのことが起きた気がする。

試しにwonderflにもソースコピペしてみたけど、やっぱりコンパイルできんかった。
Flexとかだとまた違う使い方なのかな>FocusManagerクラス

[EV] PUBLIC/IMAGE.METHOD #1

いろいろメモ

PUBLIC/IMAGE.METHOD
2009/5/16 14:00~20:15

◆session01:TEAM★LAB × タナカカツキ
スケッチピストン
idu+plus

スケッチピストン×タナカカツキ
→偶然の産物が面白い
→絵が下手な人でも楽しめるスケッチブック
→漫画的

プレゼン入試
→デザイン的大喜利
→面接+実技+プレゼン力をまとめて観れるという発想

漫画的な発想→くだらないことの面白さ
Why的な視点(B DASH/きのこ)

◆session02:FUGAHUM × 田島一成
田:ツールありきではなく、表現があってのツール
F:インスタント化への危機感、インスタントではない個
田:勢いとベーシックのバランス(足し算、引き算)

◆session03:I AM ROBOT AND PROUD × 真鍋大度
プログラム言語→動作ではなく、動作→プログラム言語的な発想

◆session04:辻川幸一郎 × 伊藤誠
伊:インタラクティブの自由さと演出効果とのジレンマ(反比例的)
演出家の考えるインタラクティブとは
→辻:インタラクティブの中に制限をうまく盛り込むことが大切
→伊:お化け屋敷的なコンテンツ(制限:入り口、出口、ルート。。。)

ヒッチコック「裏窓」的なサイト、HBO Voyeu
神様視点は面白い(シムシティ的)

制限には予算も含まれる。
制限の中から新しいアイデアが生まれる。

◆session05:中村勇吾× 富野由悠季
富:ツールの発達による敷居の低下(才能が無い人への学校によるだまし)
  物作りへの責任性の欠如
  スタジオワークについては、それぞれの役割をあたえる。
  (全員天才ではなりたたない)
  イーストウッドの初期作品→最近の作品の違い
中:作品のHowToは伝える必要はない。
  ツールには振り回されたくない
富:ツールの癖によるオリジナリティの欠如
  絵心の無い人はどれだけディテールを詰めても駄目なものは駄目。
  CGの使い方:アメリ◎、レッドクリフ:×
中:アニメ、映画は動きのサンプル収集(ストーリーとか興味ない)
中:新しいアウトプット
  →インテリアデザインとしての動画(非常灯など)
富:動く画としての性能
  →他人が見やすいもの
  →カット切り替えでは、通常は画面中央に目が行く
  →同じようなスピード感に疑問(ハリウッド映画とか)
  →かみて、しもての演技(原理原則)
★人の育て方
中:各個人の感性を伸ばそうとするよりも教えた方が早い
富:才能がある人は育つ、無い人は育たない
  →基礎学力は必須
  →でもいつ才能の芽がでるかはわからない(自分がそう)

富:動画製作には、物語性がないとだめ(コンセプト)

[AS]空っぽの文字列はNumberキャストで0

xmlの読み込みとかで、要素が空っぽだった場合の判定処理とかに。

var str:String;
trace(0== Number(str))//出力:true

※5/17追記
上記の例だと要素に”0″とか”0000″とかが入ってたときもtrueになっちゃいます。

var str:String = "000"
trace(0== Number(str))//出力:true

[AS]XMLを更新したのにswfに反映されない場合(キャッシュ対策)

Xmlを読み込む際には、URLにユニークな変数を追加して、かならず再読み込みをさせたほうがいいみたい。
基本のURLのままだと、変更しても再読み込みの際、キャッシュから読んで新たに読み込んでくれない。

URL(String)にユニークな変数を追加する関数

import flash.net.LocalConnection;

//基本のURL
var xml_str:String = "http://hoge.com/hoge.xml";
//基本のURLにユニークな変数を追加
xml_str = setNoCashURL(xml_str);

private function setNoCashURL(url_str):String {
	//サーバーにあがってるか同かを調べるため
	var lc:LocalConnection = new LocalConnection();
	//現在のドメイン名を取得
	var domain_str:String = lc.domain;
	//ドメイン名がlocalhostの時はローカルでのテストなので変数はつけない。
	//(変数がついてるとローカルではxmlが読みこまれないみたい)
	if (domain_str != "localhost") {
		//現在時刻を取得することでユニークな数値を取得
		var noCash:Number = new Date().getTime();
		//URLに追加できる形にして数値を文字列化
		var noCash_str:String = "?nocash="+String(noCash);
	} else {
		noCash_str = "";
	}
	
	url_str += noCash_str;
	//変数を追加した文字列を返す
	return url_str;
}

[AS][JS]Flashでブラウザ判定

もともとFlashで用意されたクラスでは、OSとかFlashのバージョンしか判定できない。

そこでえらい人が作られたライブラリ。
JSProxy.as

JSとの連携のライブラリで色々できるみたい。
とりあえずバージョン判定の使い方は以下の通り

import com.rails2u.bridge.JSProxy;
import com.rails2u.bridge.JSProxy;
var browser:String = JSProxy.proxy.navigator.$userAgent;
var tf:TextField = new TextField();
tf.text =  browser;
tf.wordWrap=  true;
tf.width = 200;
addChild(tf);

一点注意は、ブラウザ判定だからムービープレビューじゃ機能しない。
パブリッシュして初めて判定。(当たり前か)

参考サイト:trick7 quiz

[AS][JS]FLASHで「このページのトップに戻る」ボタンの設定

FLASHでブラウザのスクロールバーを最上部に戻す方法で、最初出来たと思いきや不完全だったのでメモ。

基本設定は以下の通り。
ステージサイズを500×1000くらいにしておく
インスタンス名:_mcのムービークリップをステージの下の方に配置。

まず最初のイマイチアプローチから
以下フレームアクション

//AS:フレームアクション
_mc.addEventListener(MouseEvent.CLICK , xClick);
function xClick (e):void {
	var tf = new TextField();
	addChild(tf);
	tf.text = "リロードしてないよ";    
	navigateToURL(new  URLRequest("#","_self"));
}

これだけで出来ました。
ジャンプ先を#にするとブラウザリロードせずにページの先頭にジャンプできました。
先頭にはリロードしてないよの文字が表示されます。

で、これでいいや、と思いきや・・・
winのSafari3ではブラウザリロードしてしまいテキストが表示されません。
WINのIE6,7、FF3はリロードされなかったんですがね。。。
(HTMLの解釈的にはSafariの方が正しいっぽいような気がしますが)

というわけで別のアプローチ。
jsでスクロールバーを制御する方法。

js自体のソースはこちらのブログを参考にしました。
※イージングでゆっくりページのトップに戻るような処理のjsです。

//JS:HTMLに埋め込むか、jsファイルとしてhtmlで読み込むか
function backToTop() {
    var x1 = x2 = x3 = 0;
    var y1 = y2 = y3 = 0;

    if (document.documentElement) {
        x1 = document.documentElement.scrollLeft || 0;
        y1 = document.documentElement.scrollTop || 0;
    }

    if (document.body) {
        x2 = document.body.scrollLeft || 0;
        y2 = document.body.scrollTop || 0;
    }

    x3 = window.scrollX || 0;
    y3 = window.scrollY || 0;

    var x = Math.max(x1, Math.max(x2, x3));
    var y = Math.max(y1, Math.max(y2, y3));

    window.scrollTo(Math.floor(x / 2), Math.floor(y / 2));

    if (x > 0 || y > 0) {
        window.setTimeout("backToTop()", 25);
    }
}

上記関数をhtmlに仕込んでおいて、Flash側には以下のように設定

//AS:フレームアクション
_mc.addEventListener(MouseEvent.CLICK , xClick);

// 呼びたいJSの関数名
var callJasFunction:String = "backToTop";

// JavaScriptの実行
function xClick (e):void {
	var tf = new TextField();
	addChild(tf);
	tf.text = "リロードしてないよ";
	ExternalInterface.call(callJasFunction)
}

これでOKなのですが、Htmlにjs仕込むのが面倒くさい。
できることならFLASHだけで完結できないか、と。
と思ったら、こんな書き方でもFLASH上でJSを実行できるらしい。

//AS:フレームアクション
_mc.addEventListener(MouseEvent.CLICK , xClick);

// 呼びたいJSの関数
var callJasFunction:String = "function backToTop() {var x1 = x2 = x3 = 0;var y1 = y2 = y3 = 0;if (document.documentElement) {x1 = document.documentElement.scrollLeft || 0;y1 = document.documentElement.scrollTop || 0;}if (document.body) {x2 = document.body.scrollLeft || 0;y2 = document.body.scrollTop || 0;}x3 = window.scrollX || 0;y3 = window.scrollY || 0;var x = Math.max(x1, Math.max(x2, x3));var y = Math.max(y1, Math.max(y2, y3));window.scrollTo(Math.floor(x / 2), Math.floor(y / 2));if (x > 0 || y > 0) {window.setTimeout('backToTop()', 25);}}";

// JavaScriptの実行
function xClick (e):void {
	var tf = new TextField();
	addChild(tf);
	tf.text = "リロードしてないよ";
	ExternalInterface.call(callJasFunction)
}

ようは、関数名のところに関数全部書いちゃってもOKみたい。
これなら、Html変更しなくていいから楽チンだ!
と思いきや、これだと不具合ありました・・・

jsの再帰処理的な部分が実行されず、最初の一回しか実行されてないっぽい。
↓ここの部分

//上述したJSの一部を抜粋
if (x > 0 || y > 0) {
    window.setTimeout("backToTop()", 25);
}

でも最初の一回は実行されるので、一回でトップに戻るようなjsなら問題なくページの頭だしは可能。
jsをこれだけにすれば、とりあえずイージングなしの頭だしは可能でした。

//AS:フレームアクション
_mc.addEventListener(MouseEvent.CLICK , xClick);

// 呼びたいJSの関数
var callJasFunction:String = "function backToTop() {window.scrollTo(0, 0);}";

// JavaScriptの実行
function xClick (e):void {
	var tf = new TextField();
	addChild(tf);
	tf.text = "リロードしてないよ";
	ExternalInterface.call(callJasFunction)
}

※2009/5/12追記

以下の書き方で再帰処理も可能でした。
document.insertScriptなんてものを使えばよいのだね。
JSよくわかんね。

_mc.addEventListener(MouseEvent.CLICK , xClick);

// 呼びたいJSの関数名
var callJasFunction:String = "document.insertScript = function(){ backToTop = function() {var x1 = x2 = x3 = 0;var y1 = y2 = y3 = 0;if (document.documentElement) {x1 = document.documentElement.scrollLeft || 0;y1 = document.documentElement.scrollTop || 0;}if (document.body) {x2 = document.body.scrollLeft || 0;y2 = document.body.scrollTop || 0;}x3 = window.scrollX || 0;y3 = window.scrollY || 0;var x = Math.max(x1, Math.max(x2, x3));var y = Math.max(y1, Math.max(y2, y3));window.scrollTo(Math.floor(x / 2), Math.floor(y / 2));if (x > 0 || y > 0) {window.setTimeout('backToTop()', 25);}}}"; 
var method = " backToTop";
//上記関数を読み込み(この段階では、関数backToTopは実行されないみたい)
ExternalInterface.call(callJasFunction)
// JavaScriptの実行
function xClick (e):void {
//ここで初めて実行されるみたい。
ExternalInterface.call("backToTop")
}

[AS]配列の中身をシャッフルする方法

忘れるのでメモ

function shuffleArray(myArray:Array){
	var i:Number = myArray.length;
	while(i){
		var randomNumber:Number = Math.floor(Math.random()*(i--));
		var temp:Object = myArray[i];
		myArray[i] = myArray[randomNumber];
		myArray[randomNumber] = temp;
	}
}

[AS]swfからcsvファイルをダウンロードするには

いろいろググってみても「出来ない」という結論しか見当たらなかったのだけど、どうやらAS2を対象にした結論だったのか、AS3なら簡単にできるようす。
(csvに限らず、ファイルならなんでも保存OKな感じ)

ステージに_mcというインスタンス名をつけたMCを配置して、フレームアクションに

var file:FileReference = new FileReference();

//ステージに_mcというインスタンス名をつけたMCを配置
_mc.addEventListener(MouseEvent.CLICK , xClick);

function xClick (e:MouseEvent):void {
	try{
		//ダウンロードしたいファイルのURLをURLRequestする。
		file.download(new URLRequest("http://393.bz/sam/data.csv"));
	} catch(e:Error){
		//エラー時の処理
		trace("error");
	}
}