Water Speach (inspired "Warter Talks") [Google API]
///////////////////////////////////////////////////
* FireFoxで見てください
*
/**
* Copyright romatica ( http://wonderfl.net/user/romatica )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/x36H
*/
/*
* ///////////////////////////////////////////////////
* FireFoxで見てください( ´д`; )
* ///////////////////////////////////////////////////
*
* [ "WARTER SPEACH" ] Google API
* スペース区切りで入力したテキストが、
* 1単語づつ、Speach & Drop。
*
*
* Safari/ChromeなどWebkit系からだと、音声が読み込めないそうです。
* @see http://twitter.com/clockmaker_core/status/14569180544
*
* また、同じくWebkit系だと最初の1単語しか表示されない。。。
* FireFoxで見てください( ´д`; )
*
* TODO:スペースを2つ続けるとバグる。あとでなおす(かも)。
* TODO:webkit系でもなんとかできないか調べる。
*
* @auther itoz(www.romatica.com)
*
* -----------------------
* ["Water Talks"] に Inspire。
* @see http://vimeo.com/10756110
*
* -----------------------
*
* "clock_marker"さんと"Saqoosha"さんのCODEをがっちゃんこ。
* @see http://wonderfl.net/c/rgyc/ [clock_marker:Text speech by Google API]
* @see http://wonderfl.net/c/25ff/ [Saqoosha:Rainy Day]
*
*
*/
package {
import com.bit101.components.InputText;
import com.bit101.components.PushButton;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.filters.BlurFilter;
import flash.filters.ColorMatrixFilter;
import flash.geom.Point;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.utils.Timer;
[SWF(width=465, height=465, backgroundColor=0x0, frameRate=120)]
public class WaterSpeach extends Sprite {
private static const GRAVITY : Number = 20;
private static const ZERO_POINT : Point = new Point( 0, 0 );
private var _canvas : BitmapData;
private var _drop : Vector.<SnowParticle>;
private var _blur : BlurFilter = new BlurFilter( 1.5, 1.5, 1 );
private var _input : InputText;
private var _splitArr : Array =[];
private var _tBMDArr : Array;
private var _sndArr : Array;
private var _timer : Timer;
private var _channel : SoundChannel;
private var speachLineCount : int = 0;
private var lineY : int;
private var _color : ColorMatrixFilter;
public function WaterSpeach()
{
//Wonderfl.capture_delay(1 )
//BG
var BG:Sprite = addChild(new Sprite()) as Sprite;
BG.graphics.beginFill(0x0);
BG.graphics.drawRect(0,0,465,465);
BG.graphics.endFill();
_color= new ColorMatrixFilter( [ 1, 0, 0, 0, -5,
0, 1, 0, 0, -5,
0, 0, 1, 0, -5,
0, 0, 0, 1, 0 ] );
_canvas = new BitmapData( 465, 465, true, 0x0 );
addChild( new Bitmap( this._canvas ) ) as Bitmap;
_drop = new Vector.<SnowParticle>( );
// Text Input
_input = new InputText( this, 50, 232, "Wonderful Build Flash Online", null );
_input.width = 210;
_input.maxChars = 90;
// Button
new PushButton( this, 270, 230, "WATER SPEACH", onClick );
//Start
setWaterSpeach();
}
private function onClick(e : MouseEvent=null) : void {
setWaterSpeach();
}
private function setWaterSpeach() : void
{
reset( );
_splitArr = [];
_tBMDArr = [];
_sndArr = [];
//split
_splitArr = _input.text.split( " " );
//入力テキストビットマップ化
createBitmaps( );
// サウンド作成
createSound( );
//スピーチスタート
startSpeati( );
//レンダリング
addEventListener( Event.ENTER_FRAME, this.update );
}
/**
*再入力時のリセット
*/
private function reset() : void
{
if(hasEventListener( Event.ENTER_FRAME )) {
addEventListener( Event.ENTER_FRAME, this.update );
}
crearChannel( );
crearTimer( );
for (var i : int = 0; i < _splitArr.length; i++) {
_sndArr[i] = null;
_tBMDArr[i].dispose( );
_tBMDArr[i] = null;
}
}
/**
* sound 作成し保管
*/
private function createSound() : void
{
for (var i : int = 0; i < _splitArr.length; i++) {
var req : URLRequest = new URLRequest( "http://translate.google.com/translate_tts" + "?tl=en" + "&q=" + String( _splitArr[i] ) );
var snd : Sound = new Sound( req );
_sndArr.push( snd );
}
}
/**
* bitmap 作成し保管
*/
private function createBitmaps() : void
{
for (var i : int = 0; i < _splitArr.length; i++) {
var tf : TextField = new TextField( );
tf.defaultTextFormat = new TextFormat( null, 90, 0xffffff, true );
tf.autoSize = TextFieldAutoSize.LEFT;
tf.text = _splitArr[i];
tf.x = (465 - tf.width) / 2;
var tBMD : BitmapData = new BitmapData( 465, tf.height, true, 0x0 );
tBMD.draw( tf, tf.transform.matrix );
_tBMDArr.push( tBMD );
}
}
/**
* one word speach start
*/
private function startSpeati(e : TimerEvent = null) : void
{
//trace( 'startSpeati: ' + (_splitArr[speachLineCount]) );
lineY = _tBMDArr[speachLineCount].height;
crearChannel( );
_channel = _sndArr[speachLineCount].play( 0, 1 );
_channel.addEventListener( Event.SOUND_COMPLETE, SoundCompFunc );
}
/**
* sound channel crear
*/
private function crearChannel() : void
{
if(_channel != null) {
if(_channel.hasEventListener( Event.SOUND_COMPLETE )) {
_channel.removeEventListener( Event.SOUND_COMPLETE, SoundCompFunc );
}
_channel = null;
}
}
/**
* one word speach fix
*/
private function SoundCompFunc(event : Event) : void
{
//trace( "1word最後まで再生された " + _splitArr [speachLineCount]);
crearTimer( )
//1秒後に次の単語再生
_timer = new Timer( 1000, 1 );
_timer.addEventListener( TimerEvent.TIMER, count );
_timer.start( );
}
/**
* timer clear
*/
private function crearTimer() : void
{
if(_timer != null) {
if(_timer.hasEventListener( TimerEvent.TIMER )) {
_timer.removeEventListener( TimerEvent.TIMER, startSpeati );
}
_timer = null;
}
}
/**
* word count check
*/
private function count(e : TimerEvent) : void
{
speachLineCount = (speachLineCount < _splitArr.length - 1) ? speachLineCount + 1 : 0;
startSpeati( );
}
/**
* DROP
*/
public function update(e : Event) : void
{
//Create 1 line 下から作成
if(lineY > 0) {
var xx : int = _tBMDArr[speachLineCount].width;
for (var lineX : int = 0; lineX < xx; lineX += 4) {
if(_tBMDArr[speachLineCount].getPixel( lineX, lineY ) != 0) {
_drop.push( emitParticle( lineX, 0, Math.random( ) * 0.03 + 0.5 ) );
}
}
lineY -= 2;
}
//move
_canvas.lock( );
_canvas.applyFilter( this._canvas, this._canvas.rect, ZERO_POINT, this._color );
_canvas.applyFilter( this._canvas, this._canvas.rect, ZERO_POINT, this._blur );
var max : int = _drop.length;
var gravity : Number = GRAVITY / 100;
while(max--) {
var p : SnowParticle = _drop[max];
p.vy += gravity * p.s; // まず重力を加える
p.y += p.vy;
_canvas.setPixel32( p.x, p.y, p.c | ((1 * 0xff) << 24) );
if (p.y > this.stage.stageHeight) {
// もし画面外にでちゃったら とりのぞく
_drop.splice( max, 1 );
}
}
_canvas.unlock( );
}
/**
* create 1DROP
*/
public function emitParticle(ex : Number, ey : Number, s : Number = 1, c : int = 0x00bfff, vx : Number = 0, vy : Number = 0) : SnowParticle
{
var p : SnowParticle = new SnowParticle( );
p.x = ex;
p.y = ey;
p.vx = vx;
p.vy = vy;
p.s = s;
p.c = c;
return p;
}
}
}
class SnowParticle {
public var x : Number;
public var y : Number;
public var vx : Number;
public var vy : Number;
public var s : Number;
public var c : int;
public function SnowParticle()
{
this.x = 0;
this.y = 0;
this.vx = 0;
this.vy = 0;
this.s = 1;
this.c = 0xffffff;
}
}