@@ -49,62 +49,90 @@ function delay(ms) {
4949 return new Promise ( ( resolve ) => window . setTimeout ( resolve , ms ) ) ;
5050}
5151
52- function renderStaticTerminal ( ) {
52+ function renderSessionMarkup ( session ) {
53+ return session
54+ . map ( ( frame ) => `<span class="line ${ frame . className } ">${ frame . text } </span>` )
55+ . join ( "" ) ;
56+ }
57+
58+ function renderStaticTerminal ( sessionIndex = 0 ) {
5359 if ( ! typedTerminal ) return ;
60+ typedTerminal . innerHTML = `${ renderSessionMarkup ( sessions [ sessionIndex ] ) } <span class="cursor" aria-hidden="true"></span>` ;
61+ }
5462
55- const lines = sessions . flatMap ( ( session , index ) => {
56- const sessionLines = session . map ( ( frame ) => `<span class="line ${ frame . className } ">${ frame . text } </span>` ) ;
57- if ( index < sessions . length - 1 ) {
58- sessionLines . push ( '<span class="line comment">---</span>' ) ;
59- }
60- return sessionLines ;
61- } ) ;
63+ async function playReducedMotionLoop ( ) {
64+ if ( ! typedTerminal ) return ;
65+
66+ let index = 0 ;
67+ renderStaticTerminal ( index ) ;
68+
69+ while ( true ) {
70+ await delay ( 2400 ) ;
71+ typedTerminal . classList . add ( "is-switching" ) ;
72+ await delay ( 220 ) ;
73+ index = ( index + 1 ) % sessions . length ;
74+ renderStaticTerminal ( index ) ;
75+ typedTerminal . classList . remove ( "is-switching" ) ;
76+ }
77+ }
6278
63- typedTerminal . innerHTML = `${ lines . join ( "" ) } <span class="cursor" aria-hidden="true"></span>` ;
79+ async function typeLine ( line , text ) {
80+ for ( const character of text ) {
81+ line . textContent += character ;
82+ await delay ( 16 ) ;
83+ }
84+ }
85+
86+ async function eraseLine ( line ) {
87+ while ( line . textContent . length > 0 ) {
88+ line . textContent = line . textContent . slice ( 0 , - 1 ) ;
89+ await delay ( 8 ) ;
90+ }
6491}
6592
6693async function playTerminalLoop ( ) {
6794 if ( ! typedTerminal ) return ;
6895 if ( prefersReducedMotion ) {
69- renderStaticTerminal ( ) ;
96+ await playReducedMotionLoop ( ) ;
7097 return ;
7198 }
7299
100+ const lines = [ ] ;
101+
73102 while ( true ) {
74103 typedTerminal . innerHTML = "" ;
104+ lines . length = 0 ;
75105
76- for ( let s = 0 ; s < sessions . length ; s += 1 ) {
77- const session = sessions [ s ] ;
78-
106+ for ( const session of sessions ) {
79107 for ( const frame of session ) {
80108 const line = document . createElement ( "span" ) ;
81109 line . className = `line ${ frame . className } ` ;
82110 typedTerminal . appendChild ( line ) ;
111+ lines . push ( line ) ;
83112
84- for ( const character of frame . text ) {
85- line . textContent += character ;
86- await delay ( 16 ) ;
87- }
88-
89- await delay ( 180 ) ;
113+ await typeLine ( line , frame . text ) ;
114+ await delay ( 120 ) ;
90115 }
91116
92- if ( s < sessions . length - 1 ) {
93- const spacer = document . createElement ( "span" ) ;
94- spacer . className = "line comment" ;
95- spacer . textContent = "---" ;
96- typedTerminal . appendChild ( spacer ) ;
97- }
117+ const cursor = document . createElement ( "span" ) ;
118+ cursor . className = "cursor" ;
119+ cursor . setAttribute ( "aria-hidden" , "true" ) ;
120+ typedTerminal . appendChild ( cursor ) ;
98121
99- await delay ( 520 ) ;
100- }
122+ await delay ( 900 ) ;
123+ cursor . remove ( ) ;
101124
102- const cursor = document . createElement ( "span" ) ;
103- cursor . className = "cursor" ;
104- cursor . setAttribute ( "aria-hidden" , "true" ) ;
105- typedTerminal . appendChild ( cursor ) ;
125+ for ( let i = lines . length - 1 ; i >= 0 ; i -= 1 ) {
126+ await eraseLine ( lines [ i ] ) ;
127+ lines [ i ] . remove ( ) ;
128+ lines . pop ( ) ;
129+ await delay ( 40 ) ;
130+ }
106131
107- await delay ( 1800 ) ;
132+ typedTerminal . classList . add ( "is-switching" ) ;
133+ await delay ( 140 ) ;
134+ typedTerminal . classList . remove ( "is-switching" ) ;
135+ }
108136 }
109137}
110138
0 commit comments