- 2008-11-16 (Sun) 23:59
- Flash/Flex , ActionScript , 勉強会
変なプログラマーの作り方という勉強会でプレゼンターをしました。 主催者が同じ会社のfujioka0729だったこともあり、お願いされたというわけです。 会社の仕事がかなり厳しいこのタイミングに振ってくるとは中々にSな奴です。 ま、僕はMなので受けたわけですけど。
テーマが掲示板ということなので、Flexでゆるふわ掲示板を作ってその紹介をしてきました。 「変な」というテーマを目指していたはずが、いつの間にかそれを忘れてて、最終的にはそれほど変わったものにならなかったというのが反省点かな。 作ったものはこちら。
「ゆるふわ掲示板」(公開停止しました)
- 画面上でクリックするとその周辺の書き込みを表示後、その位置に書き込むフォームが表示されます
- 頑張って探さなくとも色んな穴があるので、優しさを持って接してください。怖いので、多分そのうち削除しますけど。
まあ色々と手を抜いてる部分があるのですが、下のほうでソースでも晒しておきます。 (手を抜いているからこそソースを読んでも何が何やらわからない → わからないから手を抜いてるとわかる、みたいな。)
勉強会は会社の知人の出席率が高く、盛り上がりました。今後は幅広く色んな人が参加してくれれば楽しくなりそうですね。 毎回、投票で最も「変な」プログラマが選出される、というのが特色です。
そしてなぜか今回は僕が選ばれてしまいました。 自分で自分に投票するという節操のなさが勝因でしょう。 他にはこんなことをした方がいました。
カップラーメンより早く掲示板を作る by fujioka0729
- Railsを使ってその場で掲示板を作る
- その後、一行ずつアニメーションで表示するようなJavaScript処理を追加
- 全てその場でライブコーディングしたので、かなりテンパッてて面白かった
- Windowsのコマンド、いわゆるバッチファイルでサーバサイドの処理を作るというもの
- CGIのインターフェースを利用
- 「変なプログラマ」という勉強会の趣旨には一番あってたのではないかと思われる
上記の2人は主催者でもあります。 参加した皆さん、お疲れ様でした。 また会いましょう。
あ、そうそうソースだ。
BaloonBBS.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
xmlns:bbs="bbs.*" creationComplete="init()" backgroundColor="#aaaaaa" height="500" width="700">
<mx:Script>
<![CDATA[
import mx.core.FlexShape;
import mx.core.IFlexDisplayObject;
import bbs.FormPanel;
import mx.managers.PopUpManager;
import bbs.RemarkData;
import mx.controls.Button;
import mx.containers.TitleWindow;
import mx.controls.TextArea;
import mx.containers.Panel;
import bbs.Remark;
import mx.core.UIComponent;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import caurina.transitions.properties.DisplayShortcuts;
import mx.effects.Tween;
import caurina.transitions.Tweener;
/* 現在の書き込み一覧 */
private var remarksArray:Array;
/* 現在画面に表示されている書き込み一覧 */
private var visibleRemarksArray:Array;
/* 投稿フォーム */
private var form:FormPanel;
/* ローダー */
private var loader:URLLoader;
private var currentCircle:Shape;
private function init():void{
DisplayShortcuts.init();
remarksArray = new Array();
visibleRemarksArray = new Array();
readAll();
}
private function onClick(event:MouseEvent):void{
search(mouseX, mouseY);
}
private function search(searchX:Number, searchY:Number):void{
//現在見えている発言をクリア
visibleRemarksArray.forEach(function(element:DisplayObject, index:int, arr:Array):void{element.visible = false;});
visibleRemarksArray = new Array();
var circle:FlexShape = new FlexShape();
circle.x = searchX;
circle.y = searchY;
drawCircle(circle, 10, 0x5555ff);
currentCircle = circle;
stage.addChild(circle);
Tweener.addTween(circle,
{alpha:0, _scale:15, onUpdate:updateTween, time:2.5,
transition:"liner", onComplete:showForm, onCompleteParams:[circle]});
}
private function showForm(circle:Shape):void{
if(currentCircle == circle){
form = FormPanel(PopUpManager.createPopUp(can, FormPanel, true));
FormPanel(form).base = this;
form.x = Math.max(circle.x - form.width / 2, 0);
form.y = Math.max(circle.y - form.height / 2, 0);
}
}
private function updateTween():void{
remarksArray.forEach(lightRemark);
}
private function lightRemark(element:DisplayObject, index:int, arr:Array):void{
if(visibleRemarksArray.indexOf(element) < 0){
if(checkDistance(element.x + element.width / 2, element.y + element.height / 2)){
visibleRemarksArray.push(element);
element.alpha = 0;
element.visible = true;
Tweener.addTween(element, {alpha:1, time:5, transition:"liner"});
}
}
}
private function checkDistance(x1:int, y1:int):Boolean{
var x2:Number = currentCircle.x;
var y2:Number = currentCircle.y;
var distance:Number = currentCircle.scaleX * 10;
return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) < distance * distance;
}
private function drawCircle(shp:Shape, size:Number, color:uint):void{
shp.graphics.beginFill(color);
shp.graphics.drawCircle(x, y, size);
shp.graphics.endFill();
}
private function makeRemark(n:String, remark:String, x:Number=0, y:Number=0, col:uint=0):Remark{
var r:Remark = new Remark();
r.data = new RemarkData(n, remark);
r.x = x;
r.y = y;
r.setStyle("borderColor", col);
r.visible = false;
return r;
}
public function submit():void{
var req:URLRequest = new URLRequest();
req.data = "remark[name]=" + form.getName() + "&remark[body]=" + form.getBody() +
"&remark[x]=" + (currentCircle.x - 50) + "&remark[y]=" + (currentCircle.y - 30) +
"&remark[color]=" + form.getColor();
req.method=URLRequestMethod.POST;
req.url = "http://yurufuwa.obanet.jp/create";
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, postComplete);
loader.load(req);
PopUpManager.removePopUp(form);
}
public function readAll():void{
var req:URLRequest = new URLRequest();
req.url = "http://yurufuwa.obanet.jp/list";
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, readComplete);
loader.load(req);
PopUpManager.removePopUp(form);
}
private function readComplete(event:Event):void{
fetchRemarks();
}
private function postComplete(event:Event):void{
fetchRemarks();
search(currentCircle.x, currentCircle.y);
}
public function fetchRemarks():void{
var xml:XML = new XML(loader.data);
remarksArray.forEach(function(element:DisplayObject, index:int, arr:Array):void{can.removeChild(element)});
remarksArray = new Array;
visibleRemarksArray = new Array;
for each (var remarkXML:XML in xml.remark){
var name:String = unescape(remarkXML["name"]);
var body:String = unescape(remarkXML["body"]);
var x:Number = remarkXML.pos.@x;
var y:Number = remarkXML.pos.@y;
var col:Number = remarkXML["color"];
var remark:Remark = makeRemark(name, body, x, y, col);
remarksArray.push(remark);
}
remarksArray.reverse();
for each (var r:Remark in remarksArray){
can.addChild(r);
}
}
]]>
</mx:Script>
<mx:Canvas id="can" click="onClick(event)" x="0" y="0" width="700" height="500" styleName="plain">
</mx:Canvas>
</mx:Application>
Remark.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
title="{data.name}" horizontalAlign="left" verticalScrollPolicy="off" horizontalScrollPolicy="off" width="168" height="86">
<mx:TextArea id="tArea"
text="{data.text}" fontSize="10" color="#000000"
editable="false" wordWrap="true" maxChars="50"
horizontalScrollPolicy="off" verticalScrollPolicy="off" x="0" y="0" width="148" height="46"/>
</mx:Panel>
RemarkData.as
package bbs
{
public class RemarkData
{
[Bindable]
public var name:String;
[Bindable]
public var text:String;
public var x:Number;
public var y:Number;
public function RemarkData(name:String=null, text:String=null)
{
this.name = name;
this.text = text;
}
}
}
FormPanel.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="238" height="194" title="投稿"
horizontalScrollPolicy="off" verticalScrollPolicy="off" showCloseButton="true" close="handleClose()">
<mx:Script>
<![CDATA[
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
public var base:BaloonBBS;
public function getName():String{
return aName.text;
}
public function getBody():String{
return body.text;
}
public function getColor():uint{
return colPic.selectedColor;
}
private function onSelectColor():void{
this.setStyle("borderColor", getColor());
}
private function handleClose():void{
PopUpManager.removePopUp(this);
}
private function submit():void{
base.submit();
}
]]>
</mx:Script>
<mx:Form width="218" height="122" horizontalScrollPolicy="off" verticalScrollPolicy="off" x="0" y="0">
<mx:FormItem label="名前">
<mx:TextInput id="aName" width="135" maxChars="15"/>
</mx:FormItem>
<mx:FormItem label="本文">
<mx:TextArea id="body" width="136" height="59" maxChars="45"/>
</mx:FormItem>
</mx:Form>
<mx:Button label="投稿" x="85" y="130" click="submit()"/>
<mx:ColorPicker id="colPic" x="186" y="130" selectedColor="0x888888" change="onSelectColor()"/>
</mx:TitleWindow>
関連するエントリー [FLex] ゆるふわ掲示板 in
- Newer: [Flex]Fleverlight勉強会 Vol.2 in 大阪
- Older: [問題]コマネチ大学数学科 ラマヌジャン
トラックバック:No Trackbacks
- トラックバック URL
- http://blog.garden-place.jp/action.php?action=plugin&name=TrackBack&tb_id=211
- Listed below are links to weblogs that reference
- [FLex]ゆるふわ掲示板 in 変なプログラマーの作り方 from Web 酒 肴