キンチョウの夏? 一足早く、クリックしたらJavaScriptで花火!

まだまだ洗練されてない。無駄も多いっす。
最初は、1つの輪だけしかなかったのだけど、
調子こいて、new を連呼しちゃった〜!
オブジェクト作りっぱなしで良いのか?
eColorの配列を暗めの色にするとか、できれば、色1-色2-そして黒といけば綺麗か?
やっぱり、突然消える火も風情がないなぁ〜
やっぱり、3次元に展開して、球体にひろがるようにすれば綺麗か?
やっぱり、初速が速く、だんだん遅くなるといい感じか?
やっぱり、重力も考慮して後半はダレるといい感じ?
やっぱり、火の点が、ピリオドの文字はないだろう!?(★もださくない?!)
やっぱり、その点の大きさを変化させるとか
やっぱり、奥行きで、透明度を変えるとか・・・
クリックしたら、画面下から sin 曲線で上るやつも加えるか!?

いや!きっとそこまでやったら、俺は、お馬鹿になれるかもしれない!
でも、そんなことしたら、火の点の数は20個程度だな!
そしたら線香花火以下か・・・。
さっぱりだ。


教えられても、さっぱりだな俺・・・(泣)
this とか view を考えながらと思ったのですが、花火にハマッちまった!
本末転倒!
またもや書きかけです・・。つっこまれても、徹夜明けは眠いぞ!
返事できないかもしれません!
あんまり画面をクリックしすぎないようにね!

  • 追記

昼過ぎに、一部書き換えました。
無名関数で、囲ってから、好き勝手に関数を書いて、後から、prototype にくっつけるやり方は、
案外楽な書き方に思えてきた。昔のグローバル変数やらその場しのぎの関数をふんだんに使っていたころの
書き方に似ている。ふとそう思った。


昨日からのマウスのクリック回数は、すでに1000回は超えたな!
少しコードを見直して、高速化(?)してみた。そこそこ花火を発火させても、いけるかも?

<!DOCTYPE html>
<title></title>

<style type="text/css">
body{ background:#000 }
</style>

<body>
<h1>Hanabi</h1>
<script type="text/javascript">
//@cc_on
(function ( ) {

  var colorType = [
    [ 255, 0,   0 ], [ 0, 255,   0 ], [ 0, 0, 255 ], [ 255, 255, 0 ],
    [ 255, 0, 255 ], [ 0, 255, 255 ], [ 255, 255, 255]
  ];
  
  var dg = Math.PI / 180;
  
  var getStar = function( ) {
    var str = '●○◎*。・☆'.split('');
    return str[ str.length * Math.random() |0 ];
  };
  
  function Hanabi ( ) {
    this.make.apply( this, arguments );
    this.start();
  }


  function make ( div, x, y, size, volume, sColor, eColor, life  ) {
    this.div = div;
    this.nodes = [ ];
    this.life = life;
    this.timerId = null;
    this.sr = ( eColor[0] - sColor[0] ) / life;
    this.sg = ( eColor[1] - sColor[1] ) / life;
    this.sb = ( eColor[2] - sColor[2] ) / life;

    var doc = div.ownerDocument;
    var i = volume, n, d = 0, s, r = size / life, t = 360 / volume * dg;
    

    n = doc.createElement('span');
    n.appendChild( doc.createTextNode( getStar()) );
    s = n.style;
    s.top = y + 'px';
    s.left = x + 'px';
    s.color = '#f00';
    s.position = 'absolute';


    for( i = 0; i < volume; i++ ) {
      this.nodes.push( [
        this.div.appendChild( n.cloneNode( true ) ),
        x, y, sColor[0], sColor[1], sColor[2], Math.sin( d ) * r, Math.cos( d ) * r
      ]);
      d += t;
    }
  }


  function start ( ) {
    var that = this;
    var cbFunc = function ( ) { fire.call(that); };
    
    if( !this.timerId )
      this.timerId = setInterval( cbFunc, 30 );
  }
  
 
  function set( n ) {
    var style   = n[0].style;
    style.left  = n[1] + 'px';
    style.top   = n[2] + 'px';
    style.color = 'rgb(' + (n[3]|0) + ',' + (n[4]|0) + ',' + (n[5]|0) + ')';
  }

  
  function fire( ) {
    var i = 0, n;
    if( --this.life ) {
      while( n = this.nodes[ i++ ] ) {
        n[1] += n[6];
        n[2] += n[7];
        n[3] += this.sr;
        n[4] += this.sg;
        n[5] += this.sb;
        set( n );
      }
    } else {
      clearInterval( this.timerId );
      this.del();
    }
  }
  
  
  function del( ) {
    var i = 0, p = this.div, o;
    while( o = this.nodes[i++] )
      p.removeChild( o[0] );
    delete this;
  }

  
  function create ( x, y, size, volume, sColor, eColor, life ) {
    size   = size   || ( 200 + 200 * Math.random() |0);
    volume = volume || (  24 + 12  * Math.random() |0);
    sColor = colorType[ colorType.length * Math.random() |0];
    eColor = colorType[ colorType.length * Math.random() |0];
    life   = 30 + Math.random() * 30 |0;

    new Hanabi( this, x, y, size, volume, sColor, eColor, life );
    new Hanabi( this, x, y, size / 1.4, volume /1.4 , sColor, eColor, life );
    new Hanabi( this, x, y, size / 2, volume /2 , sColor, eColor, life );
    new Hanabi( this, x, y, size / 2.8, volume /2.8 , sColor, eColor, life );
    new Hanabi( this, x, y, size / 4, volume /4 , sColor, eColor, life );
    new Hanabi( this, x, y, size / 5.6, volume /5.6 , sColor, eColor, life );
    new Hanabi( this, x, y, size / 8, volume /8 , sColor, eColor, life );
  }

  
  function init( view ) {
    var doc = view.document;
    var div = doc.createElement( 'div' );
    var style = div.style;

    style.position = 'absolute';
    style.top      = '0px';
    style.left     = '0px';
    doc.body.appendChild( div );


    function onClick ( e ) {
      var x = e./*@if( @_jscript ) x + doc.body.scrollLeft @else@*/ pageX /*@end@*/,
          y = e./*@if( @_jscript ) y + doc.body.scrollTop  @else@*/ pageY /*@end@*/;
      create.call( div, x, y );
    };


    function onUnload(e) {
      //Click
      doc./*@if( @_jscript )
        detachEvent( 'on' + @else@*/
        removeEventListener( /*@end@*/
          'click', onClick, false );

      //unLoad
      view./*@if( @_jscript )
        detachEvent( 'on' + @else@*/
        removeEventListener( /*@end@*/
          'unload', onUnload, false );

      //all null
      view = doc = Hanabi = div = style = onClick = onUnload = null;
    }

    
    //Click 
    doc./*@if( @_jscript )
      attachEvent( 'on' + @else@*/
      addEventListener( /*@end@*/
        'click', onClick, false );

    //unLoad
    view./*@if( @_jscript )
      attachEvent( 'on' + @else@*/
      addEventListener( /*@end@*/
        'unload', onUnload, false );
  }
  
  //____________________________

  Hanabi.init = init;
  Hanabi.prototype.make = make;
  Hanabi.prototype.fire = fire;
  Hanabi.prototype.start = start;
  Hanabi.prototype.del = del;
  
  this.Hanabi = Hanabi;
})();

Hanabi.init( this );

</script>