<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>FICC LABS</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/" />
    <link rel="self" type="application/atom+xml" href="http://www.ficc.jp/labs/feeds/atom.xml" />
    <id>tag:www.ficc.jp,2008-03-28:/labs//5</id>
    <updated>2009-04-16T11:49:30Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.1</generator>

<entry>
    <title>CakePHP のデバッグ出力を FirePHP で表示する。</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/tkc/cakephp_firephp/" />
    <id>tag:ogino.ficc.jp,2009://2.231</id>

    <published>2009-04-16T11:47:30Z</published>
    <updated>2009-04-16T11:49:30Z</updated>

    <summary>たけしです。 CakePHP で開発をしている時は、core.php のデバッグ...</summary>
    <author>
        <name>tkc</name>
        
    </author>
    
    <category term="cakephp" label="CakePHP" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>たけしです。</p>

<p>CakePHP で開発をしている時は、core.php のデバッグレベルを２とか３とかにして開発をしているのですが、これがhtmlの最後の方にブリッと大量に吐かれて案外邪魔です。 <br />
そこで FirePHP (FireBugのPHP版のようなもの)を導入して、consoleタブ色々なデバッグ情報を出力してみます。ちなみにPHP5限定です。</p>
]]>
        <![CDATA[<p>[ 用意するもの ]
・Firefox の２か３
・<a href="http://getfirebug.com/" target="_blank">FireBug</a>
・<a href="http://www.firephp.org/" target="_blank">FIrePHP</a>
・<a href="http://www.firephp.org/HQ/Install.htm" target="_blank">FirePHPコアライブラリ</a></p>

<p>[ インストール手順 ]
1. FirePHP.class.php を /app/vendors に配置します
2. /cake/libs/model/datasources/dbo<em>source.php を 任意のAPPディレクトリ/model/datasources/dbo</em>source.php にコピーします
3. dbo_source.php 内の showLog()　を下記の関数に置き換えます</p>

<pre name="code" class="php">
    function showLog($sorted = false) {
        if ($sorted) {
            $log = sortByKey($this->_queriesLog, 'took', 'desc', SORT_NUMERIC);
        } else {
            $log = $this->_queriesLog;
        }

        if ($this->_queriesCnt > 1) {
            $text = 'queries';
        } else {
            $text = 'query';
        }

        if (php_sapi_name() != 'cli') {
            $summery = "{$this->_queriesCnt} {$text} took {$this->_queriesTime} ms";
            $header = array("Nr", "Query", "Error", "Affected", "Num. rows", "Took (ms)");
            $body = array($header);
            foreach ($log as $k => $i) {
                $row = array(($k + 1), $i['query'], $i['error'], $i['affected'], $i['numRows'], $i['took']);
                $body[] = $row;
                }
            fb(array($summery, $body), FirePHP::TABLE);
            } else {
            foreach ($log as $k => $i) {
                print (($k + 1) . ". {$i['query']} {$i['error']}\n");
            }
        }
    }
</pre>

<ol>
<li>任意のAPPディレクトリ/config/bootstrap.php に下記のソースを追記します</li>
</ol>

<pre name="code" class="php">
ob_start();
App:: import ( 'Vendor', 'FirePHP', array ( 'file' => 'FirePHPCore'.DS.'FirePHP.class.php'));
function fb() 
{
    $instance = FirePHP::getInstance(true);
    $args = func_get_args();
    return call_user_func_array(array($instance,'fb'),$args);
    return true;
}
</pre>

<ol>
<li>好きなところで fb($this->data); 等とすると FirePHP の console に表示されるはずです。</li>
</ol>

<p>一応上記の方法はハックになりますので、自己責任でお願いします。</p>
]]>
    </content>
</entry>

<entry>
    <title>MT 4.25 でアクションストリームの表示をカスタマイズ</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/tkc/mt_425/" />
    <id>tag:ogino.ficc.jp,2009://2.230</id>

    <published>2009-04-16T10:41:50Z</published>
    <updated>2009-04-16T11:50:16Z</updated>

    <summary>入社一年目にして、初エントリーのたけしです。こんにちは。  久しぶりにMTをいじ...</summary>
    <author>
        <name>tkc</name>
        
    </author>
    
        <category term="Movable Type" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>入社一年目にして、初エントリーのたけしです。こんにちは。 <br />
久しぶりにMTをいじってみたらバージョンが4.25になっていて、「アクションストリーム」という機能が追加されていたので少し触ってみました。 <br />
アクションストリーム詳細は<a href="http://www.movabletype.jp/documentation/actionstreams/" target="_blank">こちら</a>  </p>
]]>
        <![CDATA[<p>要するに、MTのサイドバー等に Twitter や Last.fm 等の情報を簡単に引っ張ってこれる機能ですね。
試しにMTのテンプレートに下記のコードを追加して、僕の Twitter のタイムラインを引っ張ってくると。</p>

<pre name="code" class="js">
<dl>
  <mt:ActionStreams service="twitter">
  <li><$MTStreamAction$></li>
  </mt:ActionStreams>
</dl>
</pre>

<p>・takesiは"デコエルモ http://twitpic.com/3ajzv"をtweetしました
・takesiは"久しぶりに横断歩道を手を上げて渡る子供を見て和んだ... けど信号は赤だった"をtweetしました
・takesiは"とりあえずmixiアプリを試してみたけど､あとは商用利用のハードルか"をtweetしました</p>

<p>おぉ、表示された... けど... 前後に何かくっついてくるのが嫌!!複数人の発言を表示するならわかるけど、自分のブログで自分の発言を表示するには前後の「takesiは"..."をtweetしました」は不要だと思ったのでカスタマイズしてみます。まずは下記のファイルを開きます。</p>

<p>MTインストールディレクトリ/plugins/ActionStreams/streams.yaml</p>

<p>Twitter の発言の場合は 841行目あたりの</p>

<pre name="code" class="js">
html_form: '[_1] <a href="[_2]">tweeted</a>, "[_3]"'
</pre>

<p>↓</p>

<pre name="code" class="js">
html_form: '[_3]'
</pre>

<p>と変更して、MTを再構築すれば完了... と思ったらもう一つ。
例えば誰かに下記のようにリプライをした場合</p>

<p>＠akirafukuoka ねーねー</p>

<p>この場合「akirafukuoka」に自動的にリンクが挿入されるのですが、targetが無指定なんですね。なので、target='_blank'させるために下記のファイルを修正します。</p>

<p>MTインストールディレクトリ/plugins/ActionStreams/lib/ActionStreams/Event/Twitter.pm　の２１行目を</p>

<pre name="code" class="js">
return qq{<a href="$url">$name</a>};
</pre>

<p>↓</p>

<pre name="code" class="js">
return qq{<a href="$url" target='_blank'>$name</a>};
</pre>

<p>これで再構築をすれば別タブ等で開くはずです。</p>
]]>
    </content>
</entry>

<entry>
    <title>JSFLとJSF</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/ando/jsfl_jsf/" />
    <id>tag:www.ficc.jp,2008:/labs//5.146</id>

    <published>2008-06-23T02:57:08Z</published>
    <updated>2008-06-24T09:54:18Z</updated>

    <summary>FICC安藤です。タケシがJSFLとJSFのPDFを見つけてきたので試してみまし...</summary>
    <author>
        <name>Ando</name>
        <uri>http://www.haricot.to/</uri>
    </author>
    
        <category term="Flash" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>FICC安藤です。</p><p>タケシがJSFLとJSFのPDFを見つけてきたので試してみました。</p><p>[Flash]<a href="http://livedocs.adobe.com/flash/9.0_jp/main/flash_cs3_extending.pdf" target="_blank">?</a><a href="http://livedocs.adobe.com/flash/9.0_jp/main/flash_cs3_extending.pdf" target="_blank">http://livedocs.adobe.com/flash/9.0_jp/main/flash_cs3_extending.pdf</a></p><p>[Fireworks]?<a href="http://help.adobe.com/en_US/Fireworks/9.0_Extending/fireworks_cs3_extending.pdf" target="_blank">http://help.adobe.com/en_US/Fireworks/9.0_Extending/fireworks_cs3_extending.pdf</a></p><p><br /></p>

<p>JSFLとは「Flashオーサリング環境をjavascriptで拡張し、定型的な作業を自動化する強力なマクロのような物が作れる」だそうで少しでもjavascriptを書いた事があればすぐに作れます、書いた事がなくてもAS触ってれば同じECMAScriptですから、大丈夫。</p>

<p>[<a href="http://ficc.jp/users/ando/study/jsfl/FixSize.jsfl" target="_blank">FixSize.jsfl</a>]<br />
Flash CS3以降、ステージに読み込んだ画像が変なサイズになり「変形の解除」でも元に戻らなくなるときがあります。<br />
それを本来のサイズに戻すJSFLです。<br />
この間Twitterで書いた時のは画像がライブラリの中でフォルダに入ってると正しく動作しなかったようです、落とされた方はお手数ですがもう一度ダウンロードしてください。</p>

<p>[<a href="http://ficc.jp/users/ando/study/jsf/Export.jsf" target="_blank">Export.jsf</a>]<br />
ちなみに鈴木に教えてもらったんですが上記の問題はそもそもFireworksで解像度をちゃんと72で書き出していないからだそうでFireworks用の選択項目を新規ファイルにコピー＆ペーストして解像度を72に変更し、フィットするJSFです。</p>

<p>[<a href="http://ficc.jp/users/ando/study/jsfl/SetInstanceName.jsfl" target="_blank">SetInstanceName.jsfl</a>]<br />
あと個人的に必要だった選択したインスタンスに<span class="Apple-style-span" style="text-decoration: line-through;">クラス</span>シンボル名の頭を小文字に変えて名前を付けてレイヤー分けするJSFLです。</p><p>(追記：クラス名ではなくシンボル名からでした）</p><p><br /></p><p><br /></p>

<p></p>

<p>JSFL（Flash）のインストール場所<br />
windows<br />
c:\Documents and Setting\ユーザー\Local Setting\Application Data\Adobe\Flash CS3\ja\Configuration\Commands\<br />
mac<br />
/Users/ユーザー/Library/Application Support/Adobe/Flash CS3/ja/Configuration/Commands/</p>

<p><br /></p><p>JSF（Fireworks）のインストール場所<br />
windows<br />
c:\Documents and Setting\ユーザー\Application Data\Adobe\Fireworks CS3\Commands\<br />
mac<br />
/Application/Adobe Fireworks CS3/Configuration/Commands/</p>]]>
        
    </content>
</entry>

