2008-06-18

透過 ActionScript 產生 PDF

Flash 8 / ActionScript 2 Version: blazePDF v2 component (要付費)

ActionScript 3 Open-Source PDF Library: AlivePDF

Neo's blog 整理的 [PHP] 免費好用的 PDF Library 大搜集

2008-06-10

台灣 Adobe/macromedia 使用者俱樂部論壇搬家中

這兩天無法上 mmug.com.tw
問了一下 Willy,才知道原來在搬家中,可能還會暫停服務數天。

2008-06-09

2008-06-06

flashandmath.com - ActionScript 3 Tutorials

flashandmath.com 滿讚的 AS3 教學網站。

以動態文字作為遮罩

mmug上討論的問題
在此我用之前的 Substitute 類別來解決

Frame Actions:
// 底
var bmd:BitmapData = new BitmapData(200, 200, true, 0xFFCCCCCC);
var seed:int = int(Math.random() * int.MAX_VALUE);
var channels:uint = BitmapDataChannel.RED | BitmapDataChannel.BLUE;
bmd.perlinNoise(100, 80, 12, seed, false, true, channels, false, null);
var bm:Bitmap = new Bitmap(bmd);
this.addChild(bm);

// 動態文字
var _txt:TextField = new TextField;
_txt.autoSize = "left";
var myTextFormat:TextFormat = new TextFormat(null, 30, 0, true);
_txt.text = "動態文字";
_txt.x = 50;
_txt.setTextFormat(myTextFormat);
this.addChild(_txt);

// 建立替身
import lin.shinder.display.Substitute;
var s:Substitute = new Substitute(_txt).displace();
s.rotation = 30;

// 設定遮罩
bm.cacheAsBitmap = true;
s.cacheAsBitmap = true;
bm.mask = s;

原始檔下載

2008-06-05

取得 Domain Name (AS3 版)

/**
* author: shinder lin
* email: shinder.lin@gmail.com
*/
package lin.shinder.net
{
import flash.display.DisplayObject;
public class HttpDomain
{
static public var defaultDomain:String = "http://localhost";
static public function getDomain(displayObj:DisplayObject)
{
var url_str:String = displayObj['stage'].loaderInfo.loaderURL;
if (url_str.indexOf("http://") == 0 || url_str.indexOf("https://") == 0) {
var s_index:int = url_str.indexOf("/", 10);
return url_str.substring(0, s_index);
} else {
return defaultDomain;
}
}
}
}

由 URL 取得 Domain Name (AS2 版)

2008-06-04

PHP 使用 JSON 和 AS3 溝通

JSON 常用在 AJAX 的資料交換上,其實也可以用在 SWF<->PHP 上。
PHP5有內建 JSON 的函式;PHP4沒有,但可以用 PEAR 的 JSON 類別
AS3 則可以用 as3corelib 裡的 JSON 類別。
以下是將DB資料轉換成JSON的例子。
mysql2json4.php
/*** shinder.lin@gmail.com
for PHP4
*/
require_once("JSON.php");
function mysql2json4($sql) {
if(is_string($sql)) {
$query = mysql_query($query) or die(mysql_error());
} else {
$query = $sql;
}

$ar = array();
if($total = mysql_num_rows($query)) {
while($row = mysql_fetch_assoc($query)) {
$obj = array();
foreach($row as $key => $value) {
$obj[ $key ] = $value;
}
array_push($ar, $obj);
}
mysql_data_seek($query, 0);
}

$json = new Services_JSON();
return $json->encode($ar);
}
?>

test_mysql2json4.php
require("mysql2json4.php");

mysql_connect("localhost", "root", "");
mysql_select_db("test");
mysql_query("SET NAMES 'utf8'");
$q = mysql_query("select * from ctest");
echo mysql2json4($q);
?>

test_json.fla frame actions:
import  com.adobe.serialization.json.*;

