Yuichi: 2008年6月アーカイブ

いつの間にか(日本の)Yahoo!ウィジェットエンジンが4.5になっていましたよ。(6月10日かららしい)
米Yahoo!では去年11月にリリースされていたものですが、ウィジェットエンジン4.5からは
Flashを埋め込んだり出来るようになっています。
Flasher, ASerもぐっとウィジェット開発しやすくなるかと。

AIRにも頑張ってほしいけど、一般ユーザーの知名度としては完全に Yahoo > Adobeでしょうからね。
Yahooウィジェットもまだ普及してる感はないですが、このままだとライトユーザー向け市場もっていかれるかも。

AIRは毎度インストールという形をとらざるを得ないので、そこが既に敷居が高いなあと。(そんな話をどこかの懇親会でした気もする)
軽めのソフトはAIRガジェット(妄想)で、みたいにならないかなと。

yahooウィジェット
前回エントリのサンプルでも一部使用していますが、AlivePDFにはページ要素を追加するための
メソッドが色々用意されています。今回はその一部を紹介したいと思います。

テキスト関係(今のところ日本語対応には対応していないようです ※埋め込みフォントの対応は実装予定にある模様)
addText() - テキストの追加
addTextNote() - 注釈の追加
addMultiCell() - マルチセルの追加 ※マルチセルって日本語でいうとなんだろ...
setFont() - fontの指定 ※今のところ使えるフォントが数種類に制限されています

図形関係(Graphicsの各種メソッドと似ているものも多いです)
beginFill() - 塗りの色指定
drawCircle() - 円描画
drawPolygone() - 多角形描画
etc...
色指定
RGBColor, CMYKColor

画像
addImageStream() - 画像描画 ※引数でbyteArrayを指定します

画面効果(フルスクリーン時の画面効果)
addTransition() - 画面効果の追加
効果の種類の指定
Transition.WIPE, Transition.DISSOLVE, Transition.BOX, などなど

適当にページ・ページの要素が確認できるようなサンプルを作ってみました。
前回と同様AIRプロジェクトとして作成しています。

今回のサンプル
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Text id="txt" x="10" y="10" width="200"/>
	<mx:Button label="Generate PDF" click="generatePDF(event)" x="10" y="30"/>
	<mx:Script>
		<![CDATA[
			import org.alivepdf.fonts.Style;
			import org.alivepdf.transitions.MotionDirection;
			import org.alivepdf.transitions.TransitionDirection;
			import org.alivepdf.transitions.Dimension;
			import org.alivepdf.transitions.Transition;
			import org.alivepdf.colors.RGBColor;
			import org.alivepdf.images.ImageFormat;
			import org.alivepdf.pages.Page;
			import org.alivepdf.events.ProcessingEvent;
			import org.alivepdf.fonts.FontFamily;
			import org.alivepdf.saving.Method;
			import org.alivepdf.layout.Size;
			import org.alivepdf.layout.Unit;
			import org.alivepdf.layout.Orientation;
			import org.alivepdf.pdf.PDF;
			[Embed( source="01.jpg", mimeType="application/octet-stream" )]
			private var Jpg01:Class;
			private var myPDF:PDF;
			public function generatePDF(event:MouseEvent):void {
				myPDF = new PDF(Orientation.PORTRAIT, Unit.MM, Size.A4);
				myPDF.addEventListener(ProcessingEvent.COMPLETE, completeHandler);
				myPDF.setFont(FontFamily.ARIAL, Style.BOLD, 18);
				
				myPDF.addPage();
				myPDF.addText("page 1", 20, 20);
				myPDF.addText("PDF generation test!", 20, 40);
				myPDF.addTextNote(170, 20, 50, 30, "Note!");
				myPDF.addTransition(Transition.FLY, 1, Dimension.HORIZONTAL);
				
				myPDF.addPage();
				myPDF.addText("page 2", 20, 20);
				myPDF.setFont(FontFamily.COURIER);
				myPDF.addMultiCell(100, 80, "multicell", 1);
				myPDF.addImageStream(new Jpg01() as ByteArray, 20, 160);
				myPDF.addTransition(Transition.GLITTER, 1, Dimension.HORIZONTAL);
				
				myPDF.addPage();
				myPDF.setFont(FontFamily.ARIAL, Style.BOLD, 18);
				myPDF.addText("page 3", 20, 20);
				myPDF.beginFill(new RGBColor(0xffcc00));
				myPDF.drawRect(new Rectangle(50, 50, 60, 110));
				myPDF.endFill();
				myPDF.addTransition(Transition.COVER, 1, Dimension.HORIZONTAL);
				
				myPDF.addPage();
				myPDF.addText("page 4", 20, 20);
				myPDF.beginFill(new RGBColor(0xccff00));
				myPDF.drawCircle(105, 148, 85);
				myPDF.endFill();
				myPDF.addTransition(Transition.SPLIT, 1, Dimension.HORIZONTAL);
				
				try {
					var stream:FileStream = new FileStream();
					var file:File = File.desktopDirectory.resolvePath("pdf/generate3.pdf");
					stream.open(file, FileMode.WRITE);
					var bytes:ByteArray = myPDF.save(Method.LOCAL);
					stream.writeBytes(bytes);
				} catch(e:Error) {
					txt.text = "ファイルをオープン出来ません"
				} finally {
					stream.close();
				}
			}
			private function completeHandler(event:ProcessingEvent):void {
				txt.text = "PDF生成終了";
			}
			
		]]>
	</mx:Script>