<entry>
    <title>重要なお知らせ</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/shota/080331_important_notice/" />
    <id>tag:118.82.71.170,2008:/labs//5.54</id>

    <published>2008-03-31T11:27:23Z</published>
    <updated>2008-04-01T08:26:14Z</updated>

    <summary>ラボブログのリーダーの方への重要なお知らせです。サーバーの移行に伴い、フィード登...</summary>
    <author>
        <name>Shota</name>
        <uri>http://www.ausp.net/</uri>
    </author>
    
        <category term="Information" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>ラボブログのリーダーの方への重要なお知らせです。サーバーの移行に伴い、<strong>フィード登録先や各エントリーページのURLに変更</strong>が発生しました。お手数ですが、RSSリーダーに登録されている方は、登録のし直しをお願いします。また、個別エントリーページをブックマークされている方もご注意ください。</p>

<p>以下、主な変更点です。</p>

<ul>
<li><strong>RSSのURL変更</strong><br />
旧：http://www.ficc.jp/labs/feeds/top.xml<br />
新：<a href="http://www.ficc.jp/labs/feeds/rss.xml" target="_blank">http://www.ficc.jp/labs/feeds/rss.xml</a></li>
<li><strong>ATOMのURL変更</strong><br />
旧：http://www.ficc.jp/labs/feeds/top_atom.xml<br />
新：<a href="http://www.ficc.jp/labs/feeds/atom.xml" target="_blank">http://www.ficc.jp/labs/feeds/atom.xml</a></li>
<li><strong>カテゴリーアーカイブページのURL変更</strong></li>
<li><strong>ユーザー別アーカイブのURL変更</strong></li>
</ul>

<p>＊環境によっては、まだ旧サーバーに飛ぶ場合もあります。</p>

<p>サーバー移行に伴い、Movable TypeをVersion 4.1にアップグレードしてブログを再構築しました。諸事情の理由で、デフォルトのテンプレートをほぼそのまま使用した形でのリニューアルになってしまいましたが、近いうちにリニューアルを行う予定です。CSSがかなりお見苦しいことになっております。</p>

<p>また、コードを見易くするために、実験的に<a href="http://code.google.com/p/syntaxhighlighter/" target="_blank">syntaxhighlighter</a>を導入しました。ActionScript関係のネタが多いこのブログ、そのコードのためにも導入したのですが、実はオリジナルのsyntaxhighlighterには、ActionScriptには対応しておらず、取り敢えずJSの色分けで対応しています。（AS拡張用のJSもあるのですが、表示が重くなってしまい今回の導入は見送りました。）</p>

<p>今後ともFICCラボブログを宜しくお願い致します。</p>]]>
        
    </content>
</entry>

<entry>
    <title>滑らかな3次ベジェでゆらゆら曲線を描く</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/akira/3d_beizer/" />
    <id>tag:118.82.71.170,2008:/labs//5.51</id>

    <published>2008-03-18T08:04:34Z</published>
    <updated>2008-04-07T04:07:03Z</updated>

    <summary>FICC 福岡です。 珍しくやる気になりましてAS3関連のエントリー。個人的にゆ...</summary>
    <author>
        <name>Akira</name>
        <uri>http://www.akirafukuoka.com/</uri>
    </author>
    
        <category term="ActionScript 3" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Flash" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>FICC 福岡です。</p>

<p>珍しくやる気になりましてAS3関連のエントリー。個人的にゆらゆらした円が描きたくなり、</p>

<p><img alt="こんなのが作りたい" src="/labs/archives/akira/3d_beizer/img/img0.jpg" width="201" height="180" /></p>

<p>こんな図を描き出す方法を考えてみました。Flashで滑らかな曲線、といえばgraphics.curveTo()ですが、このcurveToは2次ベジェ曲線しか書く事ができません。ベジェ曲線の詳しい話は省略しますが、できればIllustratorのようにハンドリングが楽な3次ベジェが使いたい。今回はアンカーポイントとコントロールポイントの位置から3次ベジェを計算し、2次ベジェに変換してFlashで描画します。幸いFlashCS3のfl.motion.BezierSegmentクラスが面倒な計算を助けてくれますのでこのクラスを有効活用します。</p>]]>
        <![CDATA[<p><img alt="図解3次ベジェ" src="/labs/archives/akira/3d_beizer/img/img1.jpg" width="460" height="112" /></p>

<p>BezierSegmentを使うには、まず3次ベジェの要素である4つのポイント（上図でのp0,p1,p2,p3）を用います。</p>

<pre name="code" class="js">var bezierSegment:BezierSegment = new BezierSegment(p0,p1,p2,p3);</pre>

<p>例えば上図中の赤い点の座標を知りたい場合、赤い点は線分のおよそ中間地点(t=0.5)にいますので赤い点の座標(Point)は</p>

<pre name="code" class="js">var point:Point = bezierSegment.getValue(0.5);</pre>

<p>で求める事ができます。これを踏まえて完成したのがこんなswfです。</p>

<div id="3d_bezier"></div>
<script type="text/javascript" src="/labs/common/js/swfobject.js"></script>
<script type="text/javascript">
// <![CDATA[
var so = new SWFObject('/labs/archives/akira/3d_beizer/swf/circle.swf', 'CaseStudy', '560', '460', '9', '#FFFFFF');
so.useExpressInstall('/labs/common/swf/expressinstall.swf');
so.addParam('menu', 'false');
so.addParam('scale', 'noscale');
so.write('3d_bezier');
// ]]&gt;
</script>

<p>クリックすると曲線の形が変わります。また、交互にコントロールバーがまっすぐな場合と折れている場合で切り替わります。滑らかなベジェ曲線を描く場合はアンカーポイントと2つのコントロールポイントが一直線に並んでいなければいけません。今回書いたコードではアンカーポイントと1つのコントロールポイントの座標をランダムで決定し、そこからもう1つのコントロールポイントの座標を決定しています。</p>

<pre name="code" class="js">package {
import flash.display.Sprite;
import flash.display.Graphics;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.geom.Point;
import fl.motion.BezierSegment;
	
public class YurayuraCircle extends Sprite {
private var container:Sprite = new Sprite();
private var pointArray:Array = new Array(); //ポイントを格納するArray
private var anchorNum:int = 5; //アンカーポイントの数
private var totalPointNum:int = anchorNum*3; //アンカーポイントとコントロールポイントの総数
private var smoothing:Boolean = true;
private var outlineColor:Number = 0x4F80FF;
	
public function yurayuraCircle() {
stage.addChild(container);
container.x = 250;
container.y = 250;
createPointArray()
drawLine();
var txt:TextField = new TextField();
txt.text = &quot;クリックで再描画&quot;;
stage.addChild(txt);
stage.addEventListener(MouseEvent.CLICK,onClick); // クリックで再描画
}
private function createPointArray():void{
var array:Array = pointArray;
var prevNum1:int;
var prevNum2:int;
//
array[totalPointNum-1] = createPoint(totalPointNum-1)
for (var i:int=0; i &lt; totalPointNum-1; i++) {
if(i%3 == 1 &amp;&amp; smoothing){
prevNum1 = i-1;
prevNum2 = i-2;
if(prevNum2&lt;0){
prevNum2 = totalPointNum-1;
}
//アンカーポイントとコントロールポイントからもう一つのコントロールポイントの座標を割り出す
//（ただしこの場合アンカーポイントは2つのコントロールポイントの中点とする）
array[i] = new Point(2*array[prevNum1].x-array[prevNum2].x,2*array[prevNum1].y-array[prevNum2].y);
}else{
array[i] = createPoint(i)
}
}
}
private function createPoint(num:int):Point{
var r:Number = 150;
var rad:Number = num*(2*Math.PI)/totalPointNum;
var ran:Number = Math.random();
var point:Point = new Point(Math.sin(rad)*r*(0.5+0.8*ran) , Math.cos(rad)*r*(0.5+0.8*ran));
return point;
}
private function drawLine():void {
var array:Array =pointArray;
var point1:Number;
var point2:Number;
var anchor1:Number;
var anchor2:Number;
container.graphics.clear();
for (var i:int=0; i
point1 = i;
if (i%3 == 0) {
point2 = i+3;
anchor1 = i+1;
anchor2 = i+2;
if (point2 &gt;= totalPointNum) {
point2 = 0;
}
drawBezier(array[point1],array[anchor1],array[anchor2],array[point2])
//アンカーポイントの四角ぽち＆コントロールバー描画
container.graphics.lineStyle(1, outlineColor,1);
container.graphics.drawRect(array[point1].x-2,array[point1].y-2,4,4);
container.graphics.endFill();
container.graphics.lineStyle(1, outlineColor,1);
container.graphics.beginFill(0x000000,0);
container.graphics.moveTo(array[point1].x, array[point1].y);
container.graphics.lineTo(array[anchor1].x, array[anchor1].y);
container.graphics.moveTo(array[anchor2].x, array[anchor2].y);
container.graphics.lineTo(array[point2].x, array[point2].y);
container.graphics.endFill();
}else{
//コントロールポイントの丸ぽち描画
container.graphics.lineStyle(0, 0x000000,0);
container.graphics.beginFill(outlineColor,1);
container.graphics.drawCircle(array[point1].x,array[point1].y,2);
container.graphics.endFill();
}
}
}
public function drawBezier(p0:Point,p1:Point,p2:Point,p3:Point):void{
var ancorPoint1:Point
var ancorPoint2:Point
var ancorPoint3:Point
var controllPoint:Point;
var t:Number;
	
var separate:Number = 4; // ベジェの分割数
var sep:Number = 1.0 / separate;
container.graphics.moveTo(p0.x, p0.y);
container.graphics.lineStyle(1, 0x000000,1);
// BezierSegmentを用意
var bezierSegment:BezierSegment = new BezierSegment(p0,p1,p2,p3);
for(t = sep * 2; t &lt;= 1.0; t += sep * 2){
ancorPoint1 = bezierSegment.getValue(t-sep*2);
ancorPoint2 = bezierSegment.getValue(t-sep);
ancorPoint3 = bezierSegment.getValue(t);
//ancorPoint2を通るようにcontrollPointを設定
controllPoint = new Point(2 * ancorPoint2.x - (ancorPoint1.x + ancorPoint3.x) * 0.5, 2 * ancorPoint2.y - (ancorPoint1.y + ancorPoint3.y) * 0.5);
//ancorPoint1からancorPoint3への2次ベジェを描画
container.graphics.curveTo(controllPoint.x, controllPoint.y, ancorPoint3.x, ancorPoint3.y);
}
}
private function onClick(event:MouseEvent):void{
if(smoothing){
smoothing = false;
outlineColor = 0xFF4F4F;
}else{
smoothing = true;
outlineColor = 0x4F80FF
}
createPointArray()
drawLine();
}
}
}</pre>

<p>なお今回のエントリーを書くにあたって<br />
<a href="http://d.hatena.ne.jp/nitoyon/20070921/bezier_4" target="_blank">ベジエ曲線の仕組み (4) - ActionScript 3.0 でベジエ曲線を描く - てっく煮ブログ</a><br />
を参考にさせていただきました。ありがとうございました。</p>]]>
    </content>
