Flexのvkontakteのような写真アップローダー

1週間前、アクションスクリプトに関する私の知識は、バナーネットワークにアップロードする前にonclickイベントをバナーに追加する方法に限定されていました。 ファイルローダーとしてswfuploadを使用しましたが、swfのニックネームを取得してコードを理解したくありませんでした。 私はフラッシュが好きではありません。私はデザイナーではないので、これらすべてのレイヤー、フレーム、星を描くためのツール、モーションガイドを見ると迷子になります。



それから私はこの驚くほど美しいものに出会い、 フレックスがあることを知りました。 私のような超初心者でも、数日のうちにゼロから写真ダウンローダーを作成し、クライアントでサイズを変更し、 vkontakte.ruで使用したものとほぼ同じアップロードバーを作成できたため、このフレックスはクールです



写真をアップロードするためにフラッシュを使用することに決めた理由は3つあります。 これらは、FileReference、FileReferenceList、およびflash.display.Bitmapです。 Flash Playerの10番目のバージョンでは、FileReferenceがload()関数を導入しました。この関数を使用すると、サーバーにダウンロードせずに、ビデオ内の選択した写真をローカルで表示できます。 FileReferenceListを使用すると、ファイルダイアログのシフトダイアログを使用して、複数の写真を一度に選択できます。 ビットマップは、サーバーに送信する前に画像のサイズを変更します。 これをすべて純粋なjavascriptで行うことはできません。



そのため、フレックスのvkontakteとして写真ダウンローダーを作成します(初心者向けのステップバイステップガイド)。



まず、フレックスビルダー3(60日間使用できるバージョンがあります)をインストールし、フラッシュプレーヤーをバージョン10に更新する必要があります。 新しいflexプロジェクトを作成します。 アプリケーションタイプはWebアプリケーションで、サーバータイプはなしです。 すぐにプロジェクトコンパイラを修正する必要があります。これを行うには、[プロジェクト]-> [プロパティ]-> [Flexコンパイラ]を選択し、[Flash Playerバージョンが必要]パラメーターを10.0.0に変更します。 これを行わないと、FileReferenceオブジェクトのload()関数は機能しません。



まず、ページに必要なすべての要素を配置してから、スクリプトを作成します。 ワークスペース(アプリケーションタグ)の固定寸法を設定し、パネルをTileList、ProgressBar、およびControlBarの内側に、「写真を選択」、「アップロードを開始」、「クリア」のボタンで配置します。 TileListの後に、ProgressBar要素とキャンセルボタンを持つHBoxを追加します。 結果は次のとおりです。

<? xml version ="1.0" encoding ="utf-8" ? >

< mx:Application xmlns:mx ="http://www.adobe.com/2006/mxml" layout ="absolute" width ="540" height ="465" >



< mx:Panel title =" "

paddingTop ="10" paddingLeft ="10" paddingBottom ="10" paddingRight ="10"

width ="100%" height ="100%" >



< mx:TileList

alternatingItemColors ="[#FFFFFF,#CCCCCC,#AAAAAA]"

verticalScrollPolicy ="on"

columnWidth ="120" columnCount ="4" rowHeight ="110" rowCount ="3" />



< mx:HBox horizontalAlign ="center" width ="100%" >

< mx:ProgressBar />

< mx:Button label ="" />

</ mx:HBox >



< mx:ControlBar horizontalAlign ="right" >

< mx:Button label =" " />

< mx:Button label =" " />

< mx:Button label ="" />

</ mx:ControlBar >

</ mx:Panel >

</ mx:Application >




* This source code was highlighted with Source Code Highlighter .












ProgressBarを非表示にし、「アップロードの開始(visible = "false")ボタンをクリックしたときにのみ表示します。enabled= "false"ボタンの "アップロードの開始とクリア"(写真のリストが空でない場合にのみアクティブになります。)すべての重要な要素にID shniki。



<mx:Script>タグを追加して、その中にコードを記述します。 flash.net.FileReferenceListとmx.collections.ArrayCollectionを接続し、ArrayCollectionタイプのメインのグローバル変数photosを設定します。

< mx:Script >

<! [CDATA[



import flash.net.FileReferenceList;

import mx.collections.ArrayCollection;



[Bindable]

private var photos:ArrayCollection = new ArrayCollection;



]] >

