ウェブサイトをダイナミックで華やかに飾るflashムービーがあるのは有名です。 Mingと呼ばれるライブラリを使えばPHPからでもこのflashムービーを作成することができます。 xamppliteを入れたらMingも付属してたのでこれを使っていろいろ遊んでみたいと思います。 と、その前にflashについての簡単なことをまとめておきます。 flash5からActionScriptが使えるようになってゲームが作れるようになったらしいです。 flashの構造は、土台となるSWFMovieオブジェクトを作成して、その上にいろんな部品オブジェクトを貼り付けていくようなイメージです。 例えて言うなら、土台となる自動車に荷台を貼り付けてトラックにしたり、クレーンを貼り付けてクレーン車にしたり、ハシゴを乗っけてハシゴ車にしたりするイメージです。 SWFMovieはその名のとおり、ムービー的に表示させるためのタイムラインを持っています。 なので、SWFMovieに貼り付いてるオブジェクト全体をフレーム単位で刻々と変化させていくことができるということです。 SWFMovieと似ているSWFSprite(ムービークリップとも呼ばれる)は、これ自体がムービーで、独自のタイムラインを持っています。 単純に図形や画像、文字といったものを表示させるだけならflashの必要性があまりないので、flashとして作るからには貼り付けたオブジェクトをフレームごとにいろいろ動かしたり、操作に応じて変化していくものを作ることになると思います。 flashにはActionScriptと呼ばれるコンパクトなプログラム(スクリプト)を含ませることができます。 ActionScriptは、ブラウザでのなんらかのアクション(操作)に応じて行いたい処理を記述しておくためのスクリプトになります。 つまり、単にムービー的な表示以外にゲームのようなインタラクティブな操作をさせたい場合には必須ということになります。
ウェブサイトをダイナミックで華やかに飾るflashムービーがあるのは有名です。
Mingと呼ばれるライブラリを使えばPHPからでもこのflashムービーを作成することができます。
xamppliteを入れたらMingも付属してたのでこれを使っていろいろ遊んでみたいと思います。
と、その前にflashについての簡単なことをまとめておきます。
flash5からActionScriptが使えるようになってゲームが作れるようになったらしいです。 flashの構造は、土台となるSWFMovieオブジェクトを作成して、その上にいろんな部品オブジェクトを貼り付けていくようなイメージです。
例えて言うなら、土台となる自動車に荷台を貼り付けてトラックにしたり、クレーンを貼り付けてクレーン車にしたり、ハシゴを乗っけてハシゴ車にしたりするイメージです。
SWFMovieはその名のとおり、ムービー的に表示させるためのタイムラインを持っています。 なので、SWFMovieに貼り付いてるオブジェクト全体をフレーム単位で刻々と変化させていくことができるということです。
SWFMovieと似ているSWFSprite(ムービークリップとも呼ばれる)は、これ自体がムービーで、独自のタイムラインを持っています。
単純に図形や画像、文字といったものを表示させるだけならflashの必要性があまりないので、flashとして作るからには貼り付けたオブジェクトをフレームごとにいろいろ動かしたり、操作に応じて変化していくものを作ることになると思います。
flashにはActionScriptと呼ばれるコンパクトなプログラム(スクリプト)を含ませることができます。
ActionScriptは、ブラウザでのなんらかのアクション(操作)に応じて行いたい処理を記述しておくためのスクリプトになります。 つまり、単にムービー的な表示以外にゲームのようなインタラクティブな操作をさせたい場合には必須ということになります。
▽ 土台となるムービーを作成してファイル保存する 実行スクリプト [index.php] save('ming01.swf'); // ファイル保存する echo 'done!'; index.phpにアクセスした結果、同じディレクトリ内に"ming01.swf"が作成されていることを確認しましょう。 このファイルをブラウザで見てみます(ドラッグ&ドロップ)。 ちゃんと真っ白い画面が表示されたと思います。 ホントに表示できてるかわかりづらいので、右クリックしてみるとswfファイル独特のプロパティが表示されると思います。 表示結果 ▽ 土台のサイズと背景色を指定する 実行スクリプト [index.php] setDimension(400, 200); // 土台サイズ指定 $swf->setBackground(0, 0, 0); // 土台色指定 $swf->save('ming02.swf'); // ファイル保存 echo 'done!'; 作成された"ming02.swf"を確認してみます。色変わったっしょ 表示結果 ▽ 作成してそのまま表示させる 実行スクリプト [index.php] setDimension(400, 200); // 土台サイズ指定 $swf->setBackground(0, 0, 0); // 土台色指定 // ヘッダーとその内容を送信 header('Content-type: application/x-shockwave-flash'); $swf->output(); 前回まではムービー作成したら保存していました。 今回は作成したムービーを保存せずにそのまま表示させています。 作成したムービーの確認作業の手間を省く為、今後はこちらの方法で作っていきます。
index.phpにアクセスした結果、同じディレクトリ内に"ming01.swf"が作成されていることを確認しましょう。
このファイルをブラウザで見てみます(ドラッグ&ドロップ)。 ちゃんと真っ白い画面が表示されたと思います。 ホントに表示できてるかわかりづらいので、右クリックしてみるとswfファイル独特のプロパティが表示されると思います。
表示結果
作成された"ming02.swf"を確認してみます。色変わったっしょ
前回まではムービー作成したら保存していました。
今回は作成したムービーを保存せずにそのまま表示させています。 作成したムービーの確認作業の手間を省く為、今後はこちらの方法で作っていきます。
▽ まずは1本線を引いてみる 実行スクリプト [index.php] setLine(5, 96, 96, 96); // 線の太さと色指定 $shape->movePenTo(50, 50); // 絶対位置にペンを移動 $shape->drawLineTo(350, 150); // 絶対位置へ線を引く // 土台を準備して図形を貼り付ける $swf = new SWFMovie(); $swf->setDimension(400, 200); $swf->setBackground(128, 128, 255); $swf->add($shape); // 土台に図形を貼り付ける // ヘッダーとその内容を送信 header('Content-type: application/x-shockwave-flash'); $swf->output(); movePen()なら相対位置への移動、drawLine()なら相対位置へ線を引くということもできます。 作成した図形は、SWFムービーのadd()メソッドを使って貼り付けます。 表示結果 ▽ 図形内部を塗りつぶす 実行スクリプト [index.php] setLine(5, 96, 96, 96); // 線の太さと色指定 $fill = $shape->addFill(192, 192, 128); // 塗りつぶす色のオブジェクト取得 $shape->setRightFill($fill); // 右回りで描いた内部を塗りつぶす指定 // 枠線を引く(図形が閉じた時に内部が塗りつぶされる) $shape->movePenTo(200, 50); // 絶対位置にペンを移動 $shape->drawLineTo(350, 150); // 絶対位置へ線を引く $shape->drawLineTo(50, 150); // 絶対位置へ線を引く $shape->drawLineTo(200, 50); // 絶対位置へ線を引く // 土台を準備して図形を貼り付ける $swf = new SWFMovie(); $swf->setDimension(400, 200); $swf->setBackground(128, 128, 255); $swf->add($shape); // 土台に図形を貼り付ける // ヘッダーとその内容を送信 header('Content-type: application/x-shockwave-flash'); $swf->output(); 今度は描画した図形を塗りつぶしています。 塗りつぶしの色はaddFill()メソッドを使ってオブジェクトとして作成し、それをsetRightFill()やsetLeftFill()メソッドに渡す形で塗りつぶします。 右回りに描画された図形はsetRightFill()を使い、左回り描画ならsetLeftFill()メソッドを使って指定します。 表示結果
movePen()なら相対位置への移動、drawLine()なら相対位置へ線を引くということもできます。
作成した図形は、SWFムービーのadd()メソッドを使って貼り付けます。
今度は描画した図形を塗りつぶしています。
文字を描く場合は、まず先にSWFFontを使って使用するフォントオブジェクトを作成する必要があります。 使用できるフォントは、拡張子".fdb"になっている形式のものを使う必要があるので、事前に用意しておきましょう。(「フォント fdb」で検索すれば見つかると思います) わたしは『みかちゃんフォント』をfdb形式に変換済みの配布サイトからいただきました。 実行スクリプト [index.php] setFont($font); // 使用フォント登録 $text->setColor(196, 128, 105); // 文字色指定 $text->setHeight(36); // 文字高さ指定 $text->moveTo(60, 100); // 文字描画位置指定 $text->addUTF8String($s); // 文字を描く // 土台を準備して文字を貼り付ける $swf = new SWFMovie(); $swf->setDimension(400, 200); $swf->setBackground(128, 128, 255); $swf->add($text); // 土台に貼り付ける // ヘッダーとその内容を送信 header('Content-type: application/x-shockwave-flash'); $swf->output(); 使用フォントはSWFFontクラスを使ってフォントオブジェクトにしておきます。 文字オブジェクトのsetFont()メソッドを使って登録する形です。 fdbのパス指定はrealpath()関数を使ってフルパスで渡しています。もし認識できなければCドライブ直下などの浅い階層に置いたりすればイケると思います。 文字コードは必ずUTF−8を使うことになります。 表示結果
文字を描く場合は、まず先にSWFFontを使って使用するフォントオブジェクトを作成する必要があります。
使用できるフォントは、拡張子".fdb"になっている形式のものを使う必要があるので、事前に用意しておきましょう。(「フォント fdb」で検索すれば見つかると思います)
わたしは『みかちゃんフォント』をfdb形式に変換済みの配布サイトからいただきました。
使用フォントはSWFFontクラスを使ってフォントオブジェクトにしておきます。 文字オブジェクトのsetFont()メソッドを使って登録する形です。
fdbのパス指定はrealpath()関数を使ってフルパスで渡しています。もし認識できなければCドライブ直下などの浅い階層に置いたりすればイケると思います。
文字コードは必ずUTF−8を使うことになります。
SWFBitmapというクラス名ではありますが、"jpeg", "gif", "png"といった画像形式に対応しています。 少し前に行った図形塗りつぶしの場合は塗りつぶしの色をオブジェクトにして枠内を塗りつぶすメソッドに渡しましたが、 今回は画像で塗りつぶすように画像オブジェクトを作成して枠内を塗りつぶすメソッドに渡します。 ▽ 画像で枠内を塗りつぶす 実行スクリプト [index.php] addFill($image); // 塗りつぶしオブジェクト作成 $shape->setRightFill($fill); // 枠内を塗りつぶす指定 // 枠線を引く(図形が閉じた時に内部が画像で塗りつぶされる) $w = $image->getWidth(); $h = $image->getHeight(); $shape->movePenTo(50, 50); // 絶対位置にペンを移動 $shape->drawLineTo($w, 50); // 絶対位置へ線を引く $shape->drawLineTo($w, $h); // 絶対位置へ線を引く $shape->drawLineTo(50, $h); // 絶対位置へ線を引く $shape->drawLineTo(50, 50); // 絶対位置へ線を引く // 土台を準備して図形(画像ぬりつぶし)を貼り付ける $swf = new SWFMovie(); $swf->setDimension(400, 200); $swf->setBackground(128, 128, 255); $swf->add($shape); // 土台に図形を貼り付ける // ヘッダーとその内容を送信 header('Content-type: application/x-shockwave-flash'); $swf->output(); 表示結果 これで画像を枠内に貼り付けることができました。 ただ、枠のサイズよりも画像が大きいので入りきれませんでした。 というわけで次に枠の塗りつぶしパターンを変える方法を試みます。 ▽ 画像で枠内を塗りつぶすパターンを変える 塗りつぶしオブジェクトを使うと塗りつぶし方をいろいろ変えることができます。 実行スクリプト [index.php] addFill($image); // 塗りつぶしオブジェクト作成 $fill->moveTo(50, 50); // 画像の開始座標を(150, 200)に指定 $fill->scaleTo(5); // 倍率を指定 //$fill->rotateTo(20); // 20度回転させる指定 //$fill->skewXTo(1.0); // 前方45度に傾ける $shape->setRightFill($fill); // 枠内を塗りつぶす指定 // 枠線を引く $w = $image->getWidth(); $h = $image->getHeight(); $shape->movePenTo(50, 50); // 絶対位置にペンを移動 $shape->drawLineTo($w, 50); // 絶対位置へ線を引く $shape->drawLineTo($w, $h); // 絶対位置へ線を引く $shape->drawLineTo(50, $h); // 絶対位置へ線を引く $shape->drawLineTo(50, 50); // 絶対位置へ線を引く // 土台を準備して図形(画像で塗りつぶされている)を貼り付ける $swf = new SWFMovie(); $swf->setDimension(400, 200); $swf->setBackground(128, 128, 255); $swf->add($shape); // 土台に図形を貼り付ける // ヘッダーとその内容を送信 header('Content-type: application/x-shockwave-flash'); $swf->output(); 塗りつぶしオブジェクトのscaleTo()メソッドを使って倍率を変えることで、大きかった画像全体が入るようにできました。 塗りつぶしオブジェクトにはscaleTo()以外にもmoveTo(), rotateTo(), skewXTo(), skewYTo()といった座標や回転、傾きを指定できるメソッドが用意されています。 scaleTo(X方向, Y方向)という指定もでき、Y方向省略ならX方向に指定した倍率と同じ扱いになります。 今のところよくわからないんですが、指定枠サイズと画像サイズが同じときにscaleTo(20.0)指定で等倍になるような感じです。なので枠の2倍サイズの画像をちょうどぴったり当てはめるにはscaleTo(10.0)で指定することになると思います。 この他にも、addFill()メソッドの第二引数省略時は定数「SWFFILL_TILED_BITMAP」指定扱いになり画像が枠より小さい場合にタイル貼りのように敷き詰めて塗りつぶされますが、定数「SWFFILL_CLIPPED_BITMAP」を指定すればこの塗りつぶしを解除できます。 表示結果 これで、枠線の中を画像で塗りつぶすことができました。
SWFBitmapというクラス名ではありますが、"jpeg", "gif", "png"といった画像形式に対応しています。
少し前に行った図形塗りつぶしの場合は塗りつぶしの色をオブジェクトにして枠内を塗りつぶすメソッドに渡しましたが、 今回は画像で塗りつぶすように画像オブジェクトを作成して枠内を塗りつぶすメソッドに渡します。
これで画像を枠内に貼り付けることができました。
ただ、枠のサイズよりも画像が大きいので入りきれませんでした。 というわけで次に枠の塗りつぶしパターンを変える方法を試みます。
塗りつぶしオブジェクトを使うと塗りつぶし方をいろいろ変えることができます。
塗りつぶしオブジェクトのscaleTo()メソッドを使って倍率を変えることで、大きかった画像全体が入るようにできました。 塗りつぶしオブジェクトにはscaleTo()以外にもmoveTo(), rotateTo(), skewXTo(), skewYTo()といった座標や回転、傾きを指定できるメソッドが用意されています。
scaleTo(X方向, Y方向)という指定もでき、Y方向省略ならX方向に指定した倍率と同じ扱いになります。
今のところよくわからないんですが、指定枠サイズと画像サイズが同じときにscaleTo(20.0)指定で等倍になるような感じです。なので枠の2倍サイズの画像をちょうどぴったり当てはめるにはscaleTo(10.0)で指定することになると思います。
この他にも、addFill()メソッドの第二引数省略時は定数「SWFFILL_TILED_BITMAP」指定扱いになり画像が枠より小さい場合にタイル貼りのように敷き詰めて塗りつぶされますが、定数「SWFFILL_CLIPPED_BITMAP」を指定すればこの塗りつぶしを解除できます。
これで、枠線の中を画像で塗りつぶすことができました。
これまでいろいろなタイプのオブジェクトを土台(SWFMovieオブジェクト)に貼り付けてきました。 ただ貼り付けただけなので、図形や文字といったオブジェクトは静止したまま微動だにしませんでした。 貼り付ける時にadd()メソッドを使っていましたが、このメソッドは返り値としてSWFDisplayItemオブジェクトを返すようになっています。 この返ってきたSWFDisplayItemオブジェクトには、move()やrotate()といった動きを与えられるメソッドを指定できるのでこれを使って、貼り付けたオブジェクトを動かしてみましょう。 ▽ SWFDisplayItemを取得して部品を動かす 実行スクリプト [index.php] addFill($image); // 塗りつぶしオブジェクト作成 $fill->moveTo(0, 0); // 画像の開始座標を(150, 200)に指定 $fill->scaleTo(10); // 倍率を指定 $shape->setRightFill($fill); // 枠内を塗りつぶす指定 // 枠線を引く $w = $image->getWidth(); $h = $image->getHeight(); $shape->movePenTo(40, 0); // 絶対位置にペンを移動 $shape->drawLineTo($w, 0); // 絶対位置へ線を引く $shape->drawLineTo($w, $h); // 絶対位置へ線を引く $shape->drawLineTo(40, $h); // 絶対位置へ線を引く $shape->drawLineTo(40, 0); // 絶対位置へ線を引く // 土台を準備して図形(画像で塗りつぶされている)を貼り付ける $swf = new SWFMovie(); $swf->setDimension(400, 200); $swf->setBackground(128, 128, 255); $d = $swf->add($shape); // 土台に図形を貼り付けSWFDisplayItemオブジェクトを取得 $swf->setRate(6); // 1秒当たりのフレーム数指定 $deg = 5; for ($i=0; $i<60; $i++,$deg*=-1) { $swf->nextFrame(); // 新たなフレームへ移動 $d->move(2, 1); // 指定位置へ移動 $d->rotate($deg); // 指定角度ずらす } // ヘッダーとその内容を送信 header('Content-type: application/x-shockwave-flash'); $swf->output(); 1つの静止画を1フレームだとすると、ムービー(動画)はフレームが次々に変わっていくものと考えることができます。 なのでsetRate()メソッドを使って、1秒当たりのフレーム(コマ)数を設定し、nextFrame()でフレームを順送りにすることでムービーを実現しています。 表示結果 この辺からようやくflashを使う意味(醍醐味)が出てくると思います。 ▽ SWFSpriteでも動かす これまで土台にしてきたSWFMovieがあるわけですが、前回はこれだけで動きを与えることをしました。 もう一つSWFMovieと似たようなものにSWFSprite(ムービークリップとも呼ばれる)というクラスがあり、これもまた貼り付けたオブジェクトに動きを与えることができるようになっています。 スプライトと言えば日本ではおいしい飲み物の意味ですが、アメリカ近辺ではどうやらコンピュータ用語で『表示画面のイメージパターン』という意味らしいです。 SWFSpriteに貼り付けたオブジェクトを動かして、更に 土台(SWFMovie)に貼り付けたSWFSpriteオブジェクトを動かせば二重の動きを与えることになります。 これができれば複雑な動きでも比較的簡単に作り出すことができそうです。 実行スクリプト [index.php] setDimension(W_SIZE, H_SIZE); $swf->setBackground(128, 128, 255); $swf->setRate(6); // 1秒当たりのフレーム数指定 for ($i=0; $iadd($sprite[$i]); // 土台に貼り付けSWFDisplayItemオブジェクトを取得 $d[$i]->moveTo(rand(0, W_SIZE), rand(0, H_SIZE)); // 初期位置を指定 } for ($i=0; $i<60; $i++) { $swf->nextFrame(); // 新たなフレームへ移動 for ($j=0; $jmove(rand(-2, 2), rand(-2, 2)); // 指定位置へ移動 } } // ヘッダーとその内容を送信 header('Content-type: application/x-shockwave-flash'); $swf->output(); /** * ランダムな四角を描画してSWFSpriteに貼り付けて返す */ function randomrect() { $bold = rand(1, 5); list($r, $g, $b) = array(rand(0, 255), rand(0, 255), rand(0, 255)); $w = rand(5, 50); $h = rand(5, 50); $shape = new SWFShape(); $shape->setLine($bold, $r, $g, $b); // 線の太さと色RGB設定 $shape->movePenTo(0, 0); // (0, 0)座標にペンを置く $shape->drawLineTo($w, 0); // 絶対位置へ線を引く $shape->drawLineTo($w, $h); // 絶対位置へ線を引く $shape->drawLineTo(0, $h); // 絶対位置へ線を引く $shape->drawLineTo(0, 0); // 絶対位置へ線を引く $sprite = new SWFSprite(); $d = $sprite->add($shape); // SWFDisplayItemオブジェクトを取得 for ($i=0,$type=rand(-1,1); $i<90; $i++) { $sprite->nextFrame(); $d->rotate(rand(1, 60) * $type); // 回転させる } return $sprite; } ランダムな四角形を作成してSWFSpriteに貼り付けるまではいくつ作ろうとも同じ作業になるので関数化しました。 表示結果 どうでしょう。これだけ複雑な動きをごく少ないコードで作成できました。
これまでいろいろなタイプのオブジェクトを土台(SWFMovieオブジェクト)に貼り付けてきました。 ただ貼り付けただけなので、図形や文字といったオブジェクトは静止したまま微動だにしませんでした。
貼り付ける時にadd()メソッドを使っていましたが、このメソッドは返り値としてSWFDisplayItemオブジェクトを返すようになっています。
この返ってきたSWFDisplayItemオブジェクトには、move()やrotate()といった動きを与えられるメソッドを指定できるのでこれを使って、貼り付けたオブジェクトを動かしてみましょう。
1つの静止画を1フレームだとすると、ムービー(動画)はフレームが次々に変わっていくものと考えることができます。
なのでsetRate()メソッドを使って、1秒当たりのフレーム(コマ)数を設定し、nextFrame()でフレームを順送りにすることでムービーを実現しています。
この辺からようやくflashを使う意味(醍醐味)が出てくると思います。
これまで土台にしてきたSWFMovieがあるわけですが、前回はこれだけで動きを与えることをしました。
もう一つSWFMovieと似たようなものにSWFSprite(ムービークリップとも呼ばれる)というクラスがあり、これもまた貼り付けたオブジェクトに動きを与えることができるようになっています。
スプライトと言えば日本ではおいしい飲み物の意味ですが、アメリカ近辺ではどうやらコンピュータ用語で『表示画面のイメージパターン』という意味らしいです。
SWFSpriteに貼り付けたオブジェクトを動かして、更に 土台(SWFMovie)に貼り付けたSWFSpriteオブジェクトを動かせば二重の動きを与えることになります。
これができれば複雑な動きでも比較的簡単に作り出すことができそうです。
ランダムな四角形を作成してSWFSpriteに貼り付けるまではいくつ作ろうとも同じ作業になるので関数化しました。
どうでしょう。これだけ複雑な動きをごく少ないコードで作成できました。
今度は土台にボタンを追加して、押された時の挙動を指定する方法です。 挙動を指定するので、当然ActionScriptの出番となります。 ボタン上に貼り付けられるのは図形オブジェクトだけなので図形を描画するか、図形で描いた枠内を画像で塗りつぶしたものになります。 実行スクリプト [index.php] array(51, 0, 0), 'over' => array(64, 64, 64), 'down' => array(128, 128, 128), 'hit' => array(192, 192, 192)); // グラデーション塗りつぶし用 $grad = new SWFGradient(); $grad->addEntry(0, 0x33, 0, 0); $grad->addEntry(1.0, 0xff, 0xff, 0xff); // 画像塗りつぶし用 $image = new SWFBitmap($fp=fopen("./magick.jpg", "rb")); fclose($fp); // フォントを用意 $font = new SWFFont(realpath('./mikachan.fdb')); // ボタン作成 $btn = new btn(array('width'=> $width, 'height'=> $height, 'fill'=> $image, 'font' => $font)); $btn1 = $btn->make('Google', 'getURL("http://www.google.co.jp/", "_blank");', 0, $height * 0); $btn2 = $btn->make('Yahoo!', 'getURL("http://www.yahoo.co.jp/", "_blank");', 0, $height * 1); $btn3 = $btn->make('goo', 'getURL("http://www.goo.ne.jp/", "_blank");', 0, $height * 2); $btn4 = $btn->make('背景を画像に', null, 0, $height * 3); $btn5 = $btn->make('日本語表示', null, 0, $height * 4); $btn6 = $btn->make('テスト', null, 0, $height * 5); $btn->setParam(array('font_align' => 10)); // 左から10の位置指定 $btn7 = $btn->make('文字を左寄せ', null, $width+5, $height * 0); $btn8 = $btn->make('文字を左寄せ', null, $width+5, $height * 1); $btn9 = $btn->make('文字を左寄せ', null, $width+5, $height * 2); $btn10 = $btn->make('文字を左寄せ', null, $width+5, $height * 3); $btn11 = $btn->make('文字を左寄せ', null, $width+5, $height * 4); $btn12 = $btn->make('文字を左寄せ', null, $width+5, $height * 5); $btn->setParam(array('fill' => $fill)); // 単色塗りつぶし $btn13 = $btn->make('色が変わるボタン', null, $width*2+10, $height * 0); $btn->setParam(array('font_height' => 16)); $btn14 = $btn->make('文字を小さくする', null, $width*2+10, $height * 1); $btn->setParam(array('fill' => $grad)); // グラデーション塗りつぶし $btn15 = $btn->make('グラデーション', null, $width*2+10, $height * 2); $btn->setParam(array('font_color' => array(255, 96, 96))); $btn16 = $btn->make('文字色を変える', null, $width*2+10, $height * 3); $btn->setParam(array('grad_opt'=>SWFFILL_RADIAL_GRADIENT)); $btn17 = $btn->make('グラデーション方式を変える', null, $width*2+10, $height * 4); $btn->setParam(array('line_width' => 5, 'line_color' => array(255, 0, 128))); $btn18 = $btn->make('枠色と太さを変える', null, $width*2+10, $height * 5); // ボタンを貼り付ける $swf = new SWFMovie(); $swf->setDimension($width * 3 + 10, $height * 6 + 10); $swf->setBackground(128, 128, 255); $swf->add($btn1); $swf->add($btn2); $swf->add($btn3); $swf->add($btn4); $swf->add($btn5); $swf->add($btn6); $swf->add($btn7); $swf->add($btn8); $swf->add($btn9); $swf->add($btn10); $swf->add($btn11); $swf->add($btn12); $swf->add($btn13); $swf->add($btn14); $swf->add($btn15); $swf->add($btn16); $swf->add($btn17); $swf->add($btn18); // ヘッダーとその内容を送信 header('Content-type: application/x-shockwave-flash'); $swf->output(); class btn { var $width = 200; // ボタン幅の初期値 var $height = 36; // ボタン高さの初期値 var $fill = null; // 塗りつぶしオブジェクトarray(r,g,b) or Gradient or Bitmap var $font = null; // フォントオブジェクト var $font_color = array(0, 0, 0); var $font_height= 20; var $font_align = 'center'; // 文字寄せ(center か左スペース値) var $line_width = 1; // 枠線の太さ var $line_color = array(0, 0, 0); // 枠線の色 var $putx = 0; // ボタン描画位置X var $puty = 0; // ボタン描画位置Y var $bitmap_opt = null; // SWFFILL_TILED_BITMAP or SWFFILL_CLIPPED_BITMAP var $grad_opt = null; // SWFFILL_LINEAR_GRADIENT or SWFFILL_RADIAL_GRADIENT function btn($array=array()) { // コンストラクタ $this->setParam($array); } function setParam($array=array()) { // 属性設定用メソッド foreach ($array as $key => $value) $this->$key = $value; } function make($label='', $actionScript='', $putx=0, $puty=0) { $this->putx = $putx; $this->puty = $puty; $btn = new SWFButton(); // ボタンオブジェクト作成 // ボタン枠および塗りつぶし if (is_array($this->fill)) { $btn->addShape($this->rect($this->fill['up']), SWFBUTTON_UP); $btn->addShape($this->rect($this->fill['over']), SWFBUTTON_OVER); $btn->addShape($this->rect($this->fill['down']), SWFBUTTON_DOWN); $btn->addShape($this->rect($this->fill['hit']), SWFBUTTON_HIT); } else $btn->addShape($this->rect($this->fill), SWFBUTTON_UP | SWFBUTTON_OVER | SWFBUTTON_DOWN | SWFBUTTON_HIT); // ActionScript if (!empty($actionScript)) $btn->addAction(new SWFAction($actionScript), SWFBUTTON_MOUSEUP); // 文字入れ if ($label !== '' && $this->font !== null) { $text = new SWFText(); $text->setFont($this->font); $text->setColor($this->font_color[0], $this->font_color[1], $this->font_color[2]); $text->setHeight($this->font_height); $label = mb_convert_encoding($label, "UTF-8", "SJIS-win,CP51932,UTF-8"); $f_x= intval(($this->width - $text->getUTF8Width($label))/2); $f_y= intval(($this->height - $this->font_height)/2); if ($f_x < 0) $f_x = 0; $f_x += $this->putx; if ($f_y < 0) $f_y = 0; $f_y += $this->puty + $this->font_height; if ($this->font_align !== 'center') $f_x= $this->putx + $this->font_align; $text->moveTo($f_x, $f_y); $text->addUTF8String($label); $btn->addShape($text, SWFBUTTON_OVER | SWFBUTTON_UP | SWFBUTTON_DOWN); } return $btn; // 結果のボタンオブジェクトを返す } // 枠と塗りつぶし function rect($fill) { $shape = new SWFShape(); if (is_array($fill)) $shape->setRightFill($fill[0], $fill[1], $fill[2]); elseif (get_class($fill) === 'SWFBitmap') { if (empty($this->bitmap_opt)) $shape->setRightFill($shape->addFill($fill)); else $shape->setRightFill($shape->addFill($fill, $this->bitmap_opt)); } else { if (empty($this->grad_opt)) $shape->setRightFill($shape->addFill($fill)); else $shape->setRightFill($shape->addFill($fill, $this->grad_opt)); } if ($this->line_width) $shape->setLine($this->line_width - 1, $this->line_color[0], $this->line_color[1], $this->line_color[2]); $shape->movePenTo($this->putx, $this->puty); $shape->drawLine($this->width, 0); $shape->drawLine(0, $this->height); $shape->drawLine(-$this->width, 0); $shape->drawLine(0, -$this->height); return $shape; // 結果の図形オブジェクトを返す } } ボタン塗りつぶし用に今回初めてSWFGradientクラスを使ってグラデーションを描いてみました。 このグラデーションはデフォルトの「SWFFILL_LINEAR_GRADIENT」の他に「SWFFILL_RADIAL_GRADIENT」指定が使えるので2種類のグラデーションを使うことができます。 あとは単色(クリックやマウスオーバー時に色を変えるもの)と画像での塗りつぶしを使っています。 いろんなボタンを作るため、属性をちょいちょい変えていってそれを保持できるようにボタン作成部分はクラス化しています。 btn::make()の第二引数に書いたgetURL()がActionScriptのコードになります。これを記述したボタンをクリックすると指定URLへ飛べるようになります。 ちょっとコード量が増えてしまいましたが、ボタン表面の塗りつぶし方、ActionScriptを使ってボタンに動きを付けるやり方はこんな感じでできました。 ここで一つ大事なことがあります。 ボタン表面の塗りつぶしや背景などに使用する画像で同じものを共有する場合に、使用する度にオブジェクトを作成(new SWFBitmap)してしまうと、その度に画像が取り込まれることになるので最終的なswfファイル容量が膨れ上がってしまいます。 再利用する画像は外にくくり出して1度のオブジェクト作成で済ませるようにしましょう。 表示結果 表示はこんな感じになりました。 「Google」「Yahoo!」「goo」の3つのボタンだけActionScriptでそのサイトが開くように記述しています。 ボタン18個を作成しましたが、これでswfファイル容量は24.3KBに収めることができました。 画像ボタンを個々に18個用意するよりもコンパクトだと思います。flash恐るべしですね。
今度は土台にボタンを追加して、押された時の挙動を指定する方法です。
挙動を指定するので、当然ActionScriptの出番となります。
ボタン上に貼り付けられるのは図形オブジェクトだけなので図形を描画するか、図形で描いた枠内を画像で塗りつぶしたものになります。
ボタン塗りつぶし用に今回初めてSWFGradientクラスを使ってグラデーションを描いてみました。 このグラデーションはデフォルトの「SWFFILL_LINEAR_GRADIENT」の他に「SWFFILL_RADIAL_GRADIENT」指定が使えるので2種類のグラデーションを使うことができます。 あとは単色(クリックやマウスオーバー時に色を変えるもの)と画像での塗りつぶしを使っています。
いろんなボタンを作るため、属性をちょいちょい変えていってそれを保持できるようにボタン作成部分はクラス化しています。
btn::make()の第二引数に書いたgetURL()がActionScriptのコードになります。これを記述したボタンをクリックすると指定URLへ飛べるようになります。
ちょっとコード量が増えてしまいましたが、ボタン表面の塗りつぶし方、ActionScriptを使ってボタンに動きを付けるやり方はこんな感じでできました。
ここで一つ大事なことがあります。 ボタン表面の塗りつぶしや背景などに使用する画像で同じものを共有する場合に、使用する度にオブジェクトを作成(new SWFBitmap)してしまうと、その度に画像が取り込まれることになるので最終的なswfファイル容量が膨れ上がってしまいます。 再利用する画像は外にくくり出して1度のオブジェクト作成で済ませるようにしましょう。
表示はこんな感じになりました。 「Google」「Yahoo!」「goo」の3つのボタンだけActionScriptでそのサイトが開くように記述しています。
ボタン18個を作成しましたが、これでswfファイル容量は24.3KBに収めることができました。 画像ボタンを個々に18個用意するよりもコンパクトだと思います。flash恐るべしですね。