class Fire implements Effect { private width : number ; private height : number ; private palette : Uint8Array = new Uint8Array ( 256 * 4 ) ; private screen : Uint8Array = new Uint8Array ( 0 ) ; public async init ( width , height ) { this . width = width ; this . height = height ; this . screen = new Uint8Array ( this . width * ( this . height + 2 ) ) ; let vOfs = 0 ; for ( let v = 0 ; v < 256 ; v ++ ) { this . palette [ vOfs ++ ] = v >> 1 ; this . palette [ vOfs ++ ] = v >> 3 ; this . palette [ vOfs ++ ] = v >> 4 ; vOfs ++ ; } } public render ( ctx , _ ) { const dest = ctx . getImageData ( 0 , 0 , this . width , this . height ) ; let ofs = 0 ; for ( ; ofs < this . width * this . height ; ofs ++ ) { const y1 = ( this . screen [ ofs + this . width - 1 ] + this . screen [ ofs + this . width ] ) >> 1 ; const y2 = ( this . screen [ ofs + this . width * 2 ] + this . screen [ ofs + this . width * 2 + 1 ] ) >> 1 ; this . screen [ ofs ] = Math . max ( ( ( y1 + y2 ) >> 1 ) - 2 , 0 ) ; } for ( ; ofs < this . width * ( this . height + 2 ) ; ofs ++ ) { this . screen [ ofs ] = Math . random ( ) > 0.5 ? 255 : 0 ; } ofs = 0 ; for ( let destOfs = 0 ; destOfs < this . width * this . height * 4 ; ) { let pix = this . screen [ ofs ++ ] * 4 ; dest . data [ destOfs ++ ] = this . palette [ pix ++ ] ; dest . data [ destOfs ++ ] = this . palette [ pix ++ ] ; dest . data [ destOfs ++ ] = this . palette [ pix ++ ] ; dest . data [ destOfs ++ ] = 0xff ; } ctx . putImageData ( dest , 0 , 0 ) ; } } demoFX . register ( "fire" , new Fire ( ) ) ;