</entry>

<entry>
    <title>AS3 Macでのマウススクロールイベント</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/ando/as3_mac/" />
    <id>tag:118.82.71.170,2008:/labs//5.49</id>

    <published>2008-02-13T06:12:51Z</published>
    <updated>2008-04-07T04:07:30Z</updated>

    <summary>FICC安藤です。 連続で Box2DFlashAS3 関連のエントリーでしたが...</summary>
    <author>
        <name>Ando</name>
        <uri>http://www.haricot.to/</uri>
    </author>
    
        <category term="ActionScript 3" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>FICC安藤です。</p>

<p>連続で <a href="http://box2dflash.sourceforge.net/"  target="_blank">Box2DFlashAS3</a> 関連のエントリーでしたが今回は実用的なエントリー、対応するところに開発者の良心のようなものが見える「AS3 Macでのマウススクロールイベント」です。</p>

<p>AS2のMacMouseWheelと同じく<a href="http://blog.pixelbreaker.com/"  target="_blank">pixelbreaker</a>の方が<a href="http://blog.pixelbreaker.com/flash/as30-mousewheel-on-mac-os-x/"  target="_blank">AS3バージョン</a>を公開されています。</p>]]>
        <![CDATA[<p>AS2バージョンよりシンプルになってまずはimport。<br />
<pre name="code" class="js">import com.pixelbreaker.ui.osx.MacMouseWheel;</pre></p>

<p>前回はなかったsetup。</p>

<pre name="code" class="js"><code>MacMouseWheel.setup(stage);</pre>

<p>後はイベントを取得するだけ。</p>

<pre name="code" class="js">stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);</pre>

<p>これだけで後は全く意識せずにMac&Win両方対応できます、かなり便利です。<br />
SafariとFirefoxでスクロール量（特に大きく動かしたとき）の違いはまだ残っていますがかなり差は小さくなった気がします。</p>

<p>たまにやってしまいますがMacではFlashのプレビューで動かそうとしても動かないのでhtmlから確認してください。</p>

<p>追記：<br />
del.icio.us コメントで気づきましたがFirefoxだと完全にFlash Playerがスクロールを持っていってます。<br />
逆にWin IE6 / 7だと完全にブラウザに持ってかれます。<br />
全画面で使う分には良さそうですが、ブログパーツに使ったりするのは危ないかもしれません。<br />
なので、サンプルは全画面で開くように変えました。</p>

<p><a href="http://ficc.jp/users/ando/study/mmw2/"  target="_blank">サンプルを開く</a></p>

<pre name="code" class="js">package {
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import com.pixelbreaker.ui.osx.MacMouseWheel;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	
	public class Main extends Sprite{
		private var txtFld:TextField;
//============================================================================================//
//		Constructor
//============================================================================================//
		public function Main(){
			init();
		}
//--------------------------------------------------------------------------------------------------------------------------------//
//		init
//--------------------------------------------------------------------------------------------------------------------------------//
		private function init():void{
			MacMouseWheel.setup(stage);
			txtFld = new TextField();
			txtFld.selectable = false;
			txtFld.autoSize = TextFieldAutoSize.LEFT;
			txtFld.text = 'MacMouseWheel';
			txtFld.textColor = 0xFFFFFF;
			txtFld.x = Math.round(stage.stageWidth / 2 - txtFld.width / 2);
			txtFld.y = Math.round(stage.stageHeight / 2 - txtFld.height / 2);
			addChild(txtFld);
			stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);
			stage.addEventListener(Event.RESIZE, resizeHandler);
		}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//		enterFrameHandler
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		private function enterFrameHandler(_evt:Event):void{
		}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//		mouseWheelHandler
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		private function mouseWheelHandler(_evt:MouseEvent):void{
			txtFld.y -= _evt.delta;
			if(txtFld.y &gt; stage.stageHeight + txtFld.height){
				txtFld.y = 0 - txtFld.height;
			}else if(txtFld.y &lt; 0 - txtFld.height){
				txtFld.y = stage.stageHeight - txtFld.height;
			}
		}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//		resizeHandler
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		private function resizeHandler(_evt:Event):void{
			txtFld.x = Math.round(stage.stageWidth / 2 - txtFld.width / 2);
		}
	}
}</pre>]]>
    </content>
</entry>

<entry>
    <title>Box2DFlashAS3での衝突判定</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/ando/box2dflashas3/" />
    <id>tag:118.82.71.170,2008:/labs//5.48</id>

    <published>2008-01-29T06:55:02Z</published>
    <updated>2008-04-07T04:07:56Z</updated>

    <summary> 昨日に引き継ぎBox2DFlashAS3、楽しすぎます。 FICC安藤です。 ...</summary>
    <author>
        <name>Ando</name>
        <uri>http://www.haricot.to/</uri>
    </author>
    
        <category term="ActionScript 3" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p><a href="http://ficc.jp/users/ando/study/box2d/shotthestar/" target="_blank"><img alt="Box2D LetterFIC" src="/labs/archives/ando/box2dflashas3/img/shotthestar.jpg" width="460" height="300" /></a></p>

<p><a href="/labs/archives/ando/box2dflashas3_f_i_c/" target="_blank">昨日</a>に引き継ぎ<a href="http://box2dflash.sourceforge.net/" target="_blank">Box2DFlashAS3</a>、楽しすぎます。<br />
FICC安藤です。</p>

<p>今回は、もしゲームを作るとなると必要になると思われる「当たり判定」です。<br />
上のサンプルでは３つのルールがあって</p>

<p>1	敵役は星形<br />
2	マウスクリックで左側から玉が飛んでくる<br />
3	玉が敵に当たるとエフェクトを残して玉だけ消す。</p>]]>
        <![CDATA[<p>今まではMovieClip.hitTest() で毎フレームごとにぶつかってるのがいないか走査してたと思います。<br />
Box2Dではworld内の物は特別なにもしなくてもお互いがぶつかれば反発しあって跳ね返ります。<br />
まぁそういうエンジンですからと言えばそれまでですが、逆にただレンダリングしてるだけだと「いつ何が何とぶつかったか？」がわかりません。</p>

<p>ぶつかった時のイベント等ないかソースを見てみましたがそれっぽいものは見当たらず、<br />
Box2D/Dynamics/Contacts/b2ContactNode が怪しかったのでそれを使います。</p>

<p>このb2ContactNodeでわかるのは「何と何がぶつかったか」のリストで、これはb2Body内のm_contactListに収まっています。</p>

<p>実際のコードで見てみます。</p>

<p>TestBed/Testでのサンプルでは描画ループはこんな感じになってます。</p>

<pre name="code" class="js">for&nbsp;(var&nbsp;bb:b2Body&nbsp;=&nbsp;m_world.m_bodyList;&nbsp;bb;&nbsp;bb&nbsp;=&nbsp;bb.m_next){
	for&nbsp;(var&nbsp;s:b2Shape&nbsp;=&nbsp;bb.GetShapeList();&nbsp;s&nbsp;!=&nbsp;null;&nbsp;s&nbsp;=&nbsp;s.GetNext()){
		drawShape(s);
	}
}</pre>

<p><br />
ここにb2ContactNodeを取得するコードを追加</p>

<pre name="code" class="js">for&nbsp;(var&nbsp;bb:b2Body&nbsp;=&nbsp;m_world.m_bodyList;&nbsp;bb;&nbsp;bb&nbsp;=&nbsp;bb.m_next){
	//	ここから
	//	追記：もしかしたら↑のループの外でb2Contactを使っても可能なのかも（未確認）
	for&nbsp;(var&nbsp;cn:b2ContactNode&nbsp;=&nbsp;bb.m_contactList;&nbsp;cn&nbsp;!=&nbsp;null;&nbsp;cn&nbsp;=&nbsp;cn.next){
		trace(cn.contact.GetShape1().m_body);
		trace(cn.contact.GetShape2().m_body);
	}
	//	ここまで
	for&nbsp;(var&nbsp;s:b2Shape&nbsp;=&nbsp;bb.GetShapeList();&nbsp;s&nbsp;!=&nbsp;null;&nbsp;s&nbsp;=&nbsp;s.GetNext()){
		drawShape(s);
	}&nbsp;			
}</pre>

<p>これで衝突している２つのb2Bodyが取得できるので、玉だけを消す事が出来ます。</p>

<p>実際には敵b2Bodyには userData.id = 'enemy'、玉b2Bodyには userData.id = 'bullet' を追加して<br />
１つの玉が２つの敵に同時に当たる可能性もあるのですでに消されてないかをチェックしてから削除しています。</p>

<pre name="code" class="js">for&nbsp;(var&nbsp;cn:b2ContactNode&nbsp;=&nbsp;bb.m_contactList;&nbsp;cn&nbsp;!=&nbsp;null;&nbsp;cn&nbsp;=&nbsp;cn.next){
	var&nbsp;body1:b2Body;
	var&nbsp;body2:b2Body;
	var&nbsp;bulletEffect:BulletEffect;	
	if(cn.contact.GetShape1()&nbsp;&amp;&amp;&nbsp;cn.contact.GetShape2()){
		body1&nbsp;=&nbsp;cn.contact.GetShape1().m_body;
		body2&nbsp;=&nbsp;cn.contact.GetShape2().m_body;
	if(body1.m_userData.id&nbsp;==&nbsp;'bullet'&nbsp;&amp;&amp;&nbsp;body2.m_userData.id&nbsp;==&nbsp;'enemy'){
			m_world.DestroyBody(body1);
			bulletEffect&nbsp;=&nbsp;new&nbsp;BulletEffect();
			bulletEffect.x&nbsp;=&nbsp;body1.m_position.x;
			bulletEffect.y&nbsp;=&nbsp;body1.m_position.y;
			Main.effectContainer.addChild(bulletEffect);
	
		}
	if(body1.m_userData.id&nbsp;==&nbsp;'enemy'&nbsp;&amp;&amp;&nbsp;body2.m_userData.id&nbsp;==&nbsp;'bullet'){
			m_world.DestroyBody(body2);
			bulletEffect&nbsp;=&nbsp;new&nbsp;BulletEffect();
			bulletEffect.x&nbsp;=&nbsp;body2.m_position.x;
			bulletEffect.y&nbsp;=&nbsp;body2.m_position.y;
			Main.effectContainer.addChild(bulletEffect);
		}	
	}
}</pre>

<p>ちなみに、その玉が左から飛んでくる部分は Box2D/Common/Math/b2Vec2 を使います。</p>

<pre><code>var&nbsp;body:b2BodyDef&nbsp;=&nbsp;new&nbsp;b2BodyDef();
body.linearVelocity&nbsp;=&nbsp;new&nbsp;b2Vec2(1000,&nbsp;0);
//	b2Vec2(x軸の移動量,&nbsp;y軸の移動量)</pre></code>

<p>これで一部変な挙動（星の下の方だとあんまり反応薄かったり）は残りますが、物理エンジンシューティングとか作ってみたり、とか、どうでしょう？</p>

<p>以下今回のソースファイルです。<br />
Source:<a href="http://www.ficc.jp/users/ando/study/box2d/shotthestar/box2d_shotthestar.zip">box2d_shotthestar.zip</a></p>

<p>＊パブリッシュにはBox2D以外にサンプルに含まれたGeneral/FRateLimiter.as, General/Input.as が必要です。</p>]]>
    </content>
