ベクタ画像(*.pdr)読み込み
ParaDrawで描いたベクタ画像(*.pdr)をActionScript3.0で読み込みます。
クリックでズームします。
ParaDraw
http://www.geocities.jp/coa9999/
/**
* Copyright shohei909 ( http://wonderfl.net/user/shohei909 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/luUj
*/
/*
ParaDrawで描いたベクタ画像(*.pdr)をActionScript3.0で読み込みます。
クリックでズームします。
ParaDraw
http://www.geocities.jp/coa9999/
今後の目標
グラデーションに対応。
モーフィングをTweenでできるようにする。
*/
package {
import flash.utils.Endian;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.net.FileFilter;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import com.bit101.components.PushButton;
import flash.net.FileReference;
import caurina.transitions.Tweener;
[SWF(width="465",height="465",backgroundColor="0x333333")]
public class PDRTest extends Sprite {
private var loader:URLLoader;
private var file:FileReference;
private var field:Sprite;
private var pdrImage:PDRImage; //pdrを読み込むオブジェクト
function PDRTest() {
//データのロード============================================================
loader = new URLLoader();
loader.load(new URLRequest("http://spheresofa.web.fc2.com/wonderfl/man.pdr")); //ファイルのロード
loader.addEventListener("complete",onLoad );
//=========================================================================
//画像を配置するフィールドを作成===============================================
field = new Sprite();
with(field.graphics){ beginFill( 0x888888 ); drawRect(0, 0, 445, 425); }
field.x = field.y = 10;
addChild(field);
var mask:Bitmap = new Bitmap(new BitmapData(445,425,false,0));
mask.x = mask.y = 10;
addChild(mask);
field.mask = mask;
//=========================================================================
new PushButton(this, 350, 440, "load", load ); //loadボタンの追加
field.addEventListener("mouseDown",onDown );
field.addEventListener("mouseUp",onUp );
}
private function onLoad(e:Event):void{
loader.removeEventListener("complete",onLoad )
pdrImage = new PDRImage(loader.data); //pdrデータをStringで渡す
field.addChild(pdrImage); //表示リストに追加
}
//ローカルからのpdfファイル読み込む。
private function load(e:Event):void{
file = new FileReference();
file.addEventListener("select",onSelect );
file.browse( [new FileFilter("ParaDrawベクタ画像(*.pdr)","*.pdr;")] );
}
private function onSelect(e:Event):void{
file.removeEventListener("select",onSelect );
file.load();
file.addEventListener("complete",onFileLoad );
}
private function onFileLoad(e:Event):void{
file.removeEventListener("complete",onFileLoad );
if(pdrImage != null){ field.removeChild(pdrImage)}
pdrImage = new PDRImage(file.data.readUTFBytes(file.data.length));
field.addChild(pdrImage);
}
private function onDown(e:Event):void{
Tweener.addTween(pdrImage,{time:1,x:(-field.mouseX+field.width/2)-field.mouseX*5,y:(-field.mouseY+field.height/2)-field.mouseY*5,scaleX:5,scaleY:5,transition:"easeInOutBack"});
}
private function onUp(e:Event):void{
Tweener.addTween(pdrImage,{time:1,x:0,y:0,scaleX:1,scaleY:1,transition:"easeOutBounce"});
}
}
}
import flash.display.Shape;
import flash.display.Graphics;
import flash.events.Event;
class Path extends Object {
public var anchors:Vector.<Anchor> = new Vector.<Anchor>();
public var style:PathStyle;
function Path(style:PathStyle = null) {
if(style == null ){ this.style = new PathStyle() }
else{ this.style = style }
}
public function addAnchor(anchor:Anchor):void{ anchors.push(anchor); }
/**
* 指定したグラフィックスに対して,このパスブロックを描画します
* @param g:描画を行うグラフィックス
*/
public function draw(g:Graphics, comp:Boolean = false):void {
if (anchors.length > 1) {
var s:PathStyle = style;
var a0:Anchor = anchors[0], a1:Anchor = anchors[1];
if(comp == false){ g.lineStyle( s.thickness, (s.lineRed << 16) + (s.lineGreen << 8) + (s.lineBlue << 0), s.lineAlpha ); }
var curve:Number = 0;
if ( s.close ) {
if(comp == false){ g.beginFill( (s.fillRed << 16) + (s.fillGreen << 8) + (s.fillBlue << 0), s.fillAlpha); }
if( a0.curve > 0 ) { g.moveTo(( a1.curve * a0.x + a0.curve * a1.x ) / ( a0.curve + a1.curve ) , ( a1.curve * a0.y + a0.curve * a1.y ) / ( a0.curve + a1.curve ) ); }
else { g.moveTo( a0.x, a0.y ); }
}else { g.moveTo( a0.x , a0.y ); }
for ( var i:int = 1; i < anchors.length - 2; i++ ) {
a0 = anchors[i]; a1 = anchors[i + 1];
_drawLine(g, a0, a1);
}
a0 = anchors[i]; a1 = anchors[i + 1];
if ( s.close ) {
_drawLine(g, a0, a1);
a0 = anchors[i + 1]; a1 = anchors[0]; _drawLine(g, a0, a1);
a0 = anchors[0]; a1 = anchors[1]; _drawLine(g, a0, a1);
}else {
if( a0.curve > 0 ) { g.curveTo(a0.x, a0.y, a1.x, a1.y); }
else{ g.lineTo( a0.x, a0.y );g.lineTo( a1.x, a1.y ); }
}
}
}
/**
* Pathの複製を返します
* @return このオブジェクトの複製
*/
public function clone():Path { var cl:Path = new Path( style.clone() ); anchors = objClone(anchors); return cl; }
private function _drawLine(g:Graphics, a0:Anchor, a1:Anchor):void {
if( a0.curve > 0 ) { g.curveTo(a0.x, a0.y, ( a1.curve * a0.x + a0.curve * a1.x ) / ( a0.curve + a1.curve ) , ( a1.curve * a0.y + a0.curve * a1.y ) / ( a0.curve + a1.curve ) ); }
else{ g.lineTo( a0.x, a0.y ); }
}
}
class VectorImage extends Shape {
public var paths:Vector.<Path> = new Vector.<Path>();
public function get numPath():uint { return paths.length; }
private var _locked:Boolean = false;
public function lock():void { _locked = true; }
public function unlock():void { _locked = false; draw( graphics ); }
public function get locked():Boolean { return _locked; }
function VectorImage(){
addEventListener(Event.EXIT_FRAME, onFrame);
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
public function addPath(path:Path):void{ paths.push(path); }
/**
* 指定したグラフィックスに対して,このイメージを描画します
* @param g:描画を行うグラフィックス
*/
public function draw(g:Graphics):void {
g.clear();
var comp:Boolean;
for each( var path:Path in paths ) {
if ( bf != null && path.style.compounded == true && bf.style.compounded == true && path.style.compID == bf.style.compID ) { comp = true }
else { comp = false; }
path.draw( g, comp );
var bf:Path = path;
}
}
/**
* このベクタイメージに描かれたものを消去します。
* ロックも解除されます。
*/
public function clear():void {
paths = new Vector.<Path>();
unlock();
}
/**
* このイメージの複製を返します
*/
public function clone():VectorImage { var img:VectorImage = new VectorImage(); paths = objClone(paths); return img; }
private function onFrame(e:Event):void { if( !_locked ){ draw( graphics ); } }
private function addedToStage(e:Event):void { removeEventListener(Event.ADDED_TO_STAGE, addedToStage);draw( graphics ); }
}
class PDRImage extends VectorImage {
function PDRImage( data:String ) {
var line:Array = data.split("\r\n");
var pathNum:int = line[3];
var start:int = 4; var count:int = 0;
for (var i:int = 0; i < pathNum; i++ ) {
var pd:Array = line[start].split(","); //パスヘッダのデータ
var style:PathStyle = new PathStyle( pd[1] == "#TRUE#", pd[2] / 20,
(pd[4]>>>0)%0x100, (pd[4]>>>8)%0x100, (pd[4]>>>16)%0x100, pd[3] > 0 ?((pd[4]>>>24)%0x100)/0x100:0,
(pd[6]>>>0)%0x100, (pd[6]>>>8)%0x100, (pd[6]>>>16)%0x100, pd[5] > 0 ?((pd[6]>>>24)%0x100)/0x100:0,
pd[15] == "#TRUE#", pd[16]
);
var path:Path = new Path( style );
var ancNum:int = pd[0];
var gradNum:int = line[start + 1];
for (var j:int = 0; j < ancNum+1; j++ ) {
count++;
var ancData:Array = line[start+j+gradNum+2].split(",");
var anchor:Anchor = new Anchor(ancData[1]/20, ancData[2]/20, ancData[0]);
path.addAnchor(anchor);
}
addPath(path);
start += ancNum + gradNum + 3;
}
unlock();
lock();
}
}
class PathStyle extends Object {
public var thickness:Number,lineRed:uint,lineGreen:uint,lineBlue:uint,lineAlpha:Number;
public var close:Boolean,fillRed:uint,fillGreen:uint, fillBlue:uint,fillAlpha:Number;
public var compounded:Boolean,compID:int;
//public var useGradation:Boolean = false;
//public var gradation:Gradation;
function PathStyle( close:Boolean = true, thickness:Number = 1.5,
lineRed:uint = 0, lineGreen:uint = 0, lineBlue:uint = 0, lineAlpha:Number = 1,
fillRed:uint = 0xFF, fillGreen:uint=0x33, fillBlue:uint=0x66, fillAlpha:Number = 1,
compounded:Boolean = false, compID:int = 0
):void {
this.close = close; this.thickness = thickness;
this.lineRed = lineRed; this.lineGreen = lineGreen; this.lineBlue = lineBlue; this.lineAlpha = lineAlpha;
this.fillRed = fillRed; this.fillGreen = fillGreen; this.fillBlue = fillBlue; this.fillAlpha = fillAlpha;
this.compounded = compounded; this.compID = compID;
}
/**
* PathStyleの複製を返します
* @return このオブジェクトの複製
*/
public function clone():PathStyle { return new PathStyle(close, thickness, lineRed, lineGreen, lineBlue, lineAlpha,fillRed, fillGreen, fillBlue, fillAlpha, compounded, compID); }
}
class Anchor extends Object {
public var x:Number, y:Number, curve:Number;
function Anchor(x:Number, y:Number, curve:Number):void {
this.x = x; this.y = y; this.curve = curve;
}
/**
* Anchorの複製を返します
* @return このオブジェクトの複製
*/
public function clone():Anchor { return new Anchor(x,y,curve) }
}
/**
* オブジェクトの複製を行います。
*/
function objClone(arg:*):*{
import flash.utils.getQualifiedClassName;
var cl:*;
var name:String = getQualifiedClassName(arg);
if( name == "Object" || name == "Array" || name == "Vector" ){
if( name == "Object" ){ cl = {}; }
else if( name == "Array" ){ cl = []; }
else if( name == "Vector" ){ cl = Vector([]); }
for( var s:String in arg ){
cl[s] = objClone( arg[s] );
}
return cl;
}else if( arg is Object && arg.hasOwnProperty("clone") && arg.clone is Function ){
return arg.clone();
}
return arg;
}