@@ -4,6 +4,7 @@ const routes = {
44 "/contact" : "pages/contact.html" ,
55 "/test" : "pages/test.html" ,
66 "/projects" : "pages/projects.html" ,
7+ "/notebook" : "pages/notebook.html" ,
78} ;
89
910const app = document . getElementById ( "app" ) ;
@@ -34,54 +35,24 @@ const router = async () => {
3435 const response = await fetch ( route ) ;
3536 if ( ! response . ok ) throw new Error ( `Page not found: ${ route } ` ) ;
3637 const html = await response . text ( ) ;
37-
38- app . innerHTML = "" ; // Clear previous content
39-
40- const parser = new DOMParser ( ) ;
41- const doc = parser . parseFromString ( html , "text/html" ) ;
42-
43- Array . from ( doc . body . childNodes ) . forEach ( ( node ) => {
44- if ( node . nodeName === "SCRIPT" ) {
45- const script = document . createElement ( "script" ) ;
46- script . setAttribute ( "data-dynamic-script" , "true" ) ; // Mark as dynamic
47-
48- if ( node . src ) {
49- // Re-create the src to ensure it's correctly resolved
50- const scriptURL = new URL (
51- node . getAttribute ( "src" ) ,
52- window . location . href
53- ) ;
54- script . src = scriptURL . href ;
55- // Start animation after script loads
56- script . onload = ( ) => {
57- if (
58- window . pageAnimations &&
59- window . pageAnimations [ currentPage ] &&
60- typeof window . pageAnimations [ currentPage ] . start === "function"
61- ) {
62- window . pageAnimations [ currentPage ] . start ( ) ;
63- }
64- } ;
65- } else {
66- script . textContent = node . textContent ;
67- }
68- // Append to body to ensure execution
69- document . body . appendChild ( script ) ;
70-
71- // For inline scripts, start animation immediately after append
72- if ( ! node . src ) {
73- if (
74- window . pageAnimations &&
75- window . pageAnimations [ currentPage ] &&
76- typeof window . pageAnimations [ currentPage ] . start === "function"
77- ) {
78- window . pageAnimations [ currentPage ] . start ( ) ;
79- }
80- }
81- } else {
82- app . appendChild ( node . cloneNode ( true ) ) ;
38+ app . innerHTML = html ;
39+
40+ // Automatically load the corresponding script
41+ const scriptPath = route . replace ( ".html" , ".js" ) ;
42+ const script = document . createElement ( "script" ) ;
43+ script . src = scriptPath ;
44+ script . setAttribute ( "data-dynamic-script" , "true" ) ;
45+ document . body . appendChild ( script ) ;
46+
47+ script . onload = ( ) => {
48+ if (
49+ window . pageAnimations &&
50+ window . pageAnimations [ currentPage ] &&
51+ typeof window . pageAnimations [ currentPage ] . start === "function"
52+ ) {
53+ window . pageAnimations [ currentPage ] . start ( ) ;
8354 }
84- } ) ;
55+ } ;
8556 } catch ( error ) {
8657 console . error ( "Routing error:" , error ) ;
8758 app . innerHTML = "<h1>404 - Not Found</h1>" ;
@@ -132,7 +103,7 @@ document.addEventListener("DOMContentLoaded", () => {
132103 if ( matrixTimer > matrixInterval ) {
133104 const matrix = window . matrix ;
134105 if ( matrix && typeof matrix . draw === "function" ) {
135- matrix . draw ( ) ;
106+ matrix . draw ( deltaTime ) ;
136107 }
137108 matrixTimer = 0 ;
138109 }
@@ -177,44 +148,193 @@ const matrixEffect = (canvasId, containerSelector) => {
177148 const canvas = document . getElementById ( canvasId ) ;
178149 if ( ! canvas ) return null ;
179150 const ctx = canvas . getContext ( "2d" ) ;
151+ //const ctx = canvas.getContext("2d", {
152+ // willReadFrequently: true,
153+ //});
180154 const container = document . querySelector ( containerSelector ) ;
181155
182156 canvas . width = container . offsetWidth ;
183157 canvas . height = container . offsetHeight ;
184158
185159 const matrix = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789@#$%^&*()*&^%" ;
186160 const font_size = 10 ;
161+
162+ const circle_buffer_width = canvas . width / font_size ;
163+ const circle_buffer_height = canvas . height / font_size ;
187164 const columns = canvas . width / font_size ;
188165 const drops = [ ] ;
166+ const particles = [ ] ;
167+ const circle_buffer = new Int8Array (
168+ circle_buffer_width * circle_buffer_height
169+ ) ;
170+
171+ const maxParticles = 6 ;
189172
190- let beginMatrixEffect = true ;
191173 for ( let x = 0 ; x < columns ; x ++ ) {
192174 drops [ x ] = 1 ;
193175 }
194176 for ( let i = 0 ; i < drops . length ; i ++ ) {
195177 drops [ i ] = canvas . height / font_size ;
196178 }
179+ for ( let i = 0 ; i < maxParticles ; i ++ ) {
180+ particles . push ( {
181+ x : Math . random ( ) * canvas . width ,
182+ y : Math . random ( ) * canvas . height ,
183+ radius : Math . random ( ) * 50 + 75 ,
184+ speed : Math . random ( ) * 4 ,
185+ dir : vec2 ( Math . random ( ) - 0.5 , Math . random ( ) - 0.5 ) ,
186+ } ) ;
187+ }
188+
189+ function plotPixel ( x , y , v ) {
190+ const sx = Math . floor ( x ) | 0 ;
191+ const sy = Math . floor ( y ) | 0 ;
192+ const index = ( sy * circle_buffer_width + sx ) | 0 ;
193+ if (
194+ sx >= 0 &&
195+ sx < circle_buffer_width &&
196+ sy >= 0 &&
197+ sy < circle_buffer_height
198+ ) {
199+ circle_buffer [ index ] = v ;
200+ }
201+ }
197202
198- let frame = 0 ;
199- let hideIniitalEffect = true ;
203+ function plotOctants ( x , y , centerX , centerY ) {
204+ plotPixel ( centerX + x , centerY + y , 1 ) ;
205+ plotPixel ( centerX - x , centerY + y , 1 ) ;
206+ plotPixel ( centerX + x , centerY - y , 1 ) ;
207+ plotPixel ( centerX - x , centerY - y , 1 ) ;
208+ plotPixel ( centerX + y , centerY + x , 1 ) ;
209+ plotPixel ( centerX - y , centerY + x , 1 ) ;
210+ plotPixel ( centerX + y , centerY - x , 1 ) ;
211+ plotPixel ( centerX - y , centerY - x , 1 ) ;
212+ }
200213
201- function draw ( ) {
214+ function bresenhamCircle ( centerX , centerY , radius ) {
215+ centerX /= font_size ;
216+ centerY /= font_size ;
217+ radius /= font_size ;
218+ centerX = Math . floor ( centerX ) | 0 ;
219+ centerY = Math . floor ( centerY ) | 0 ;
220+ radius = Math . floor ( radius ) | 0 ;
221+ let x = 0 | 0 ;
222+ let y = radius | 0 ;
223+ let d = ( 3 - 2 * radius ) | 0 ;
224+ while ( y > x ) {
225+ x ++ ;
226+ if ( d > 0 ) {
227+ y -- ;
228+ d = ( d + 4 * ( x - y ) ) | 0 ;
229+ } else {
230+ d = ( d + 4 * x ) | 0 ;
231+ }
232+ plotOctants ( x , y , centerX , centerY ) ;
233+ }
234+ }
235+ const epsilon = 0.01 ;
236+
237+ function line ( x0 , y0 , x1 , y1 ) {
238+ x0 /= font_size ;
239+ y0 /= font_size ;
240+ x1 /= font_size ;
241+ y1 /= font_size ;
242+ x0 = Math . floor ( x0 ) | 0 ;
243+ y0 = Math . floor ( y0 ) | 0 ;
244+ x1 = Math . floor ( x1 ) | 0 ;
245+ y1 = Math . floor ( y1 ) | 0 ;
246+ const dx = Math . abs ( x1 - x0 ) ;
247+ const dy = Math . abs ( y1 - y0 ) ;
248+ const sx = Math . sign ( x1 - x0 ) ;
249+ const sy = Math . sign ( y1 - y0 ) ;
250+ let err = dx - dy ;
251+
252+ while ( true ) {
253+ plotPixel ( x0 , y0 , 2 ) ;
254+
255+ if ( Math . abs ( x0 - x1 ) + Math . abs ( y0 - y1 ) < epsilon ) break ;
256+
257+ const e2 = 2 * err ;
258+ if ( e2 > - dy ) {
259+ err -= dy ;
260+ x0 += sx ;
261+ }
262+ if ( e2 < dx ) {
263+ err += dx ;
264+ y0 += sy ;
265+ }
266+ }
267+ }
268+
269+ function drawCicleBuffer ( ) {
270+ ctx . fillStyle = "rgba(3, 94, 3, 1)" ;
271+ for ( let y = 0 ; y < circle_buffer_height ; y ++ ) {
272+ for ( let x = 0 ; x < circle_buffer_width ; x ++ ) {
273+ const index = ( y * circle_buffer_width + x ) | 0 ;
274+ const xx = ( x * font_size ) | 0 ;
275+ const yy = ( y * font_size ) | 0 ;
276+ if ( circle_buffer [ index ] > 0 ) {
277+ ctx . fillStyle = "rgba(0, 0, 0, 1)" ;
278+ ctx . fillRect ( xx , yy , font_size , font_size ) ;
279+ ctx . fillStyle = "rgba(5, 130, 5, 1)" ;
280+ const text = matrix [ Math . floor ( Math . random ( ) * matrix . length ) ] ;
281+ ctx . fillText ( text , xx , yy + font_size ) ;
282+ }
283+ }
284+ }
285+ }
286+
287+ function draw ( deltaTime ) {
202288 ctx . fillStyle = "rgba(0, 0, 0, 0.05)" ;
203289 ctx . fillRect ( 0 , 0 , canvas . width , canvas . height ) ;
204290
205- if ( hideIniitalEffect ) frame ++ ;
291+ // Set the fill color to green
292+ ctx . fillStyle = "green" ;
293+
294+ circle_buffer . fill ( 0 ) ;
295+
296+ for ( let i = 0 ; i < maxParticles ; i ++ ) {
297+ const p = particles [ i ] ;
298+ p . x += p . dir . x * p . speed ;
299+ p . y += p . dir . y * p . speed ;
300+ if ( p . x < 0 || p . x > canvas . width ) p . dir . x *= - 1 ;
301+ if ( p . y < 0 || p . y > canvas . height ) p . dir . y *= - 1 ;
302+ bresenhamCircle ( p . x , p . y , p . radius ) ;
303+ if ( Math . random ( ) < 0.01 ) {
304+ p . dir = vec2 ( Math . random ( ) - 0.5 , Math . random ( ) - 0.5 ) ;
305+ }
306+ // if (i > 0) {
307+ // line(
308+ // particles[i - 1].x,
309+ // particles[i - 1].y,
310+ // particles[i].x,
311+ // particles[i].y
312+ // );
313+ // }
314+ }
206315
207- //if (frame > drops.length) {
208- // hideIniitalEffect = false;
209316 ctx . fillStyle = "rgba(3, 94, 3, 1)" ;
210- //} else {
211- // ctx.fillStyle = "rgba(210, 15, 15, 1)";
212- //}
213317 ctx . font = font_size + "px arial" ;
214318
319+ drawCicleBuffer ( ) ;
215320 for ( let i = 0 ; i < drops . length ; i ++ ) {
216321 const text = matrix [ Math . floor ( Math . random ( ) * matrix . length ) ] ;
217- ctx . fillText ( text , i * font_size , drops [ i ] * font_size ) ;
322+
323+ const tx = i * font_size ;
324+ const ty = drops [ i ] * font_size ;
325+
326+ ctx . fillText ( text , tx , ty ) ;
327+
328+ const cx = tx / font_size ;
329+ const cy = ty / font_size ;
330+ const index = ( cy * circle_buffer_width + cx ) | 0 ;
331+ if ( circle_buffer [ index ] === 1 ) {
332+ ctx . fillStyle = "rgba(18, 215, 202, 1)" ;
333+ ctx . fillText ( "code" , tx , ty ) ;
334+ ctx . fillText ( "base" , tx + font_size , ty + font_size ) ;
335+ ctx . fillText ( "hack" , tx - font_size , ty + font_size ) ;
336+ }
337+ ctx . fillStyle = "rgba(3, 94, 3, 1)" ;
218338
219339 if ( drops [ i ] * font_size > canvas . height && Math . random ( ) > 0.975 ) {
220340 drops [ i ] = 0 ;
0 commit comments