</mx:WindowedApplication>

こちらが実際に生成されたPDFファイルです。Adobe Readerで全画面再生すると、画面効果も確認できるかと思います。
AlivePDFとは...
  • as3用のPDF生成用ライブラリ
  • 公式サイトは http://www.alivepdf.org/
  • ライセンスはMIT License
  • 現在の最新バージョンは 0.1.4.3
公式サイトにビデオチュートリアルがあってすごい親切です。※ ただ、0.1.4.3だと一部書き換えないとコンパイル失敗しますが.

ひとまずチュートリアル見ながら、簡単な流れがわかるサンプルを作ってみました。
※PDFをローカル保存する為、flexbuilderのAIRプロジェクトで作成しています。

作成したサンプルのソース
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Text id="txt" x="10" y="10" width="200"/>
    <mx:Button label="Generate PDF" click="generatePDF(event)" x="10" y="30"/>
    <mx:Script>
        <![CDATA[
            import org.alivepdf.images.ImageFormat;
            import org.alivepdf.pages.Page;
            import org.alivepdf.events.ProcessingEvent;
            import org.alivepdf.fonts.FontFamily;
            import org.alivepdf.saving.Method;
            import org.alivepdf.layout.Size;
            import org.alivepdf.layout.Unit;
            import org.alivepdf.layout.Orientation;
            import org.alivepdf.pdf.PDF;
            [Embed( source="01.jpg", mimeType="application/octet-stream" )]
            private var Jpg01:Class;
            private var myPDF:PDF;
            public function generatePDF(event:MouseEvent):void {
                myPDF = new PDF(Orientation.PORTRAIT, Unit.MM, Size.A4);
                myPDF.addEventListener(ProcessingEvent.COMPLETE, completeHandler);
                myPDF.setFont(FontFamily.ARIAL);
                myPDF.addPage();
                myPDF.addText("PDF generation test!", 20, 20);
                myPDF.addPage(new Page(Orientation.LANDSCAPE, Unit.MM, Size.A4));
                myPDF.addText("page 2", 20, 20);
                myPDF.addImageStream(new Jpg01() as ByteArray, 20, 60);
                try {
                    var stream:FileStream = new FileStream();
                    var file:File = File.desktopDirectory.resolvePath("pdf/generate2.pdf");
                    stream.open(file, FileMode.WRITE);
                    var bytes:ByteArray = myPDF.save(Method.LOCAL);
                    stream.writeBytes(bytes);
                } catch(e:Error) {
                    txt.text = "ファイルをオープン出来ません"
                } finally {
                    stream.close();
                }
            }
            private function completeHandler(event:ProcessingEvent):void {
                txt.text = "PDF生成終了";
            }
           
        ]]>
    </mx:Script>
</mx:WindowedApplication>
サンプルの流れ
まずnew PDF()でPDFクラスのインスタンス作成。
引数で用紙方向、サイズなどを指定します。

Orientation - 用紙方向
PORTRAIT - 縦長
LANDSCAPE - 横長

Unit - 単位
CM, INCH, MM, POINT

Size - サイズ(まんま)
A4, A5, etc...

addEventListner してあげるとpage追加や生成終了などのイベントを拾えます
 -> ProcessingEvent

addPage() でページを追加
addText(),addImageStream()などでページの要素を追加していきます

save()でバイナリデータ化して
filestreame.writeBytes()でファイルへの書き込み処理をします

割と簡単ですね!

(今回のエントリーはちょい絶vol.4の発表ネタをそのまま公開しています)
カスタムイベントつくってた時に嵌ったのでメモ。

カスタムイベントクラス内で以下のように定義
public static const ALL_COMPLETE:String = "allComplete";

コンパイルすると
"TypeError: Error #1034: 強制型変換に失敗しました。flash.events::Event@10c1101 を CustomEvent に変換できません。" 
と怒られまくる。

public static const ALL_COMPLETE:String = "allCompletes";
と書くと問題ない。

すげー悩みましたよ orz

海外のブログによるとplayer  9.0.115限定っぽいのかな?

(追記 2008/6/12 23:56)最新のSA debugPlayerでもエラーでました。
恐らくASer必携の書になるであろう「FLASH OOP for ActionScript 3.0」の予約がAmazonで始まっていたよ。速攻ポチりました。
内容が知りたいかたはhttp://cs3book.flashoop.jp/wiki/ をみるとよいかも?

Kuler_api_50px.jpg

だいぶ前に名古屋でやっている勉強会で見せたネタなんですが、最近ちょっと手直ししたのでようやく公開です。

kuler API を使って カラーテーマを取得しているので結構綺麗な花火があがると思います。
2009.05.08追記
kuler apiの仕様変更があったのに気づかず、長らく放置していたものを修正しました;