</entry>

<entry>
    <title>Box2DflashAS3で F I C の文字を降らす</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/ando/box2dflashas3_f_i_c/" />
    <id>tag:118.82.71.170,2008:/labs//5.47</id>

    <published>2008-01-28T09:37:32Z</published>
    <updated>2008-04-07T04:08:22Z</updated>

    <summary> あけましておめでとうございます、FICC安藤です。 やっと通常業務が落ち着いた...</summary>
    <author>
        <name>Ando</name>
        <uri>http://www.haricot.to/</uri>
    </author>
    
        <category term="ActionScript 3" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p><a href="http://ficc.jp/users/ando/study/box2d/letterfic/" target="_blank"><img alt="Box2D LetterFIC" src="/labs/archives/ando/box2dflashas3_f_i_c/img/box2d.jpg" width="460" height="300" /></a></p>

<p>あけましておめでとうございます、FICC安藤です。<br />
やっと通常業務が落ち着いたので、去年の末からずっと気になってた<a href="http://box2dflash.sourceforge.net/"  target="_blank">Box2DFlashAS3</a>のエントリーです。<br />
サンプルを見ながら四角や丸を一通り降らして見たので今度は自由な形状、安易に「F」「I」「C」の文字を降らしてみたいと思います。</p>]]>
        <![CDATA[<p>まず基本となる入れ物 worldを用意します。</p>

<pre name="code" class="js">var&nbsp;worldAABB:b2AABB&nbsp;=&nbsp;new&nbsp;b2AABB();
worldAABB.minVertex.Set(-1000.0,&nbsp;-1000.0);
worldAABB.maxVertex.Set(1000.0,&nbsp;1000.0);
var&nbsp;gravity:b2Vec2&nbsp;=&nbsp;new&nbsp;b2Vec2(0.0,&nbsp;300.0);
var&nbsp;doSleep:Boolean&nbsp;=&nbsp;true;
m_world&nbsp;=&nbsp;new&nbsp;b2World(worldAABB,&nbsp;gravity,&nbsp;doSleep);</pre>

<p>最初のステップから意味がわからなくて躓きましたが、お約束やおなじみらしいのでわからなくても次に行きましょう。<br />
参考：<a href="http://d.hatena.ne.jp/nitoyon/20071127/box2d_simple_sample"  target="_blank">Box2DFlashAS3 の単純なサンプルと使い方 - てっく煮ブログ</a></p>

<p> では早速「F」を追加します。</p>

<p>最初にb2PolyDefで「F」を描いたところ、当たり判定が大変な事になってしまいました。<br />
TestBed内のサンプルでも凹んだ形状は複数の物を組み合わせて表現していたのでBoxを３つ使って「F」にしてみます。</p>

<pre name="code" class="js">//	縦棒
var&nbsp;bd1:b2BoxDef&nbsp;=&nbsp;new&nbsp;b2BoxDef();
bd1.extents.Set(8,&nbsp;20);
bd1.density&nbsp;=&nbsp;1.0;
bd1.friction&nbsp;=&nbsp;0.1;
bd1.restitution&nbsp;=&nbsp;0.1;
	
//	上段横棒
var&nbsp;bd2:b2BoxDef&nbsp;=&nbsp;new&nbsp;b2BoxDef();
bd2.extents.Set(24,&nbsp;4);
bd2.localPosition.Set(16,&nbsp;-16);
	
//	下段横棒
var&nbsp;bd3:b2BoxDef&nbsp;=&nbsp;new&nbsp;b2BoxDef();
bd3.extents.Set(20,&nbsp;4);
bd3.localPosition.Set(12,&nbsp;0);
	
//	入れ物
var&nbsp;bd:b2BodyDef&nbsp;=&nbsp;new&nbsp;b2BodyDef();
bd.userData&nbsp;=&nbsp;new&nbsp;Object();
bd.userData.fillColor&nbsp;=&nbsp;randomColor();
bd.AddShape(bd1);
bd.AddShape(bd2);
bd.AddShape(bd3);
	
//bd.position.Set((Math.random()&nbsp;*&nbsp;360&nbsp;+&nbsp;20)&nbsp;/&nbsp;m_physScale,&nbsp;START_POS_Y);
//bd.rotation&nbsp;=&nbsp;Math.random()&nbsp;*&nbsp;Math.PI;
m_world.CreateBody(bd);&nbsp;</pre>

<p>色をランダムにしたいのでuserDataに色を入れておきます。<br />
userDataの使い道として正しいのかどうかわかりませんが、とりあえず。</p>

<p>「I」「C」も「F」と同じ感じなので割愛して次に地面です。</p>

<pre name="code" class="js">var&nbsp;bodyDefP:b2BodyDef&nbsp;=&nbsp;new&nbsp;b2BodyDef();
var&nbsp;polyDef:b2PolyDef&nbsp;=&nbsp;new&nbsp;b2PolyDef();
bodyDefP.userData&nbsp;=&nbsp;new&nbsp;Object();
bodyDefP.userData.fillColor&nbsp;=&nbsp;0xFFFFFF;	
polyDef.vertexCount&nbsp;=&nbsp;5;
polyDef.vertices[0].Set(180,&nbsp;0);
polyDef.vertices[1].Set(360,&nbsp;10);
polyDef.vertices[2].Set(360,&nbsp;100);
polyDef.vertices[3].Set(0,&nbsp;100);
polyDef.vertices[4].Set(0,&nbsp;10);
bodyDefP.position.Set(20,&nbsp;300);
bodyDefP.AddShape(polyDef);
m_world.CreateBody(bodyDefP);</pre>

<p>地面用と落下用（変な表現ですが）とでは使うクラスの差があるわけではなく、density の値が0または指定しなければ固定になります。</p>

<p>毎ループ時のupdate</p>

<pre name="code" class="js">public&nbsp;function&nbsp;update():void{
	updateMouseWorld();
	mouseDrag();
	m_world.Step(m_timeStep,&nbsp;m_iterations);
	var&nbsp;fillColor:int;
	var&nbsp;bb:b2Body;
	var&nbsp;s:b2Shape;
	var&nbsp;stageWidth:int&nbsp;=&nbsp;Main.rootStage.stageWidth;
	var&nbsp;stageHeight:int&nbsp;=&nbsp;Main.rootStage.stageHeight;
	var&nbsp;xOffset:int&nbsp;=&nbsp;(stageWidth&nbsp;-&nbsp;400)&nbsp;/&nbsp;2;
	var&nbsp;yOffset:int&nbsp;=&nbsp;(stageHeight&nbsp;-&nbsp;400)&nbsp;/&nbsp;2;
	for&nbsp;(bb&nbsp;=&nbsp;m_world.m_bodyList;&nbsp;bb;&nbsp;bb&nbsp;=&nbsp;bb.m_next){
	if(bb.m_position.y&nbsp;&gt;&nbsp;400&nbsp;+&nbsp;yOffset&nbsp;||&nbsp;bb.m_position.x&nbsp;&lt;&nbsp;0&nbsp;-&nbsp;xOffset&nbsp;&nbsp;||&nbsp;bb.m_position.x&nbsp;&gt;&nbsp;400&nbsp;+&nbsp;xOffset){
				if(!Input.mouseDown){
					//	画面外で尚かつドラッグ中でなければ削除
					m_world.DestroyBody(bb);
				}
			}
	}
	//	描画
	for&nbsp;(bb&nbsp;=&nbsp;m_world.m_bodyList;&nbsp;bb;&nbsp;bb&nbsp;=&nbsp;bb.m_next){
		if(bb.m_userData){
			fillColor&nbsp;=&nbsp;bb.m_userData.fillColor;
		}else{
			fillColor&nbsp;=&nbsp;0xFFFFFF;
		}
	for&nbsp;(s&nbsp;=&nbsp;bb.GetShapeList();&nbsp;s&nbsp;!=&nbsp;null;&nbsp;s&nbsp;=&nbsp;s.GetNext()){
			drawShape(s,&nbsp;fillColor);
		}
	}
}</pre>

<p>TestBed/Test.as のupdateと大差ありませんが画面外に消えた時に削除する処理を加えています。<br />
メインループ内で DestroyBody すると画面がちらついてしまったので無駄に２ループしてしまっています。</p>

<p>実際のレンダリングをするdrawShape</p>

<pre name="code" class="js">public&nbsp;function&nbsp;drawShape(_shape:b2Shape,&nbsp;_fillColor:int&nbsp;=&nbsp;0xFFFFFF):void{
	var&nbsp;i:int;
	var&nbsp;v:b2Vec2;
	var&nbsp;poly:b2PolyShape&nbsp;=&nbsp;_shape&nbsp;as&nbsp;b2PolyShape;
	var&nbsp;tV:b2Vec2&nbsp;=&nbsp;b2Math.AddVV(poly.m_position,&nbsp;b2Math.b2MulMV(poly.m_R,&nbsp;poly.m_vertices[i]));
	m_sprite.graphics.beginFill(_fillColor,&nbsp;1);
	m_sprite.graphics.lineStyle(0,&nbsp;0,&nbsp;0);
	m_sprite.graphics.moveTo(tV.x&nbsp;*&nbsp;m_physScale,&nbsp;tV.y&nbsp;*&nbsp;m_physScale);
	for&nbsp;(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;poly.m_vertexCount;&nbsp;++i){
	v&nbsp;=&nbsp;b2Math.AddVV(poly.m_position,&nbsp;b2Math.b2MulMV(poly.m_R,&nbsp;poly.m_vertices[i]));
	m_sprite.graphics.lineTo(v.x&nbsp;*&nbsp;m_physScale,&nbsp;v.y&nbsp;*&nbsp;m_physScale);
	}
	m_sprite.graphics.lineTo(tV.x&nbsp;*&nbsp;m_physScale,&nbsp;tV.y&nbsp;*&nbsp;m_physScale);
	m_sprite.graphics.endFill();
}</pre>

<p>これもTestBed/Test.as と大差なく、塗りを加えただけです。</p>

<p>最後にやっぱりマウスで掴んで振り回したり、飛ばしたりしたいのでマウスイベント周りもごっそりTestBed/Test.as クラスから拝借してますので<br />
その辺はソースをご覧ください。</p>

<p>Source:<a href="http://www.ficc.jp/users/ando/study/box2d/letterfic/box2d_letterfic.zip">box2d_letterfic.zip</a></p>

<p>＊パブリッシュにはBox2D以外にサンプルに含まれたGeneral/FRateLimiter.as, General/Input.as が必要です。</p>

<p>実際に触ってみると思ってたより使い勝手がよかったのでこれでゲーム作ったら楽しそうですね。</p>

<p>BEYESのサイトでも使われてますね：<a href="http://www.beyes.jp/recommend/60/"  target="_blank">BEYES Watch the world | RECOMMEND 60 BEYES EDIT STORE</a></p>]]>
    </content>
