forked from: TextFieldから文字の輪郭を取得して3Dにして砂の落下アニ・・以下省略
forked from TextFieldから文字の輪郭を取得して3Dにして砂の落下アニ・・以下省略 (diff: 5)
@author yooKo@serialField * @version 0.1 * Let's Click! * Papervision3DのPixcel3Dでまた遊んだ。 * どうぞご自由に画面をClickしてください。 * * TextFieldから文字の輪郭を取得して3D上にPixcel3Dで描画 * * ソースは荒れすぎてカオスな事になってます!! * 途中から自分でも何書いてるか分かんなくなった・・ * 特にテキストの外枠の座標をとる為にifのネストしまくった * 箇所は飯も食わずに6時間悩み続けた・・orz * * 後半から変数名とかちょー適当になってます。 * やけくそで実装しました。「可読性?なにそれ」って感じになってます。 * * 最適化もこれで精いっぱい 汗 * ifのネストは自分の頭脳ではもう無理です * * 今後思いついたらちょくちょく最適化する~ * * * クリックイベントが受け取れない!!!ちくしょー * ローカルでは問題なかったのに・・ * 本当はクリックしたらこうなる予定 ↓ * http://selflash.jp/wonderfl/Text3DSandAnime *
ActionScript3 source code
/**
* Copyright paq ( http://wonderfl.net/user/paq )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/miIm
*/
// forked from yooKo's TextFieldから文字の輪郭を取得して3Dにして砂の落下アニ・・以下省略
/**
* @author yooKo@serialField
* @version 0.1
* Let's Click!
* Papervision3DのPixcel3Dでまた遊んだ。
* どうぞご自由に画面をClickしてください。
*
* TextFieldから文字の輪郭を取得して3D上にPixcel3Dで描画
*
* ソースは荒れすぎてカオスな事になってます!!
* 途中から自分でも何書いてるか分かんなくなった・・
* 特にテキストの外枠の座標をとる為にifのネストしまくった
* 箇所は飯も食わずに6時間悩み続けた・・orz
*
* 後半から変数名とかちょー適当になってます。
* やけくそで実装しました。「可読性?なにそれ」って感じになってます。 *
* 最適化もこれで精いっぱい 汗
* ifのネストは自分の頭脳ではもう無理です
*
* 今後思いついたらちょくちょく最適化する~
*
*
* クリックイベントが受け取れない!!!ちくしょー
* ローカルでは問題なかったのに・・
* 本当はクリックしたらこうなる予定 ↓
* http://selflash.jp/wonderfl/Text3DSandAnime
*
**/
package {
import flash.display.*;
import flash.text.*;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.geom.ColorTransform;
import flash.geom.Point;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.display.StageQuality;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.Timer;
import flash.utils.getTimer;
import org.papervision3d.core.effects.BitmapLayerEffect;
import org.papervision3d.core.effects.BitmapColorEffect;
import org.papervision3d.core.effects.utils.BitmapClearMode;
import org.papervision3d.core.geom.Pixels;
import org.papervision3d.core.geom.renderables.Pixel3D;
import org.papervision3d.view.BasicView;
import org.papervision3d.view.layer.BitmapEffectLayer;
import net.hires.debug.Stats;
// 0x000000 → 0xFF000000 に変換するクラス。
//import lib.utils.ColorUtil;
[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="40")]
public class Text3DSandAnime extends BasicView {
private var _pixels:Pixels;
private var _rotateX:Number = 0;
private var _rotateY:Number = 0;
private var _particles:Array/*Particle*/;
private var _startTime:int;
private var _flg:Boolean = false;
private var _bmd:BitmapData;
private var _xy:Number;
private var _i:int;
private var _a:Number;
private var _y:Number;
private var _x:Number;
private var _c:uint;
private var _p:Particle;
private var _textW:Number;
private var _textH:Number;
//========================================================================
// コンストラクタ
//========================================================================
public function Text3DSandAnime() {
super(0, 0, true, true);
StageQuality.LOW;
if (!stage)
addEventListener(Event.ADDED_TO_STAGE, init);
else
init();
}
//========================================================================
// メイン
//========================================================================
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
camera.z = -100;
var _layer:BitmapEffectLayer = new BitmapEffectLayer(viewport, stage.stageWidth, stage.stageHeight, true, 0, BitmapClearMode.CLEAR_PRE, false);
viewport.containerSprite.addLayer(_layer);
_layer.addEffect(new BitmapColorEffect(1, 1, 1, .85));
_layer.addEffect(new BitmapLayerEffect(new BlurFilter(4, 4, 1), false));
//_layer.clippingPoint = new Point(0, -4);
_pixels = new Pixels(_layer);
scene.addChild(_pixels);
createText();
// レイヤー構造でテキストPixel3Dで生成するお~~
createBody(-12, 2, 0xFFCCCC00);
createFrame(-8, 5, 0xFFFF0066);
createFrame(-4, 5, 0xFFFF0066);
createFrame(0, 5, 0xFFFF0066);
createFrame(4, 1, 0xFFFFFFFF);
addEventListener(Event.ENTER_FRAME, upDate);
stage.addEventListener(MouseEvent.CLICK, onClickHandler);
startRendering();
addChild(new Stats());
}
//========================================================================
// textの生成
//========================================================================
private function createText():void {
var sprite:Sprite = new Sprite();
var tf:TextField = new TextField();
tf.defaultTextFormat = new TextFormat("小塚ゴシック Pro H", 30, 0x000000, true);
tf.autoSize = TextFieldAutoSize.LEFT;
tf.text = "SELFISH\n X";
_textW = tf.textWidth;
_textH = tf.textHeight;
sprite.addChild(tf);
tf = new TextField();
tf.x = 10;
tf.y = 80;
tf.defaultTextFormat = new TextFormat("小塚ゴシック Pro H", 30, 0xCCFF33, true);
tf.autoSize = TextFieldAutoSize.LEFT;
tf.text = "FLASH";
_textW += tf.textWidth;
_textH += tf.textHeight + tf.y;
sprite.addChild(tf);
_bmd = new BitmapData(_textW + 2, _textH + 10, false, 0xFFFFFF);
_bmd.draw(sprite);
}
//========================================================================
// ClickHandler
// なんか知らないけど _flg = !_flg がうまくいかなかったから冗長なコードになってしまった
//========================================================================
public function onClickHandler(e:MouseEvent = null):void {
_startTime = getTimer();
_flg = true;
}
//========================================================================
// 常に行う処理
//========================================================================
private function upDate(e:Event):void {
_rotateX += (- viewport.containerSprite.mouseX - _rotateX) * 0.1;
_rotateY += (- viewport.containerSprite.mouseY - 170 - _rotateY) * 0.1;
_pixels.rotationY = _rotateX;
_pixels.rotationX = _rotateY;
_pixels.removeAllpixels();
var len:int = _particles.length;
for (_i = 0; _i < len; _i++) {
_p = _particles[_i];
_p.x = _p.tx;
_p.y = _p.ty;
_p.z = _p.tz;
var p3D:Pixel3D = new Pixel3D(_p.c, _p.x, _p.y, _p.z);
_pixels.addPixel3D(p3D);
}
if (_flg) sandAnimation();
}
//========================================================================
// 中身を作成する
// いわゆる具ね
//========================================================================
public function createBody(depth:int = 0, distance:Number = 2, color:Number = 0xFF000000):void {
var w:Number = _textW * .3;
var h:Number = _textH * .3;
if (!_particles)_particles = [];
for ( _y = 0; _y < _textH; _y += distance ) {
for ( _x = 0; _x < _textW; _x += distance ) {
_c = _bmd.getPixel( _x, _y );
if (_c != 0xFFFFFF) {
_p = (_particles[_i])?_particles[_i]:new Particle();
_p.tx = _x - w;
_p.ty = _y - h;
_p.tz = depth;
_p.c = color;
//_p.c = ColorUtil.toARGB(_c * 3, .7);
if (!_particles[_i]) {
_particles.push(_p);
}else {
_particles[_i] = _p;
}
_i++;
}
}
}
}
//========================================================================
// 枠組みを作成する
// newする時にプロパティ突っ込んだ方が軽いのかな~??
//========================================================================
public function createFrame(depth:int = 4, distance:Number = 1, color:Number = 0xFF000000):void {
var w:Number = _textW * .3;
var h:Number = _textH * .3;
if (!_particles)_particles = [];
for ( _y = 0; _y < _textH; _y += distance ) {
for ( _x = 0; _x < _textW; _x += distance ) {
_c = _bmd.getPixel( _x, _y );
if (_c != 0xFFFFFF) {
_p = (_particles[_i])?_particles[_i]:new Particle();
_p.tx = _x - w;
_p.ty = _y - h;
_p.tz = depth;
_p.c = color;
//_p.c = ColorUtil.toARGB(_c * .5, 1);
_a = (_y == 0)?0:_p.tx - _xy;
if(_a > distance || _a < - distance) {
if (!_particles[_i])
_particles.push(_p);
else
_particles[_i] = _p;
_i++;
}
_xy = _p.tx;
}
}
}
for ( _x = 0; _x < _textW; _x += distance ) {
for ( _y = 0; _y < _textH; _y += distance ) {
_c = _bmd.getPixel( _x, _y );
if (_c != 0xFFFFFF) {
_p = (_particles[_i])?_particles[_i]:new Particle();
_p.tx = _x - w;
_p.ty = _y - h;
_p.tz = depth;
_p.c = color;
//_p.c = ColorUtil.toARGB(_c * .5, 1);
_a = (_x == 0)?0:_p.ty - _xy;
if(_a > distance || _a < - distance) {
if (!_particles[_i])
_particles.push(_p);
else
_particles[_i] = _p;
_i++;
}
_xy = _p.ty;
}
}
}
for ( _y = _textH; _y > 0; _y -= distance ) {
for ( _x = _textW; _x > 0; _x -= distance ) {
_c = _bmd.getPixel( _x, _y );
if (_c != 0xFFFFFF) {
_p = (_particles[_i])?_particles[_i]:new Particle();
_p.tx = _x - w;
_p.ty = _y - h;
_p.tz = depth;
_p.c = color;
//_p.c = ColorUtil.toARGB(_c * .5, 1);
_a = (_y == _textH)?0:_p.tx - _xy;
if(_a > distance || _a < - distance) {
if (!_particles[_i])
_particles.push(_p);
else
_particles[_i] = _p;
_i++;
}
_xy = _p.tx;
}
}
}
for ( _x = _textW; _x > 0; _x -= distance ) {
for ( _y = _textH; _y > 0; _y -= distance ) {
_c = _bmd.getPixel( _x, _y );
if (_c != 0xFFFFFF) {
_p = (_particles[_i])?_particles[_i]:new Particle();
_p.tx = _x - w;
_p.ty = _y - h;
_p.tz = depth;
_p.c = color;
//_p.c = ColorUtil.toARGB(_c * .5, 1);
_a = (_x == _textW)?0:_p.ty - _xy;
if(_a > distance || _a < - distance) {
if (!_particles[_i])
_particles.push(_p);
else
_particles[_i] = _p;
_i++;
}
_xy = _p.ty;
}
}
}
}
//========================================================================
// 砂のアニメーション
// _flgがtrueの時に発動!!!!
//========================================================================
private function sandAnimation():void {
camera.z += (-150 - camera.z) * .2;
var wait:Number;
var now:int = getTimer();
for ( _i = 0; _i < _particles.length; _i++ ) {
_p = _particles[_i];
wait = (1 - ((_p.ty + _textH * .8) / _textH )) * 15000;
wait += (1 - ((_p.tx + _textW * .8) / _textW )) * 50000;
if (_startTime + wait > now) continue ;
if (_p.ty < 70) {
_p.vy = _p.vy * _p.af + _p.g;
_p.ty += _p.vy;
}else {
_p.ty = 70;
_p.vx = _p.vx * _p.gf * (Math.random() - .5) * 3;
_p.tx += _p.vx;
_p.vz = _p.vz * _p.gf * (Math.random() - .5) * 3;
_p.tz += _p.vz;
}
}
}
}
}
//========================================================================
// 座標、色情報を保持するプロパティ持ちすぎクラス
//========================================================================
class Particle {
public var x:Number;
public var y:Number;
public var z:Number;
public var c:int;
public var tx:Number;
public var ty:Number;
public var tz:Number;
public var g:Number = .98;
public var af:Number = .99;
public var gf:Number = .999999;
public var b:Number = .8;
public var vx:Number = 8;
public var vy:Number = 4;
public var vz:Number = 8;
}