forked from: forked from: 手描きアニメ風?線文字 Ver.1
すいません。ほとんど何も変えてません。
上部テキスト入力エリアの文を手描きアニメ風の文字にします。
この文字は変更可能です。
ちょっとまわりくどい?方法でフォント→線描の変換をしています。
テキストフィールド→ビットマップデータ→ドット検出→線描領域決定 って感じ。
フォントサイズとかテキストフィールドの設定を変えると文字の出方も変化します
ビットマップをスキャンする際の平方ピクセル域の値でも変わります。
これはもともと、2×2=4ないし、3×3=9のスキャンパターン毎に作りこんだビットマップを割り当てて
ごにょごにょしようとしたもののwonderfl用に線描版。折角なのでスプライン曲線にしてみた。
いまは透過pngってつかえるんだっけ…?>wonderfl
※スプライン曲線のコードは[http://l00oo.oo00l.com/blog/archives/category/actionscript]のものを使わさせて頂いてます
これa*とかの経路探索アルゴリズムを応用して線を描くようにしたらもっと実用的な表現になるとおもうけどどうだろ
/**
* Copyright rainafter ( http://wonderfl.net/user/rainafter )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/jH48
*/
// forked from kkstudio2007's forked from: 手描きアニメ風?線文字 Ver.1
// forked from kidaipu's forked from: 手描きアニメ風?線文字 Ver.1
//すいません。ほとんど何も変えてません。
// 上部テキスト入力エリアの文を手描きアニメ風の文字にします。
// この文字は変更可能です。
// ちょっとまわりくどい?方法でフォント→線描の変換をしています。
// テキストフィールド→ビットマップデータ→ドット検出→線描領域決定 って感じ。
// フォントサイズとかテキストフィールドの設定を変えると文字の出方も変化します
// ビットマップをスキャンする際の平方ピクセル域の値でも変わります。
// これはもともと、2×2=4ないし、3×3=9のスキャンパターン毎に作りこんだビットマップを割り当てて
// ごにょごにょしようとしたもののwonderfl用に線描版。折角なのでスプライン曲線にしてみた。
// いまは透過pngってつかえるんだっけ…?>wonderfl
// ※スプライン曲線のコードは[http://l00oo.oo00l.com/blog/archives/category/actionscript]のものを使わさせて頂いてます
// これa*とかの経路探索アルゴリズムを応用して線を描くようにしたらもっと実用的な表現になるとおもうけどどうだろ
package{
import __AS3__.vec.Vector;
import caurina.transitions.properties.*;
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;
import flash.net.*;
import flash.text.Font;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.utils.*;
FilterShortcuts.init();
ColorShortcuts.init();
[SWF(width="605", height="605", backgroundColor="0xFFFFFF")]
public class Main extends Sprite
{
private var date:Date;
private var input_text:TextField;
private var date_text:TextField;
private var datetext_format:TextFormat;
private var datetext_bitmapdata:BitmapData;
private var display_bitmapdata:BitmapData;
private var clear_bmd:BitmapData;
public function Main()
{
//フォント読み出し
var fonts:Array = Font.enumerateFonts(false);
fonts.forEach(function(item:Object, arr:Array, index:uint):void { trace(item.fontName) } );
//初期化
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init():void
{
//stageの設定
stage.addChild(this);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
//withを使ってフォントの設定
datetext_format = new TextFormat();
with (datetext_format)
{
color = 0x000000;
size = 21;
bold = true;
kerning = true;
}
//textfieldの設定
date_text = new TextField();
with (date_text)
{
autoSize = TextFieldAutoSize.CENTER;
defaultTextFormat = datetext_format;
wordWrap = true;
width = 100;
}
//左上の方にあるやつ
input_text = new TextField();
var tmp_format:TextFormat = new TextFormat();
tmp_format.color = 0xffffff;
with (input_text)
{
border = true;
borderColor = 0xffffff;
defaultTextFormat = tmp_format;
type = TextFieldType.INPUT;
x = 10;
y = 10;
width = 250;
height = 20;
multiline = false;
text = "";
}
//bmpdata
display_bitmapdata = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xffffff);
clear_bmd = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xffffff);
//タイマー
var timer:Timer = new Timer(50,0);
timer.addEventListener(TimerEvent.TIMER, enterframeHndlr);
timer.start();
//
addChild(new Bitmap(new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xffffff), "auto", true)); //真ッ黒
addChild(new Bitmap(display_bitmapdata, "auto", true)); //display_bitmapdataをその上に重ねる
for (var i:uint = 0; i < cells * cells; i++) zeroStr += "0"; //cells?zeroStr?
}
private var cells:uint = 3;//←ここ変えると文字の形も変わる(2~5くらい)
private var zeroStr:String = "";
private var randness:Number =15.0;
//ループ
private function enterframeHndlr(e:Event):void
{
randness = (randness >= 1.2) ? randness-0.5:randness;
trace(randness);
var tmpString:String;
//日付:時分秒(作者は時計にしたかったのだろう...)
date = new Date();
tmpString = String("00" + date.getHours()).substr( -2, 2) + ":" + String("00" + date.getMinutes()).substr( -2, 2) + ":" + String("00" + date.getSeconds()).substr( -2, 2);// + "." + String("000" + date.getMilliseconds()).substr( -3, 1);
//フォントをBitmapdata化
tmpString = "如果我现在就死掉"; //入力した文字
date_text.text = tmpString; //
//date_text.text=tmpString.substr(0,(int(date.getSeconds())%tmpString.length)+1);
datetext_bitmapdata = new BitmapData(date_text.textWidth+(date_text.textWidth%cells), date_text.textHeight+(date_text.textHeight%cells), true, 0x00000000);
datetext_bitmapdata.draw(date_text);
//??
var cell_scaleA:Number = datetext_bitmapdata.width / stage.stageWidth;
var cell_scaleB:Number = stage.stageWidth / datetext_bitmapdata.width;
//真っ黒なbitmapを載せる
display_bitmapdata.copyPixels(clear_bmd,new Rectangle(0,0,clear_bmd.width,clear_bmd.height),new Point(0,0));
display_bitmapdata.lock();
//??
var tmpVV:Vector.<Point> = new Vector.<Point>();
var tmpShape:Shape = new Shape();
for (var yy:uint = 0; yy < datetext_bitmapdata.height / cells; yy++)
{
for (var xx:uint = 0; xx < datetext_bitmapdata.width / cells; xx++)
{
//bitmapdataの色を走査して,tmpcellsという謎の値を出している
var tmpcells:uint = 0;
for (var j:uint = 0; j < cells; j++)
for (var i :uint= 0; i < cells; i++)
{
var addvalue:Number = (datetext_bitmapdata.getPixel32(xx * cells + i, yy * cells + j) > 0x55000000) ? 1 : 0;
tmpcells = tmpcells << 1;
tmpcells += addvalue;
}
//点を取得しているような
var tmpV:Vector.<Point> = new Vector.<Point>();
tmpShape.graphics.clear();
var drawcell:String = String(zeroStr + tmpcells.toString(2)).substr( -cells*cells, cells*cells);
for (i = 0; i < cells*cells; i++)
{
if (drawcell.substr(i, 1) == "1")
{
for (j = 0; j < 5-((date_text.text.length<3)?date_text.text.length:3); j++)
{
tmpV.push(new Point(Math.random() * cell_scaleB * randness + (i % cells) * cell_scaleB, Math.random() * cell_scaleB * randness + int(i / cells) * cell_scaleB));
}
}
}
if (tmpV.length > 0)
{
tmpV = shuffle_new(tmpV);
drawSpline(tmpV,tmpShape); //描画?
}
//変換をかけてdraw
display_bitmapdata.draw(tmpShape, new Matrix( 1.1, 0, 0, 1.1, xx * (cells * cell_scaleB * .9), yy * (cells * cell_scaleB * .9)-15) );
}
}
display_bitmapdata.unlock();
}
public function shuffle_new(v:Vector.<Point>):Vector.<Point>
{
for (var j:int, t:Point, i:int = v.length, a:Vector.<Point> = v.slice(); i; j = Math.random() * i, t = a[--i], a[i] = a[j], a[j] = t);return a;
}
private function drawSpline(v:Vector.<Point>,g:Shape):void
{
if(v.length<2) return;
v.splice(0,0,v[0]);
v.push(v[v.length-1]);
var numSegments:uint = 5;//曲線分割数(補完する数)
for(var i:uint=0; i<v.length-3; i++)
{
var p0:Point = v[i];
var p1:Point = v[i+1];
var p2:Point = v[i+2];
var p3:Point = v[i+3];
splineTo(p0, p1, p2, p3, numSegments,g);
}
}
private function splineTo(p0:Point, p1:Point, p2:Point, p3:Point, numSegments:uint, g:Shape):void
{
var d:Date = new Date();
var col:uint = 0xff0099;//d.getTime();
g.graphics.lineStyle(3.4, col,.4);
g.graphics.moveTo(p1.x, p1.y);
for(var i:uint=0; i<numSegments; i++)
{
var t:Number = (i+1)/numSegments;
g.graphics.lineTo
(
catmullRom(p0.x, p1.x, p2.x, p3.x, t),catmullRom(p0.y, p1.y, p2.y, p3.y, t)
);
}
}
private function catmullRom(p0:Number,p1:Number,p2:Number,p3:Number,t:Number):Number
{
var v0:Number = (p2 - p0) * 0.5;
var v1:Number = (p3 - p1) * 0.5;
return (2*p1 - 2*p2 + v0 + v1)*t*t*t +
(-3*p1 + 3*p2 - 2*v0 - v1)*t*t + v0*t + p1;
}
}
}
class Bugfix
{
function Bugfix(){}
}