</entry>

<entry>
    <title>FileReferenceList、引数と戻り値</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/ando/filereferencelist/" />
    <id>tag:118.82.71.170,2007:/labs//5.46</id>

    <published>2007-11-17T13:51:00Z</published>
    <updated>2008-04-07T04:09:08Z</updated>

    <summary>FICC安藤です、遅ればせながらやっとAS3に移行を始めたので習作を兼ねたエント...</summary>
    <author>
        <name>Ando</name>
        <uri>http://www.haricot.to/</uri>
    </author>
    
        <category term="ActionScript 3" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Flash" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>FICC安藤です、遅ればせながらやっとAS3に移行を始めたので習作を兼ねたエントリーです。</p>

<p>個人的な理由でファイルのアップローダーが必要になり何でもかんでもFlashベースに組んでしまうのがFlash使いの悪いクセだと思いhtmlベースのフォームで作ってみると、複数ファイルのアップロードが意外と面倒くさいということに気づきました。</p>

<p>結局Flashの出番です。</p>

<p>Flash8から利用可能になったFileReferenceListは複数ファイルを一気に選択してアップロードができる便利なクラスでしたが放り投げたファイルを追いかけるのが厄介なクラスでもありました。<br />
CS3への変更時にその辺が改善されたので今更感もありますが、画像をFileReferenceListを使ったサンプル「FIleReferenceList、引数と戻り値」です。</p>

