11'use strict'
22
3- // Initial ascii stuff (Look, I don't like creating a temporary canvas either, but...)
3+ function choose ( arr ) {
4+ return arr [ Math . floor ( Math . random ( ) * arr . length ) ]
5+ }
46
5- const context = document . createElement ( 'canvas' ) . getContext ( '2d' )
6- context . font = getComputedStyle ( document . querySelector ( '.ascii' ) ) . font
7+ // Initial ascii stuff (Look, I don't like creating a temporary canvas either, but...)
8+ const asciiStyle = getComputedStyle ( document . querySelector ( '.ascii' ) )
9+ const globalFont = asciiStyle . font
10+ const globalFontSize = asciiStyle . fontSize
11+ const globalFontFamily = asciiStyle . fontFamily
12+ let context = document . createElement ( 'canvas' ) . getContext ( '2d' )
13+ context . font = globalFont
714const charDimensions = context . measureText ( '.' ) // Monospace font assumed
815const charWidth = charDimensions . width
916const charHeight = charDimensions . fontBoundingBoxAscent
1017console . log ( `Using font: ${ context . font } ` )
1118console . log ( `Found ascii char width: ${ charWidth } px, ascii char height: ${ charHeight } px` )
19+ context = null ;
20+
21+ const screenWidthChars = Math . floor ( window . innerWidth / charWidth ) ;
22+ const screenHeightChars = Math . floor ( window . innerHeight / charHeight ) ;
1223
1324const seaElement = document . querySelector ( '.sea' )
14- const seaWidth = Math . floor ( window . innerWidth / charWidth ) ;
15- const seaHeight = Math . floor ( window . innerHeight / charHeight * .25 )
16- const seaTPS = 3 ;
25+ const seaWidth = screenWidthChars
26+ const seaHeight = Math . floor ( screenHeightChars / 4 )
27+ const seaTPS = 3
1728const seaText = [ ]
1829const seaChars = [ '~' ]
1930
31+ const overlay = document . querySelector ( '.overlay' )
32+ const overlayTPS = 1
33+ const overlayChars = [ 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , 'o' , 'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' , 'x' , 'y' , 'z' , '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '#' , '$' , '^' , '.' , ',' , '%' , '$' , '$' , '.' , '.' , ',' ]
34+ const ctx = overlay . getContext ( '2d' )
35+ const scale = window . devicePixelRatio
36+
37+ overlay . width = Math . floor ( window . innerWidth * scale )
38+ overlay . height = Math . floor ( window . innerHeight * scale )
39+ ctx . font = `${ Number ( globalFontSize . slice ( 0 , globalFontSize . length - 2 ) ) * 2 } px ${ globalFontFamily } `
40+ const s = ctx . measureText ( '.' )
41+ const w = s . width
42+ const h = s . fontBoundingBoxAscent
43+ function rgbToHex ( color ) {
44+ const rgba = color . replace ( / ^ r g b a ? \( | \s + | \) $ / g, '' ) . split ( ',' ) ;
45+ const hex = `#${ ( ( 1 << 24 ) + ( parseInt ( rgba [ 0 ] ) << 16 ) + ( parseInt ( rgba [ 1 ] ) << 8 ) + parseInt ( rgba [ 2 ] ) ) . toString ( 16 ) . slice ( 1 ) } ` ;
46+
47+ return hex ;
48+ }
49+ const fontHex = rgbToHex ( asciiStyle . color )
50+ window . setInterval ( ( ) => {
51+ ctx . clearRect ( 0 , 0 , overlay . width , overlay . height )
52+ for ( let i = 0 ; i < overlay . height / h ; i ++ ) {
53+ for ( let j = 0 ; j < overlay . width / w ; j ++ ) {
54+ let alpha = Math . floor ( i / ( overlay . height / h ) * 255 ) . toString ( 16 )
55+ if ( alpha . length == 1 ) {
56+ alpha = '0' + alpha
57+ }
58+ ctx . fillStyle = `${ fontHex } ${ alpha } `
59+ ctx . fillText ( choose ( overlayChars ) , j * w , ( i + 1 ) * h ) ;
60+ }
61+ }
62+ } , 1000 / 5 )
63+
2064function setOptimizedInterval ( element , render , tps ) {
2165 render ( )
2266 let handle = setInterval ( render , 1000 / tps )
@@ -43,17 +87,3 @@ function setOptimizedInterval(element, render, tps) {
4387function randomSeaChar ( ) {
4488 return seaChars [ Math . floor ( Math . random ( ) * seaChars . length ) ]
4589}
46-
47- function updateSea ( ) {
48- seaText . length = 0
49- for ( let i = 0 ; i < seaHeight ; i ++ ) {
50- for ( let j = 0 ; j < seaWidth ; j ++ ) {
51- seaText . push ( ( Math . random ( ) > ( 0.9 * i / seaHeight + 0.1 ) ) ? randomSeaChar ( ) : ' ' )
52- }
53- seaText . push ( '\n' )
54- }
55-
56- seaElement . innerText = seaText . join ( '' )
57- }
58-
59- setOptimizedInterval ( seaElement , updateSea , seaTPS )
0 commit comments