/* * /////////////////////////////////////////////////// * 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; } } Water Speach (inspired "Warter Talks") [Google API]