<p>サンプルファイル一式は<a href="ficclabs_fileReferenceListSample.zip">こちら</a></p>]]>
        <![CDATA[<p>とりあえず試してみるにはダウンロードしたファイルの中から、PHPファイルだけ実行可能なサーバにアップロードしてFileUploader.as の17行目を書き換えて書き出してみましょう。</p>

<p>PHPはファイルの容量制限や、画像のタイプなどはチェックは省いてますので必要に応じて付け加えてください。</p>

<p>以下コード</p>

<p>FileUploader.as</p>

<pre name="code" class="js">package{
 import fl.controls.Button;
 import fl.controls.Label;
 import fl.controls.TextArea;
 
 import flash.display.Sprite;
 import flash.events.DataEvent;
 import flash.events.Event;
 import flash.events.FocusEvent;
 import flash.events.MouseEvent;
 import flash.events.ProgressEvent;
 import flash.net.FileFilter;
 import flash.net.URLVariables;
 import flash.text.TextFieldAutoSize;
 
 public class FileUploader extends Sprite{
 public const UPLOAD_PHP_URL:String = 'http://yourdomain/php/sample_uploader.php';
//============================================================================================//
//  COUSTRUCTOR
//============================================================================================//
 public function FileUploader(){
   init();
  }
//--------------------------------------------------------------------------------------------------------------------------------//
//  init
//--------------------------------------------------------------------------------------------------------------------------------//
  private function init():void{
   btnBrowse.addEventListener(MouseEvent.CLICK, browse);
  }
//--------------------------------------------------------------------------------------------------------------------------------//
//  reset
//--------------------------------------------------------------------------------------------------------------------------------//
  private function resetUploader(_evt:Event):void{
   removeChild(getChildByName('txaResult'));
   removeChild(getChildByName('btnClose'));   
   txiWidth.enabled = true;
   txiHeight.enabled = true;
   btnBrowse.enabled = true;
  }
//--------------------------------------------------------------------------------------------------------------------------------//
//  browse
//--------------------------------------------------------------------------------------------------------------------------------//
  private function browse(_evt:Event):void{
   if(txiWidth.text &amp;&amp; txiHeight.text){
    var urlVariables:URLVariables = new URLVariables();
    urlVariables.imgMaxWidth = txiWidth.text;
    urlVariables.imgMaxHeight = txiHeight.text;
      var fileRef:CustomFileReferenceList = new CustomFileReferenceList(UPLOAD_PHP_URL, urlVariables);
    fileRef.addEventListener(Event.SELECT, onUploadStart);
    fileRef.addEventListener(ProgressEvent.PROGRESS, onUploadProgress);
    fileRef.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadCompleteData);
    fileRef.browse(new Array(new FileFilter('Images (*.jpg, *.jpeg)', '*.jpg;*.jpeg;'))); 
   }
  }
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  onUploadStart
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function onUploadStart(_evt:Event):void{
   txiWidth.enabled = false;
   txiHeight.enabled = false;
   btnBrowse.enabled = false;
   var lblProgress:Label = new Label();
   lblProgress.name = 'lblProgress';
   lblProgress.x = Math.round(stage.stageWidth / 2 - lblProgress.width / 2);
   lblProgress.y = 230;
   lblProgress.text = 'アップロード開始';
   lblProgress.autoSize = TextFieldAutoSize.CENTER;
   addChild(lblProgress);
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  onUploadProgress
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function onUploadProgress(_evt:ProgressEvent):void{
   var progress:int;
   if(_evt.bytesLoaded == _evt.bytesTotal){
    progress = 100;
   }else{
    progress = Math.round(_evt.bytesLoaded / _evt.bytesTotal * 100);
   }
   getChildByName('lblProgress')['text'] = progress + '%';
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  onUploadCompleteData
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function onUploadCompleteData(_evt:Event):void{
   removeChild(getChildByName('lblProgress'));
   var txaResult:TextArea = new TextArea();
   txaResult.name = 'txaResult';
   txaResult.x = 20;
   txaResult.y = 20;
   txaResult.width = 260;
   txaResult.height = 240;
   addChild(txaResult);
 
   var result = _evt.target.result;
   for(var i:int = 0; i&lt;result.length; i++){
    txaResult.appendText('----------------------------------\n');
    for(var val in result[i]){
     txaResult.appendText(val + '=' + result[i][val] + '\n');
    }
   }
 
   var btnClose:Button = new Button();
   btnClose.name = 'btnClose';
   btnClose.label = 'close';
   btnClose.x = Math.round(stage.stageWidth / 2 - btnClose.width / 2);
   btnClose.y = 270;
   addChild(btnClose);
   btnClose.addEventListener(MouseEvent.CLICK, resetUploader);
  }  
 }
}</pre>

<p>CustomFileReferenceList.as</p>

<pre name="code" class="js">package {
 import flash.events.ProgressEvent;
 import flash.events.DataEvent;
 import flash.events.Event;
 import flash.events.HTTPStatusEvent;
 import flash.events.IOErrorEvent;
 import flash.events.SecurityErrorEvent;
 import flash.net.FileReference;
 import flash.net.FileReferenceList;
 import flash.net.URLRequest;
 import flash.net.URLRequestMethod;
 import flash.net.URLVariables;
 
 class CustomFileReferenceList extends FileReferenceList {
//  VARIABLES
  private const LOADED_SUFFIX:String = &quot;_loaded&quot;;
  private const TOTAL_SUFFIX:String = &quot;_total&quot;;
  private var urlRequest:URLRequest;
  private var pendingFiles:Array;
  private var objUploadProgress:Object;
  private var _result:Array;
//============================================================================================//
//  CONSTRUCTOR
//============================================================================================//
  public function CustomFileReferenceList(_uploadPHPURL:String, _urlVariables:URLVariables) {
   urlRequest = new URLRequest();
   urlRequest.url = _uploadPHPURL;
   urlRequest.method = URLRequestMethod.POST;
   urlRequest.data = _urlVariables;  
   addEventListener(Event.SELECT, onSelect);
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  onSelect
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function onSelect(event:Event):void {
   _result = new Array();
   objUploadProgress = new Object();
   pendingFiles = new Array();
 
   var file:FileReference;
   for (var i:uint = 0; i &lt; fileList.length; i++) {
    file = FileReference(fileList[i]);
    objUploadProgress[file.name + LOADED_SUFFIX] = 0;
    objUploadProgress[file.name + TOTAL_SUFFIX] = 0;
    addPendingFile(file);
   }
  }
//--------------------------------------------------------------------------------------------------------------------------------//
//  addPendingFIle
//--------------------------------------------------------------------------------------------------------------------------------//
  private function addPendingFile(file:FileReference):void {
   pendingFiles.push(file);
   file.addEventListener(Event.COMPLETE, fileUploadInteraction);
   file.addEventListener(IOErrorEvent.IO_ERROR, fileUploadInteraction);
   file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, fileUploadInteraction);
   file.addEventListener(ProgressEvent.PROGRESS, onUploadProgress);
   file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadCompleteData);
   file.upload(urlRequest);
  }
//--------------------------------------------------------------------------------------------------------------------------------//
//  removePendingFile
//--------------------------------------------------------------------------------------------------------------------------------//
  private function removePendingFile(file:FileReference):void {
   for (var i:uint; i &lt; pendingFiles.length; i++) {
    if (pendingFiles[i].name == file.name) {
     pendingFiles.splice(i, 1);
    return;
    }
   }
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  eventHandlers
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function fileUploadInteraction(_evt):void{
   var file:FileReference = FileReference(_evt.target);
   switch(_evt.type){
    case Event.COMPLETE:
     removePendingFile(file);
     break;
    case IOErrorEvent.IO_ERROR:
     trace(&quot;ioErrorHandler: name=&quot; + file.name);
     break;
    case SecurityErrorEvent.SECURITY_ERROR:
     trace(&quot;securityErrorHandler: name=&quot; + file.name + &quot; event=&quot; + _evt.toString());
     break;
   }
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  onUploadProgress
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function onUploadProgress(_evt:ProgressEvent):void{
   var file:FileReference = FileReference(_evt.target);
   objUploadProgress[file.name + LOADED_SUFFIX] = _evt.bytesLoaded;
   objUploadProgress[file.name + TOTAL_SUFFIX] = _evt.bytesTotal;
   var loaded:int = 0;
   var total:int = 0;
   for(var i:int = 0; i&lt;pendingFiles.length; i++){
    var tmpLoaded:int = objUploadProgress[pendingFiles[i].name + LOADED_SUFFIX];
    var tmpTotal:int = objUploadProgress[pendingFiles[i].name + TOTAL_SUFFIX];
    if(tmpLoaded != tmpTotal &amp;&amp; tmpTotal != 0){
     loaded += tmpLoaded;
     total += tmpTotal;
    }
   }
   dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, false, false, loaded, total));
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//  onUploaded
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  private function onUploadCompleteData(_evt:DataEvent):void{
   var resultObj:Object = new Object();
   var splitedDataList:Array = _evt.data.split('&amp;');
   for(var i:int = 0; i&lt;splitedDataList.length; i++){
    var splitedData:Array = splitedDataList[i].split('=');
    resultObj[splitedData[0]] = splitedData[1];
   }
   _result.push(resultObj);
   if (pendingFiles.length == 0) {
    dispatchEvent(new Event(DataEvent.UPLOAD_COMPLETE_DATA));
   }   
  }
//--------------------------------------------------------------------------------------------------------------------------------//
//  removePendingFile
//--------------------------------------------------------------------------------------------------------------------------------//  
  public function get result():Array{
   return  _result;
  }
 }
}</pre>

<p>参考：<a href="http://livedocs.adobe.com/flash/9.0_jp/ActionScriptLangRefV3/flash/net/FileReferenceList.html" _target="_blank">Adobe livedoc</a></p>]]>
    </content>
</entry>

<entry>
    <title>Photoshop ショートカット(2)</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/sato/photoshop_2/" />
    <id>tag:118.82.71.170,2007:/labs//5.45</id>

    <published>2007-09-27T11:11:32Z</published>
    <updated>2008-03-28T17:17:14Z</updated>

    <summary>だいぶ久しぶりのエントリーになってしまいましたが、Photoshopショートカッ...</summary>
    <author>
        <name>Sato</name>
        <uri>http://www.samplogue.jp/</uri>
    </author>
    
        <category term="Photoshop" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>だいぶ久しぶりのエントリーになってしまいましたが、Photoshopショートカット第2弾です。<br />
今回は知っていると便利そうなものを中心にまとめてみました。<br />
日ごろ集めた情報と自分の良く使うものを、とりあえず、ダーっと勢いでまとめた感じなので箇条書きで少し見辛いですが、今後は便利系ショートカットはこのページに追記していく予定なのでキャプチャーとかいれてもう少し見易くしていければと思っております。<br />
もし、他にもこんなのも便利なショートカットがあるよという方がいらっしゃいましたら教えていただけると大変有難いです。</p>]]>
        <![CDATA[<p><strong>■インターフェース</strong></p> 
<ul>
<li><span class="shortcutKey">Tab</span>キーを押すとツールバーとパレットが非表示になる。
<span class="shortcutKey">Shift + Tab</span>でパレットのみ非表示にすることが出来る。
<li>パレットのタイトルバーを<span class="shortcutKey">Shift</span>を押しながらクリックすると最寄の枠にくっつく（CS3ではナシ）
<li><span class="shortcutKey">F</span>でスクリーンモードでの切り替え
<li>イメージウィンドウのタイトルバーを右クリックすると「複製」「画像解像度」「カンバスサイズ」等を素早く選べる。
<li>トーンカーブ・レベル補正等の設定ダイアログ内で<span class="shortcutKey">Alt</span>を押すとキャンセルボタンが初期化ボタンに変わる。
<li>トーンカーブの調整フィールドをクリックでグリッドのサイズを選べる。
<li><span class="shortcutKey">Cntl + Tab</span>でアクティブウィンドウの切り替え。
<li><span class="shortcutKey">Cntl + Alt + W</span>で開いているウィンドウ全てを閉じる。
</ul>
<p><strong>■ツール</strong></p>
<ul>
<li>カンバス内で<span class="shortcutKey">Cntl</span>ボタンを押すと移動ツールに代わる。
<li>移動ツール使用時に<span class="shortcutKey">Alt</span>を押しながら移動したオブジェクトは複製される。
<li><span class="shortcutKey">Cntl + Plus(+)</span>で表示を拡大、<span class="shortcutKey">Cntl + Minus(-)</span>で縮小できるが、<span class="shortcutKey">Alt</span>を押しながら行うとウィンドウサイズも合わせて拡大・縮小される。
<li><span class="shortcutKey">Alt + Backspace</span>で描画色でレイヤーを塗りつぶし、<span class="shortcutKey">Alt + Shift + Backspace</span>で描画色で透明部分を保持して塗りつぶし、<span class="shortcutKey">Cntl+ Backspace</span>で背景色でレイヤーを塗りつぶし、<span class="shortcutKey">Cntl+ Shift + Backspace</span>で背景色で透明部分を保持して塗りつぶし、<span class="shortcutKey">Shift + Backspace</span>で塗りつぶし設定を開くことが出来る。
ちなみに<span class="shortcutKey">Cntl + Alt + Backspace</span>でファイルを開いた時のレイヤーの状態に塗りつぶし（復帰）が出来るようだ。
<li>長方形・楕円形選択ツールで選択範囲を作成中にスペースバーを押すと基準点を移動できる。
<li>表示されているパスを選択範囲に変換するには<span class="shortcutKey">Cntl + Enter</span>、既に選択範囲がある場合は<span class="shortcutKey">Cntl + Shift + Enter</span>で選択範囲に追加、<span class="shortcutKey">Cntl + Alt + Enter</span>で削除。
<li>パスが表示された状態でブラシツールを選択して<span class="shortcutKey">Enter</span>を押すとブラシの設定で線に沿って色を塗ることが出来る。(消しゴム、スタンプツール等でも可)
</ul>
<p><strong>■レイヤー</strong></p>
<ul>
<li><span class="shortcutKey">Shit + Plus(+)</span>、<span class="shortcutKey">Shit + Minus(-)</span>で描画モードの変更。(直接呼び出す場合は以下)
<li><span class="shortcutKey">Alt + Shift + N</span> = 通常
<li><span class="shortcutKey">Alt + Shift + I</span> = ディザ合成
<li><span class="shortcutKey">Alt + Shift + M</span> = 乗算
<li><span class="shortcutKey">Alt + Shift + K</span> = 比較(暗)
<li><span class="shortcutKey">Alt + Shift + B</span> = 焼き込みカラー
<li><span class="shortcutKey">Alt + Shift + A</span> = 焼き込み(リニア)
<li><span class="shortcutKey">Alt + Shift + G</span> = 比較(明)
<li><span class="shortcutKey">Alt + Shift + S</span> = スクリーン
<li><span class="shortcutKey">Alt + Shift + D</span> = 覆い焼きカラー
<li><span class="shortcutKey">Alt + Shift + W</span> = 覆い焼きカラー(リニア)-加算
<li><span class="shortcutKey">Alt + Shift + O</span> = オーバーレイ
<li><span class="shortcutKey">Alt + Shift + F</span> = ソフトライト
<li><span class="shortcutKey">Alt + Shift + H</span> = ハードライト
<li><span class="shortcutKey">Alt + Shift + V</span> = ビビッドライト
<li><span class="shortcutKey">Alt + Shift + J</span> = リニアライト
<li><span class="shortcutKey">Alt + Shift + Z</span> = ピンライト
<li><span class="shortcutKey">Alt + Shift + L</span> = ハードミックス
<li><span class="shortcutKey">Alt + Shift + E</span> = 差の絶対値
<li><span class="shortcutKey">Alt + Shift + X</span> = 除外
<li><span class="shortcutKey">Alt + Shift + U</span> = 色相
<li><span class="shortcutKey">Alt + Shift + T</span> = 彩度
<li><span class="shortcutKey">Alt + Shift + C</span> = カラー
<li><span class="shortcutKey">Alt + Shift + Y</span> = 輝度
<li><span class="shortcutKey">Alt</span>押しながら表示アイコン(目)を押すと選択レイヤー以外を非表示
<li><span class="shortcutKey">Cntl</span>を押しながらフォルダを開閉すると同時にすべてのフォルダを開閉できる。
<li>レイヤーパレット内の各レイヤーの間で<span class="shortcutKey">Alt</span>を押してクリックすると下のレイヤーでクリッピングマスクを作成。
<li><span class="shortcutKey">Cntl</span>を押しながらレイヤーをクリックすると透明部分を除く選択範囲を作成できる。(CS2以降、サムネールのみに範囲が限定された)
更に<span class="shortcutKey">Shift</span>を押しながらその他のレイヤーをクリックすると選択範囲が追加され、<span class="shortcutKey">Alt</span>を押すと削除される。
<li><span class="shortcutKey">Alt</span>を押しながらゴミ箱ボタンを押すとダイアログ無しでレイヤーを削除できる。
<li><span class="shortcutKey">Cntl + Shift + H</span>でパスの表示、非表示。
<li>移動ツール使用時にカンバス内で右クリックするとポインターの下にあるレイヤーを参照出来る。
<span class="shortcutKey">Alt</span> + 右クリックで一番上のレイヤーを選択。更に<span class="shortcutKey">Alt + Shift</span>で現在選択されているレイヤーと一番上のレイヤーをリンク(CS3では選択)。
<li>レイヤーを選択し、<span class="shortcutKey">Q</span>でクイックマスク、<span class="shortcutKey">/</span>で位置をロック。
<li><span class="shortcutKey">Alt</span>を押しながらレイヤーを移動するとレイヤーが複製される。
<li><span class="shortcutKey">Cntl + Alt + ↑or↓or→or←</span>で選択レイヤーの上にレイヤーが複製される。
<li><span class="shortcutKey">Cntl + J</span>で選択レイヤーの上にレイヤーが複製される。
<li><span class="shortcutKey">Cntl + Alt + Shift + E</span>で現在表示されている状態のレイヤーを生成。
選択範囲がある場合は<span class="shortcutKey">Cntl + Shift + C</span>で選択範囲内に限定してコピー。
<li><span class="shortcutKey">Shift</span>を押しながらマスクを押すとマスク効果の表示・非表示。
<li><span class="shortcutKey">Alt</span>を押しながらマスクを押すとマスクオブジェクトの表示・非表示。
<li><span class="shortcutKey">Cntl</span>を押しながらマスクを押すとマスクオブジェクト(白い部分)で選択範囲の作成。
<li><span class="shortcutKey">Cntl + Alt + 1</span>(レッド)、<span class="shortcutKey">Cntl + Alt + 2</span>(グリーン)、<span class="shortcutKey">Cntl + Alt + 3</span>(ブルー)でチャンネルの選択範囲を読み込む。(RGBモードの場合)
</ul>
<p><strong>■ガイド</strong></p>
<ul>
<li>ガイドの追加又は移動時に<span class="shortcutKey">Alt</span>を押すと縦横を変更出来る。
</ul>
<p><strong>■複製</strong></p>
<ul>
<li>違うファイルにレイヤーやフォルダを移動する際に<span class="shortcutKey">Shift</span>を押すと移動先のファイルの中央に配置される。
移動先のファイルが移動元のファイルと同じサイズであれば、まったく同じ座標に配置される。
</ul>
<p><strong>■テキスト</strong></p>
<ul> 
<li>いくつかのテキストレイヤーに同じ変更を行いたい場合は、レイヤーをリンクして(CS2以降では選択)Shiftを押しながらプロパティを変更する。
<li>文字ツールを使用時、文字をダブルクリックで一語選択、3回クリックで一行選択、4回クリックで一段落選択、5回クリックで全て選択となる。
<li>文字も<span class="shortcutKey">Cntl + Backspace</span>で描画色、<span class="shortcutKey">Alt + Backspace</span>で背景色で塗りつぶすことが出来る。
<li>文字パレットでフォント名、値にフォーカスした状態(青で覆われている)の時<span class="shortcutKey">↑</span>又は<span class="shortcutKey">↓</span>で値を変更出来る。
特にフォントはリアルタイムでドキュメントに反映されるので、選びやすい。
<li><span class="shortcutKey">Cntl + Enter</span>で文字入力を確定。
</ul>]]>
    </content>