</ mx:Script >




* This source code was highlighted with Source Code Highlighter .






[バインド可能]は、photos変数を他の要素に関連付けることができることを意味します。 TileListのdataProviderとして指定すると、photos配列のすべての変更がTileListに自動的に反映されます。



FileReferenceList型のグローバル変数frListを追加します。 [写真の選択]ボタンをクリックして、selectPhotos関数を追加します。 ファイルダイアログのfrList.browse()で写真の選択が完了したときにイベントをキャッチするには、addEventListener(Event.COMPLETE、addPhotos)をfrListに追加します。 frList.browse()関数のオプションのパラメーターは、FileFilterタイプのオブジェクトの配列で、ファイル名のマスクを指定できます。 最後に、addPhotos関数を作成します。この関数は、frList.fileListで選択されたすべてのファイルを繰り返し処理し、それらを写真配列に追加します。 結果は次のとおりです。

import mx.events.CollectionEvent;

import flash.net.FileReferenceList;

import mx.collections.ArrayCollection;



[Bindable]

private var photos:ArrayCollection = new ArrayCollection;

private var frList:FileReferenceList = new FileReferenceList;



private function init(): void

{

frList.addEventListener(Event.SELECT,addPhotos);

}



private function selectPhotos(): void

{

frList.browse([ new FileFilter( " jpeg" , "*.jpg;*.jpeg" )]);

}



private function addPhotos(): void

{

for ( var i: uint = 0; i < frList.fileList.length; i++)

{

var elem:Object = new Object;

elem.fr:FileReference = FileReference(frList.fileList[i]);

photos.addItem(elem);

}

}



* This source code was highlighted with Source Code Highlighter .






写真の配列が空でない場合にのみ、[ダウンロードの開始]ボタンと[キャンセル]ボタンをアクティブにする必要があります。 初期化関数にハンドラーを追加します。

photos.addEventListener(CollectionEvent.COLLECTION_CHANGE,function()

{

startUploadButton.enabled = (photos.length>0);

clearPhotosButton.enabled = (photos.length>0);

});



* This source code was highlighted with Source Code Highlighter .






次に、TileListのitemRendererを記述します。 itemRendererは、TileListセルに写真配列の要素を表示する方法を担当します。 itemRendererコードを別のMXMLコンポーネントに配置します。 キャンバスの幅120高さ110に基づいて、ファイル->新規-> photoThumbという名前のMXMLコンポーネントを作成します。TileListで、itemThenderプロパティに値photoThumbを追加します。



次に、コンポーネントコードを記述します。 各写真にカーソルを合わせると、コントロールボタンが付いたパネルが表示されます(これまでのところ、「削除」ボタンは1つしかありません)。 itemRendererが呼び出される対応する配列要素は、グローバルデータ変数にあります。 私たちの場合、そのような各要素は、FileReference型の単一のfrプロパティを持つオブジェクトです。 したがって、セルにファイル名を指定するには、<mx:Label text = "{data.fr.name}" />と記述する必要があります。 親パブリック関数は、parentDocumentを介して呼び出されます。 完全なitemRendererコードを次に示します。親Canvasの背景は、rollOverが正しく処理されるように設定されています。

<? xml version ="1.0" encoding ="utf-8" ? >

< mx:Canvas xmlns:mx ="http://www.adobe.com/2006/mxml"

width ="120" height ="110"

backgroundColor ="#FFFFFF" backgroundAlpha ="0"

rollOver ="{controls.visible=true}" rollOut ="{controls.visible=false}" >



< mx:VBox width ="100%" height ="75" y ="5" horizontalAlign ="center" >

< mx:Image source ="{data.fr.data}" maxWidth ="100" maxHeight ="75" horizontalAlign ="center" verticalAlign ="middle" />

</ mx:VBox >

< mx:Label text ="{data.fr.name}" width ="100%" truncateToFit ="true" bottom ="0" textAlign ="center" />



< mx:VBox id ="controls" visible ="false" y ="65" right ="10" horizontalAlign ="right" >

< mx:Button label ="X" click ="parentDocument.clearPhoto(data)" fontSize ="6" width ="30" height ="15" />

</ mx:VBox >

</ mx:Canvas >