var ur:URLRequest = new URLRequest("http://localhost/json_test/test_mysql2json4.php");
var ul:URLLoader = new URLLoader();
ul.addEventListener(Event.COMPLETE, onComplete);
ul.load(ur);

function onComplete(evt:Event) {
trace(ul.data);
var o:Object = JSON.decode(ul.data);
QopDump.echo(o);
}



資料傳給 PHP
test_json_insert4.php
require_once("JSON.php");

$raw = $GLOBALS["HTTP_RAW_POST_DATA"];

$json = new Services_JSON();
$ar = (array) $json->decode($raw);

mysql_connect("localhost", "root", "");

mysql_select_db("test");
mysql_query("SET NAMES 'utf8'");
// watch out for sql injection
$sql = sprintf("INSERT INTO `ctest` (`sno`, `name`, `phone`) VALUES (NULL, '%s', '%s')", $ar['name'], $ar['phone']);
echo (bool) mysql_query($sql);
?>

test_json_submit.fla frame actions:
import  com.adobe.serialization.json.*;

var ur:URLRequest = new URLRequest("http://localhost/json_test/test_json_insert4.php");
ur.method = URLRequestMethod.POST;
var ul:URLLoader = new URLLoader;

submit_btn.addEventListener(MouseEvent.CLICK, onSubmit);

function onSubmit(evt:MouseEvent):void {
var obj:Object = {name:name_ti.text, phone:phone_ti.text};
var str:String = JSON.encode(obj);
ur.data = str;
ur.contentType = "text/plain";
ul.load(ur);
// trace(str);
}

ul.addEventListener(Event.COMPLETE, onComplete);

function onComplete(evt:Event) {
info_ta.text = ul.data;
}

相關檔案下載

2008-05-20

建立 DisplayObject 物件 的 Bitmap 替身

包含動態文字的視覺物件常會因為旋轉而消失
在此弄個類別用以建立替身, 由於是點陣資料, 故縮放的時候會比較醜
測試的 Frame Actions :
import lin.shinder.display.Substitute;

var _txt:TextField = new TextField;
_txt.text = "ABCDEF";
this.addChild(_txt);

var s:Substitute = new Substitute(_txt).displace();
s.rotation = 30;

var s_mc:Substitute = new Substitute(t_mc);
s_mc.x = 200;
s_mc.y = 200;
this.addChild(s_mc);

類別檔 Substitute.as :
package lin.shinder.display
{
import flash.geom.Rectangle;
import flash.geom.Matrix;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.PixelSnapping;
// 替身
dynamic public class Substitute extends Sprite
{
private var bitmap:Bitmap;
public var bitmapData:BitmapData;
public var original:DisplayObject;

public function Substitute(disp:DisplayObject)
{
original = disp;
bitmapData = new BitmapData(disp.width, disp.height, true, 0);
var rect:Rectangle = disp.getBounds(disp);
var matrix:Matrix = new Matrix;
matrix.translate(-rect.x, -rect.y);
bitmapData.draw(disp, matrix);
bitmap = new Bitmap(bitmapData, PixelSnapping.AUTO, true);
bitmap.x = rect.x;
bitmap.y = rect.y;
this.addChild(bitmap);
this.visible = original.visible;
this.x = original.x;
this.y = original.y;
this.scaleX = original.scaleX;
this.scaleY = original.scaleY;
this.rotation = original.rotation;
}

public function displace():Substitute
{
if(! original.parent) {
trace('The original DisplayObject is not in display chains !');
return null;
}
var _parent:DisplayObjectContainer = original.parent as DisplayObjectContainer;
var depth:int = _parent.getChildIndex(original);
_parent.addChildAt(this, depth);

_parent.removeChild(original);
return this;
}
}
}

測試範例原始檔

2008-05-16

Flash Player 10 beta, code-named "Astro"

新的 Flash Player 10 進入 beta 階段
Developer 另一階段的苦難又要開始了 :P

FB 留言