文字をパスにして落とす
詳しくはFork元を見てください。
/**
* Copyright paq ( http://wonderfl.net/user/paq )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/w6e2
*/
// forked from shohei909's 文字のShape化
package
{
import com.actionsnippet.qbox.QuickBox2D;
import com.actionsnippet.qbox.QuickObject;
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.ui.Keyboard;
/**
* 一部の文字が使えないのはなんでなんだろ。
* @author paq89
*/
[SWF(width="465",height="465",backgroundColor="0xFFFFFF",frameRate="60")]
public class TypeBox2D extends MovieClip
{
private var _inputText:InputTextField;
private var _box2d:QuickBox2D;
private var _tts:TextToShape;
private var _polies:Vector.<QuickObject>;
public function TypeBox2D()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(event:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
_tts = new TextToShape();
_polies = new Vector.<QuickObject>();
_box2d = new QuickBox2D(this);
_box2d.setDefault({lineColor:0xFFFFFF, fillColor:0x0D0D0D});
_box2d.mouseDrag();
_box2d.start();
var sw:Number = _box2d.main.stage.stageWidth / 30;
var sh:Number = _box2d.main.stage.stageHeight / 30;
_box2d.addBox( { x:sw / 2, y: -0.5, width:sw, height:1, lineAlpha: 0, fillAlpha: 0, density:0.0 } );
_box2d.addBox( { x:sw / 2, y:sh + 0.5, width:sw, height:1, lineAlpha: 0, fillAlpha: 0, density:0.0 } );
_box2d.addBox( { x: -0.5, y:sh / 2, width:1, height:sh, lineAlpha: 0, fillAlpha: 0, density:0.0 } );
_box2d.addBox( { x:sw + 0.5, y:sh / 2, width:1, height:sh, lineAlpha: 0, fillAlpha: 0, density:0.0 } );
_inputText = new InputTextField(send, "Input here");
_inputText.width = stage.stageWidth-1;
addChild(_inputText);
}
private function send():void
{
var count:int = 0;
for each (var s:String in _inputText.text.split(""))
{
var path:Vector.<Vector.<Anchor>> = _tts.convert(s);
var points:Array = [];
var r:Number = Math.random()*7;
for each (var v:Vector.<Anchor> in path)
{
for each (var a:Anchor in v)
{
points.push(a.x / (20.0-r), a.y / (20.0-r));
}
}
if (points.length > 1)
{
var avgX:Number = 0;
var avgY:Number = 0;
var len:uint = points.length;
for (var i:uint = 0; i < len; i += 2)
{
avgX += points[i];
avgY += points[i + 1];
}
avgX /= points.length / 2;
avgY /= points.length / 2;
for (i = 0; i < len; i += 2)
{
var yp:int = i + 1;
points[i] -= avgX;
points[yp] -= avgY;
points[i] = Number(points[i].toFixed(2));
points[yp] = Number(points[yp].toFixed(2));
}
try
{
_polies.push(_box2d.addPoly( { x:1 + count * 2,
y:2,
points:points } ));
}
catch (e:*)
{
trace(e)
}
if (_polies.length > 15)
{
var p:QuickObject = _polies.shift();
p.fullDestroy();
}
count++;
}
}
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Shape;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.ui.Keyboard;
import flash.utils.getTimer;
internal class TextToShape
{
private const W:int = 100;
private const H:int = 80;
private var _map:Vector.<Vector.<Anchor>>;
private var _vec:Vector.<Anchor>;
private var _paths:Vector.<Vector.<Anchor>>;
private var _bitmapData:BitmapData = new BitmapData(W, H);
private var _textField:TextField;
private var _matrix:Matrix;
public function TextToShape()
{
_textField = new TextField()
_textField.defaultTextFormat = new TextFormat("", 50);
_textField.width = W;
_textField.height = H;
}
public function convert(text:String):Vector.<Vector.<Anchor>>
{
_map = new Vector.<Vector.<Anchor>>();
_vec = new Vector.<Anchor>();
_paths = new Vector.<Vector.<Anchor>>();
for (var i:int = 0; i < W + 1; i++)
{
_map[i] = new Vector.<Anchor>();
for (var j:int = 0; j < H + 1; j++)
{
_map[i][j] = null;
}
}
_bitmapData.fillRect(_bitmapData.rect, 0xFFFFFFFF);
_textField.text = text;
_bitmapData.draw(_textField);
progress();
return _paths;
}
private function progress():void
{
var time:int = getTimer();
var c:int = 0;
monoColor();
setVec();
setLink();
setPaths();
cutAnchors();
}
private function monoColor():void
{
var b:BitmapData = this._bitmapData;
b.lock();
for (var x:int = 0; x < W; x++)
{
for (var y:int = 0; y < H; y++)
{
if (b.getPixel(x, y) != 0xFFFFFF)
{
b.setPixel(x, y, 0)
}
}
}
b.unlock();
}
private function setVec():void
{
var b:BitmapData = this._bitmapData;
for (var x2:int = 0; x2 < W; x2++)
{
for (var y2:int = 0; y2 < H; y2++)
{
var d:Array = [];
var dl:int = 0;
for (var dx:int = -1; dx < 1; dx++)
{
for (var dy:int = -1; dy < 1; dy++)
{
var x:int = x2 + dx;
var y:int = y2 + dy;
if (x < 0 || W + 1 < x || y < 0 || H + 1 < y || b.getPixel(x, y) != 0)
{
d.push("0")
}
else
{
d.push("1");
dl++
}
}
}
if (dl == 1 || dl == 3)
{
var dir:Array;
if (dl == 1)
{
dir = [[0, -1], [-1, 0], [1, 0], [0, 1]][d.indexOf("1")]
}
else
{
dir = [[-1, 0], [0, 1], [0, -1], [1, 0]][d.indexOf("0")]
}
var anc:Anchor = new Anchor(x2, y2, dir);
_vec.push(anc);
_map[x2][y2] = anc;
}
}
}
}
private function setLink():void
{
for each (var a:Anchor in _vec)
{
var dx:int = a.dir[0];
var dy:int = a.dir[1];
var x:int = a.x;
var y:int = a.y;
while (true)
{
x += dx;
y += dy;
if (x < 0 || W < x || y < 0 || H < y)
{
break
}
if (_map[x][y] != null)
{
a.next = _map[x][y];
break;
}
}
}
}
private function setPaths():void
{
while (_vec.length > 0)
{
var first:Anchor = _vec[0];
var a:Anchor = first;
var v:Vector.<Anchor> = new Vector.<Anchor>;
var c:int = 0;
do
{
v.push(a)
_vec.splice(_vec.indexOf(a), 1);
a = a.next;
c++;
} while (first != a && c < 100)
_paths.push(v);
}
}
private function cutAnchors(size:Number = 10):void
{
for each (var v:Vector.<Anchor>in _paths)
{
while (v.length > 2)
{
var l:int = v.length
var a1:Anchor = v[l - 2];
var a2:Anchor = v[l - 1];
var a3:Anchor = v[0];
var min:Number = getTriangleSize(a1, a2, a3);
var mp:int = l - 1;
for (var i:int = 1; i < l; i++)
{
a1 = a2;
a2 = a3;
a3 = v[i];
var s:Number = getTriangleSize(a1, a2, a3);
if (s < min)
{
min = s;
mp = i - 1;
}
}
if (min <= size)
{
v.splice(mp, 1);
}
else
{
break;
}
}
}
}
private function getTriangleSize(a1:Anchor, a2:Anchor, a3:Anchor):Number
{
var s:Number = (a2.x - a1.x) * (a3.y - a1.y) - (a2.y - a1.y) * (a3.x - a1.x);
return (s > 0 ? s : -s) / 2;
}
}
internal class Anchor
{
public var x:Number;
public var y:Number;
public var dir:Array;
public var next:Anchor;
public var bf_size:Number;
public var size:Number;
public var af_size:Number;
function Anchor(x:Number, y:Number, dir:Array)
{
this.x = x;
this.y = y;
this.dir = dir
}
}
internal class InputTextField extends TextField
{
public var handler:Function;
private var _currentKey:uint;
private var _isFocus:Boolean;
private var _isMessageShowing:Boolean;
public function InputTextField(handler:Function, message:String = "")
{
super();
this.handler = handler;
_isFocus = false;
defaultTextFormat = new TextFormat("", 30);
height = 40;
text = message;
type = TextFieldType.INPUT;
border = true;
addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
addEventListener(FocusEvent.FOCUS_OUT, onFocusOut);
addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
}
private function onFocusIn(event:FocusEvent):void
{
if (!_isMessageShowing)
{
text = "";
_isMessageShowing = false;
}
_isFocus = true;
}
private function onFocusOut(event:FocusEvent):void
{
_isFocus = false;
}
private function onKeyDown(event:KeyboardEvent):void
{
if (!_isFocus) return;
_currentKey = event.charCode;
}
private function onKeyUp(event:KeyboardEvent):void
{
if (!_isFocus) return;
if (event.charCode == Keyboard.ENTER && event.charCode == _currentKey)
{
handler();
text = "";
}
}
}