* This source code was highlighted with Source Code Highlighter .






大きな写真を選択する場合、ロードする時間がなく、TileListはそれらを表示しないことを除いて、すべてが機能します。 これを修正するには、各写真をロードした後にTileList更新をaddPhotos関数に追加します。

private function addPhotos(e:Event): void

{

for ( var i: uint = 0; i < frList.fileList.length; i++)

{

var elem:Object = new Object;

elem.fr = FileReference(frList.fileList[i]);

elem.fr.load();

elem.fr.addEventListener(Event.COMPLETE,refreshThumb);

photos.addItem(elem);

}

}



private function refreshThumb(e:Event): void

{

photosList.invalidateList();

}




* This source code was highlighted with Source Code Highlighter .






ArrayCollectionクラスのremoveAll、removeItemAtおよびgetItemIndexメソッドを使用して、すべての写真を削除し、選択した写真を削除する簡単な関数を追加します。 この場合、itemRenderから呼び出される関数はパブリックでなければなりません。

private function clearPhotos(): void

{

photos.removeAll();

}



public function clearPhoto(data:Object): void

{

photos.removeItemAt(photos.getItemIndex(data));

}



* This source code was highlighted with Source Code Highlighter .






この段階で、ファイルアイコンを表示し、ローカルで動作する実用的なアプリケーションを取得しました。 複数選択は、ファイルを選択するときにも機能します。 選択したファイルのダウンロードをサーバーに追加し、ProgressBarを使用することは残ります。 簡単です。 [アップロードの開始]ボタンをクリックすると、写真から最初の要素を取得し、URLRequestを作成し、FileReferenceでUploadReferenceメソッドを呼び出し、プログレスバーを制御し、ファイルがアップロードされたタイミングを追跡するイベントリスナーを追加します。 ロード後、写真から最初の要素を削除し、すべてを再度開始します。 コードは次のとおりです。

private function startUpload(): void

{

photosProgressContainer.visible = true ;



var fr:FileReference = photos.getItemAt(0).fr;

fr.cancel();

fr.addEventListener(ProgressEvent.PROGRESS,uploadProgress);

fr.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,uploadComplete);

fr.upload( new URLRequest( "http://ragneta.com/tests/flexupload/upload.php" ));

}



private function uploadProgress(e:ProgressEvent): void

{

photosProgress.setProgress(e.bytesLoaded,e.bytesTotal);

}



private function uploadComplete(e:DataEvent): void

{

photos.removeItemAt(0);

if (photos.length > 0)

startUpload();

else

photosProgressContainer.visible = false ;

}




* This source code was highlighted with Source Code Highlighter .






以上が、完全なコード: Uploader.mxmlphotoThumb.mxmlです。 さらに、ある種の承認をビデオに転送する必要があります。セッション識別子をflashvarsにそれぞれ渡します。flexでは、転送された変数はApplication.application.parameters配列にあります。 次に、初期化でHTTPRequestを実行し、セッションを送信して、ユーザーの名前、アルバム、その他すべてを取得します。 また、エラーや例外をキャッチしたり、サーバーの応答を解析したりする必要もあります。 ここには必要な最小値のみが記載されています。



写真のソースをダウンロードする必要がない場合は、サーバーに送信する前にサイズを変更できます。 flash.display.Bitmapを使用して完了しました。以下に例を示します。



投稿を準備する過程で、奇妙なバグを見つけました。 進行状況バーとFileReference.cancel()イベントはWinVista + FF 3.5.7 + Flash Player 10.0.42では正しく機能しませんが、同様のWinXP + FF 3.5.7 + Flash Player 10.0.42ではすべて問題ありません。



また、画像の回転に関する問題をまだ解決していません。 第一に、新しいimage.transform.matrixを設定して、アニメーション化された変換を行う方法を見つけられませんでした。 2番目の問題は、私のRotateがitemRendererに渡されるデータではなく、itemRenderera自体のタグに適用されることです。 画像を回転してから削除し、その場所に新しい画像をロードすると、画像が回転します。 この場合、各セルの初期化イベントは1回だけ発生します。 dataChangeのitemRendererでは、回転を0にハングさせる必要がありますが、TileListがデータを削除するときにセルを完全に破壊してから再初期化できれば十分です。



All Articles