</entry>

<entry>
    <title>Twitterブログパーツ更新</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/ando/twitter/" />
    <id>tag:118.82.71.170,2007:/labs//5.44</id>

    <published>2007-08-23T12:04:49Z</published>
    <updated>2008-11-26T11:27:50Z</updated>

    <summary>FICC安藤です。 春に作ったtwitterブログパーツが意外に貼って頂いてたら...</summary>
    <author>
        <name>Ando</name>
        <uri>http://www.haricot.to/</uri>
    </author>
    
        <category term="Flash" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>FICC安藤です。</p>

<p>春に作ったtwitterブログパーツが意外に貼って頂いてたらしく、申し訳ないのでちゃんと作り直ししました。</p>

<p>ファイルの場所が変わりましたので以前貼って頂いた方も新しいソースに更新をお願いします。</p>

<p>以下貼付け用ソースです。<br />
<pre name="code" class="html">&lt;script type=&quot;text/javascript&quot; src=&quot;http://labs.ficc.jp/projects/twitter_blogparts/js/twitter2.js&quot;&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; &gt;attachBlogParts(<span class="red">幅, &quot;背景色&quot;, &quot;twitterユーザーID&quot;</span>);&lt;/script&gt;</pre></p>

<p>サンプルとしてページ右側の「ficc」のソースです。<br />
<pre name="code" class="js">attachBlogParts(205, &quot;#FAFAFA&quot;, &quot;ficc&quot);</pre></p>

<p>免責事項：<br />
このブログパーツをご利用されたことで生じるいかなる損害についても責任を負うものではありません。<br />
このブログパーツは予告なしに停止・変更又は抹消される場合があります。あらかじめご了承ください。</p>]]>
        
    </content>
</entry>

<entry>
    <title>[MTプラグイン] エントリーのプレビュー機能を改善するプラグイン</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/shota/mt_style_preview/" />
    <id>tag:118.82.71.170,2007:/labs//5.43</id>

    <published>2007-06-26T07:45:10Z</published>
    <updated>2009-09-16T01:39:05Z</updated>

    <summary>どうも、FICC戸塚です。MTの便利なプラグインを先日見つけたので投稿します。 ...</summary>
    <author>
        <name>Shota</name>
        <uri>http://www.ausp.net/</uri>
    </author>
    
        <category term="Movable Type" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>どうも、FICC戸塚です。MTの便利なプラグインを先日見つけたので投稿します。</p>

<p>エントリーを投稿する時、公開しているブログと同様の見えでプレビューができればなぁと思っている方は多いはず。一度「公開」して、本番で確認するのもありですが、それだとフィードが一度生成されてしまいます。</p>

<p>そんな時、<a href="http://junnama.alfasado.net/online/2007/03/movabletype_3.html" target="_blank">StylePreview</a>というプラグインがあれば、もう大丈夫。これを使えば、ブログのエントリーページのCSSが適用された状態で投稿内容がプレビューができます。ついに、投稿ページの「確認」ボタンで本当に「確認」できるようになります。ちなみにバージョン4ではちゃんとプレビューができるようになってるようです...。</p>

<ul>
<li><a href="http://junnama.alfasado.net/online/2007/03/movabletype_3.html" target="_blank">MovableTypeのプレビュー機能を改良する(StylePreviewプラグイン)。 (Junnama Online (Mirror))</a></li>
<li><a href="http://glover.jp/2007/07/13/movable_type_style_preview.php" target="_blank">Movable Type のエントリーを確認ボタンでプレビューする方法 / glover</a></li>
</ul>]]>
        
    </content>
</entry>

<entry>
    <title>カメラと被写体の関係から擬似3D空間を作る (2)</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/akira/flash_3d_camera_2/" />
    <id>tag:118.82.71.170,2007:/labs//5.42</id>

    <published>2007-06-18T01:18:56Z</published>
    <updated>2008-04-07T04:10:27Z</updated>

    <summary>FICC 福岡です。 CS3ももうすぐ登場する事だしそろそろPaperVisio...</summary>
    <author>
        <name>Akira</name>
        <uri>http://www.akirafukuoka.com/</uri>
    </author>
    
        <category term="ActionScript 2" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Flash" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>FICC 福岡です。<br />
CS3ももうすぐ登場する事だしそろそろPaperVision3Dとか...と思っている方もいらっしゃるでしょうが、今回も引き続きAS2でがんばる3Dのお話。前回お話しした<a href="/labs/archives/akira/flash_3d_camera/">「カメラと被写体の関係から擬似3D空間を作る」</a>で公開したコードですが、実はちょっとした問題点を抱えております。それは「カメラのZ座標によってオブジェクトの見え方が異なる」。図で簡単にご説明しましょう。</p>

<p><img alt="Z値が大きくなればなるほどオブジェクトが詰まっていく" src="/labs/archives/akira/flash_3d_camera_2/img/3d_sideview.jpg" width="460" height="112" /></p>]]>
        <![CDATA[<p>この図は前回作成した3D空間を横から見たものです。黒い棒は浮遊している矩形を横から見たものと思ってください。前回ご説明したコードではオブジェクトのZ位置が大きくなればなるほど、距離が詰まっていってしまうのです。つまりカメラと被写体の距離・位置関係が同じでも、Z値によってまったく別の見え方（奥行きがなくなっていく）になってしまう。しかしなぜこんなことになってしまったか...答えは次の一行です。</p>

<pre name="code" class="js">var sZ:Number = camera.oz/this.oz;</pre>

<p>前回のコードではカメラとオブジェクトの距離の差を割り算で算出していました。例えばカメラとオブジェクトのZ値の差が2000だとしても、2000/4000 = 0.5 と 12000/14000 = 約0.86と大幅に答えが変わってしまう事に。本当ならば2000と4000でも12000と14000でも同じ答えにならいと困りますよね。ただ前回のコードで作成した3D空間は限りがあったために気付きにかったということです。もし仮に延々と奥行きがある3D空間であればこの書き方では少し困ってしまう事も。ですからZ値の差を表すsZは、</p>

<pre name="code" class="js">var dZ:Number = this.oz-camera.oz;<br />
var sZ:Number = 1/(dZ*0.0003+1);</pre>

<p>これならどこでどう切り取っても同じ見え方に。これを踏まえて今回は延々と奥行きがある3D空間ということで、今話題の<a href="http://www.apple.com/macosx/leopard/features/timemachine.html" target="_blank">Time Machine</a>を作ってみました。</p>

<div id="timemachine"></div>
<script type="text/javascript" src="/labs/common/js/swfobject.js"></script>
<script type="text/javascript">
// <![CDATA[
var so = new SWFObject('swf/timemachine.swf', 'CaseStudy', '460', '307', '8', '#000000');
so.useExpressInstall('/labs/common/swf/expressinstall.swf');
so.addParam('menu', 'false');
so.addParam('scale', 'noscale');
so.write('timemachine');
// ]]&gt;
</script>

<p>本物に似てる似てないかは別として、中身のコードは前回とさほど変わらないのでコードの記述は省略します。その代わりに<a href="flash_3d_camera_2.zip">ソースファイル</a>を用意しました。ぜひダウンロードしてどこまで本物のTime Machineに近づけることができるか(星が流れる、ウィンドウの中身が操作できるetc...)がんばってみてください。ちなみにコンパイルには<a href="http://www.mosessupposes.com/Fuse/" target="_blank">Fuse Kit</a>が必要ですのでご注意を。</p>]]>
    </content>
</entry>

<entry>
    <title>[MTプラグイン] RightFieldsについて</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/shota/mt_rightfields/" />
    <id>tag:118.82.71.170,2007:/labs//5.41</id>

    <published>2007-06-12T03:08:41Z</published>
    <updated>2008-04-07T04:10:52Z</updated>

    <summary>はじめまして、FICCの戸塚です。 FICCではデザイン・HTMLコーディングを...</summary>
    <author>
        <name>Shota</name>
        <uri>http://www.ausp.net/</uri>
    </author>
    
        <category term="Movable Type" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>はじめまして、FICCの戸塚です。</p>

<p>FICCではデザイン・HTMLコーディングを担当しています。LABSでは、MTのプラグインやいかついカスタマイズ方法についてご紹介できればと思います。また、CSSの小ネタなんかも投稿予定です。</p>

<p><a href="http://www.sixapart.jp/press_releases/2007/06/05-1430.html" target="_blank">MT4</a>が発表されてしまった今タイミング的に非常に微妙なのですが、今回は<a href="http://www.staggernation.com/mtplugins/RightFields" target="_blank">RightFields</a>というMTのプラグインについて簡単にご紹介します。</p>]]>
        <![CDATA[<p>RightFieldsの特徴としては、1）既存のエントリーフィールドのカスタマイズできる、2）エントリーフィールドの数を増やせ、カスタマイズできる点が挙げられます。</p>

<p>最近では、その拡張性や機能面から、MTをCMSとして使う事が一般的になっていますが、一方でHTMLに不慣れな人にとっては、MTは取っつき難いものと思われているのも事実。例えば、エントリーフィールドの数を増やし、フィールド細分化して、極力HTMLタグを入力しなくて済むようにすれば、その取っ付き難さは軽減できるのではないでしょうか。エントリーフィールドの名前を変えるだけでも、分かりやすさは格段に向上するはずです。</p>

<p>インストール方法やフィールドの増やし方などは割愛させて頂きますが、今回RightFieldsの機能の中でご紹介したいのが、それぞれのフィールドの値をifタグで挟める<code>&lt;MTIfExtraField&gt;</code>という独自タグについて。これを使えば、増やしたフィールドに対して<code>&lt;MTIfNonEmpty&gt;</code>タグと同じような事ができます。</p>

<p>例えば、MTをバリバリにカスタマイズして完成した<a href="http://www.wsi.jp/" target="_blank">WSIのウェブサイト</a>。<a href="http://www.wsi.jp/database/steelcase/seating/leap/" target="_blank">商品ページ</a>は、商品詳細のPDFファイルがある場合、カスタマイズしたフィールドを使ってファイルをアップロードすれば、ページにボタンが表示されるように設計されています。ここでは、「商品情報PDFダウンロード」というボタンのHTMLソースが<code>&lt;MTIfExtraField&gt;</code>で囲まれていて、フィールドの値によってボタンの表示・非表示がコントロールされている訳です。</p>

<p><a href="http://www.wsi.jp/database/steelcase/seating/leap/" target="_blank"><img src="http://www.ficc.jp/labs/archives/shota/mt_rightfields/img/wsi_page.gif" alt="WSI" width="466" height="176" class="bdr" title="WSI" /></a></p>

<p><img src="http://www.ficc.jp/labs/archives/shota/mt_rightfields/img/mt_entry_field.gif" alt="WSIのエントリーフィールド" width="466" height="176" class="bdr" title="WSIのエントリーフィールド" /></p>

<p><strong>例：</strong></p>

<pre name="code" class="html">&lt;p&gt;
&lt;MTIfExtraField field=&quot;product_pdf&quot;&gt;
&lt;a href=&quot;&lt;$MTBlogURL$&gt;database/steelcase/pdf/&lt;$MTExtraFieldValue field=&quot;product_pdf&quot;$&gt;&quot; target=&quot;_blank&quot;&gt;
&lt;img src=&quot;&lt;$MTBlogURL$&gt;common/img/btn_product_pdf_download.gif&quot; alt=&quot;商品情報PDFダウンロード&quot; width=&quot;187&quot; height=&quot;34&quot; title=&quot;商品情報PDFダウンロード&quot; /&gt;
&lt;/a&gt;
&lt;/MTIfExtraField&gt;
&lt;/p&gt;</pre>

<p>また、<code>&lt;MTIfExtraField&gt;</code>はチェックボックス（にカスタマイズしたフィールド）ともリンクさせられるので、上記の例であれば、「商品情報PDFダウンロードボタンを表示する」というような名称にチェックボックスを設定すれば、チェックボックスのオン・オフで同様の効果が得られます。（ファイルのアップロードは別に行う必要がありますが...。）チェックボックスと<code>&lt;MTIfExtraField&gt;</code>の組み合わせ。使いようによっては、これはかなり便利な機能です。</p>

<p>さらに、<code>&lt;MTIfExtraField&gt;</code>は<code>&lt;MTElse&gt;</code>タグとも組み合わせられるのも魅力的。これならカスタマイズの幅はかなり広がるはずです。</p>

<p>MT4で、このRightFieldsプラグインがそのまま使えるか微妙ですが（恐らく使えない？）、MT3.3xをしばらく使う方にとってはこのプラグインは心強いですよね。</p>

<p><a href="http://www.staggernation.com/mtplugins/RightFields" target="_blank">RightFields | Plugins for Movable Type | staggernation.com</a></p>]]>
    </content>
</entry>

<entry>
    <title>Flashから画像ファイルを保存する</title>
    <link rel="alternate" type="text/html" href="http://www.ficc.jp/labs/archives/ando/flash_img_file/" />
    <id>tag:118.82.71.170,2007:/labs//5.40</id>

    <published>2007-06-11T13:00:20Z</published>
    <updated>2008-04-07T04:11:41Z</updated>

    <summary>喜び勇んで英語版Flash CS3 Trialをインストールした皆様、そろそろ試...</summary>
    <author>
        <name>Ando</name>
        <uri>http://www.haricot.to/</uri>
    </author>
    
        <category term="ActionScript 3" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Flash" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.ficc.jp/labs/">
        <![CDATA[<p>喜び勇んで英語版Flash CS3 Trialをインストールした皆様、そろそろ試用期限が切れてしまった頃でしょうか？</p>

<p>FICC安藤です。<br />
FICCサイトのバックエンドの設計、構築、FLASH開発など担当しました、裏方の人です。<br />
MT+Flashの記事から始める予定でしたがCS3日本語版の発売間近という事もあり先にCS3(AS3)関連のエントリーから。</p>

<p>今回はFlashから画像ファイルを保存する方法です。<br />
画像ファイルを保存するという事だけであればAS2時代から「一応」可能でしたが今回はせっかくAS3ですのでよりスマートな方法で実現したいと思います。</p>]]>
        <![CDATA[<div id="CaseStudy"></div>
<script type="text/javascript" src="/labs/common/js/swfobject.js"></script>
<script type="text/javascript">
// <![CDATA[
var so = new SWFObject('swf/CaseStudy.swf', 'CaseStudy', '560', '200', '9.0.45', '#ffffff');
so.useExpressInstall('/labs/common/swf/expressinstall.swf');
so.addParam('menu', 'false');
so.addParam('scale', 'noscale');
so.write('CaseStudy');
// ]]&gt;
</script>
(Player9.0.45.0以降が必要です）

<p>ちなみにAS2ではgetPixel()を使い左上から右下までのピクセルの色情報が入った配列をPHPなどにポストし、サーバで同じように１ピクセルずつ描いて復元するという方法で可能です。<br />
実際に現在のFICCサイトもその方法でエントリー投稿時にローカルの管理ツールから文字のPNGをアップロードし、その内容を自動でMTにポストする形をとっていますがサーバ負荷を考えるとあまりお勧めできません。</p>

<p>それでは必要な下準備からしていきましょう。<br />
今回のサンプルではAdobe Labsのas3corelibのJPGEncoderクラスを利用します。</p>

<p>SVNリポジトリはこちら<br />
<a href="http://as3corelib.googlecode.com/svn/" target="_blank">http://as3corelib.googlecode.com/svn/</a></p>

<pre name="code" class="js">package {
	import flash.display.Sprite;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.Event;
	import fl.controls.Button;
	import flash.events.MouseEvent;
	import flash.utils.ByteArray;
	import flash.text.TextField;
	import flash.net.*;
	import com.adobe.images.JPGEncoder;
	public class CaseStudy extends Sprite {
		private var bmdPerlin:BitmapData;
		private var bmp:Bitmap;
		private var urlRequest:URLRequest
		private var urlLoader:URLLoader;
		private var imgDir:String = &quot;http://yourdomain/img/&quot;;
		private var phpPath:String = &quot;http://yourdomain/encoder.php&quot;;
		private var fileName:String;
		private var btnRedraw:Button;
		private var btnUpload:Button;
		private var btnImage:Button;
		private var txtFld:TextField;
		public function CaseStudy() {
			stage.quality   = &quot;MEDIUM&quot;;
			stage.scaleMode = &quot;noScale&quot;;
			bmdPerlin = new BitmapData(100, 100, false, 0x00CCCCCC);
			bmp = new Bitmap(bmdPerlin);
			bmp.x = 180;
			bmp.y = 30;
			drawPerlinNoise(null);
			addChild(bmp);
			txtFld = new TextField();
			txtFld.text = &quot;アップロード中&quot;;
			txtFld.x = 190;
			txtFld.y = 135;
			addChild(txtFld);
			txtFld.visible = false;
			setRedrawBtn();
			setUploadBtn();
			setImageBtn();
		}
		//-----------------------------------------------------------------//
		//	redraw button
		//-----------------------------------------------------------------//
		private function setRedrawBtn():void {
			btnRedraw = new Button();
			btnRedraw.label = &quot;redraw&quot;;
			btnRedraw.move(140, 160);
			btnRedraw.setSize(80,30);
			addChild(btnRedraw);
			btnRedraw.addEventListener(MouseEvent.CLICK, drawPerlinNoise);
		}
		private function drawPerlinNoise(event:Event):void {
			bmdPerlin.perlinNoise(Math.floor(Math.random()*100),Math.floor(Math.random()*100),6,Math.floor(Math.random()*10),false,true);
		}
		//-----------------------------------------------------------------//
		//	upload button
		//-----------------------------------------------------------------//
		private function setUploadBtn():void {
			btnUpload = new Button();
			btnUpload.label = &quot;upload&quot;;
			btnUpload.move(240, 160);
			btnUpload.setSize(80,30);
			addChild(btnUpload);
			btnUpload.addEventListener(MouseEvent.CLICK, upload);
		}
		private function upload(event:Event):void{
			btnRedraw.enabled = false;
			btnUpload.enabled = false;
			txtFld.visible = true;
			var jpgEncoder:JPGEncoder = new JPGEncoder(80);
			var byteArr:ByteArray = jpgEncoder.encode(bmdPerlin);
			urlRequest = new URLRequest(phpPath);
			urlLoader = new URLLoader();
			urlRequest.contentType = &quot;application/octet-stream&quot;;
			urlRequest.method = URLRequestMethod.POST;
			urlRequest.data = byteArr;
			urlLoader.load(urlRequest);
			urlLoader.addEventListener(Event.COMPLETE,onUpload);
		}
		private function onUpload(event:Event):void{
			txtFld.visible = false;
			bmp.visible = false;
			btnImage.visible = true;
			fileName = urlLoader.data;
		}
		//-----------------------------------------------------------------//
		//	画像を表示 button
		//-----------------------------------------------------------------//
		private function setImageBtn():void{
			btnImage = new Button();
			btnImage.label = &quot;画像を表示&quot;;
			btnImage.move(180,30);
			btnImage.setSize(100,100);
			addChild(btnImage);
			btnImage.visible = false;
			btnImage.addEventListener(MouseEvent.CLICK, openURL);
		}
		private function openURL(event:Event):void{
			navigateToURL(new URLRequest(imgDir+fileName),&quot;_blank&quot;);
			btnRedraw.enabled = true;
			btnUpload.enabled = true;
			btnImage.visible = false;
			bmp.visible = true;
		}
	}
}</pre>

<p>画像の保存と関係のないコードで少し長くなりましたが、必要な部分はシンプルです。</p>

<pre name="code" class="js">var jpgEncoder:JPGEncoder = new JPGEncoder(JPGの画質);
var byteArr:ByteArray = jpgEncoder.encode(BitmapData);</pre>

<p><br />
あとはbyteArrに入ったJPGバイナリをPHPに送るだけです。<br />
以下、データを保存してファイル名をprintするだけのシンプルなPHPです。<br />
必要に応じて書き加えてください。</p>

<pre name="code" class="php">&lt;?php
$fileName&nbsp;=&nbsp;time().&quot;-&quot;.round(rand(1,10000)).&quot;.jpg&quot;;
$fp&nbsp;=&nbsp;fopen(&quot;img/&quot;.$fileName,&nbsp;'wb');
fwrite($fp,&nbsp;$GLOBALS['HTTP_RAW_POST_DATA']);
fclose($fp);
print&nbsp;$fileName;
?&gt;</pre>

<p>ちなみにJPGEncoderと同様にPNGEncoderもありますが、こちらはstaticなので使い方が異なります。<br />
<pre name="code" class="js">import com.adobe.image.PNGEncoder;<br />
var byteArr:ByteArray = PNGEncoder.encode(BitmapData);</pre><br />
これでFlashでレタッチソフトとか作れますね。</p>]]>
    </content>
</entry>

</feed>
