11// Wait for the DOM content to fully load
22document . addEventListener ( "DOMContentLoaded" , ( ) => {
3- fetch ( 'load/header.html' ) // Fetch the header HTML from the server
4- . then ( response => response . text ( ) )
5- . then ( data => {
6- document . querySelector ( 'header' ) . innerHTML = data ; // Inject the header content
7- } ) ;
3+ fetch ( 'load/header.html' )
4+ . then ( response => response . text ( ) )
5+ . then ( data => {
6+ document . querySelector ( 'header' ) . innerHTML = data ;
7+ } ) ;
88} ) ;
99
1010document . addEventListener ( 'DOMContentLoaded' , ( ) => {
11- // Set active nav link based on current page
1211 const currentPage = window . location . pathname . split ( '/' ) . pop ( ) ;
1312 const navLinks = document . querySelectorAll ( '.nav-link' ) ;
1413
@@ -17,7 +16,6 @@ document.addEventListener('DOMContentLoaded', () => {
1716 link . classList . add ( 'active' ) ;
1817 }
1918
20- // Add hover effect
2119 link . addEventListener ( 'mouseenter' , ( e ) => {
2220 const img = e . currentTarget . querySelector ( 'img' ) ;
2321 img . style . transform = 'scale(1.1) rotate(5deg)' ;
@@ -30,173 +28,154 @@ document.addEventListener('DOMContentLoaded', () => {
3028 } ) ;
3129} ) ;
3230
33- // Include the 'matter-wrap' plugin
3431Matter . use ( 'matter-wrap' ) ;
3532
36- // HexBokeh: A customizable background effect using Matter.js
3733let hexBokeh = {
38- // Default options for customization
39- options : {
40- canvasSelector : '' , // CSS selector for the canvas element
41- radiusRange : [ 30 , 60 ] , // Random range of hexagon radii
42- xVarianceRange : [ 0.1 , 0.3 ] , // X velocity scaling range
43- yVarianceRange : [ 0.5 , 1.5 ] , // Y velocity scaling range
44- airFriction : 0.03 , // Air friction applied to the bodies
45- opacity : 0.5 , // Opacity of the hexagons
46- collisions : false , // Enable or disable collisions
47- scrollVelocity : 0.025 , // Effect of scroll on body velocities
48- pixelsPerBody : 40000 , // Pixels in viewport per hexagon
49- colors : [ '#7ef2cf' , '#bea6ff' , '#8ccdff' ] // Hexagon fill colors
50- } ,
51-
52- // Delays for scroll and resize event throttling
53- scrollDelay : 100 ,
54- resizeDelay : 400 ,
55-
56- // Variables to track event state
57- lastOffset : undefined ,
58- scrollTimeout : undefined ,
59- resizeTimeout : undefined ,
60-
61- // Matter.js components
62- engine : undefined ,
63- render : undefined ,
64- runner : undefined ,
65- bodies : undefined ,
66-
67- // Initialize the effect
68- init ( options ) {
69- // Merge provided options with defaults
70- this . options = Object . assign ( { } , this . options , options ) ;
71-
72- let viewportWidth = document . documentElement . clientWidth ;
73- let viewportHeight = document . documentElement . clientHeight ;
74-
75- this . lastOffset = window . pageYOffset ;
76- this . scrollTimeout = null ;
77- this . resizeTimeout = null ;
78-
79- // Create Matter.js engine
80- this . engine = Matter . Engine . create ( ) ;
81- this . engine . world . gravity . y = 0 ;
82-
83- // Create renderer
84- this . render = Matter . Render . create ( {
85- canvas : document . querySelector ( this . options . canvasSelector ) ,
86- engine : this . engine ,
87- options : {
88- width : viewportWidth ,
89- height : viewportHeight ,
90- wireframes : false ,
91- background : 'transparent'
92- }
93- } ) ;
94- Matter . Render . run ( this . render ) ;
95-
96- // Create runner
97- this . runner = Matter . Runner . create ( ) ;
98- Matter . Runner . run ( this . runner , this . engine ) ;
99-
100- // Create and add bodies to the engine
101- this . bodies = [ ] ;
102- let totalBodies = Math . round ( viewportWidth * viewportHeight / this . options . pixelsPerBody ) ;
103- for ( let i = 0 ; i <= totalBodies ; i ++ ) {
104- let body = this . createBody ( viewportWidth , viewportHeight ) ;
105- this . bodies . push ( body ) ;
106- }
107- Matter . World . add ( this . engine . world , this . bodies ) ;
108-
109- // Attach event listeners for scroll and resize
110- window . addEventListener ( 'scroll' , this . onScrollThrottled . bind ( this ) ) ;
111- window . addEventListener ( 'resize' , this . onResizeThrottled . bind ( this ) ) ;
112- } ,
113-
114- // Shutdown and clean up the engine
115- shutdown ( ) {
116- Matter . Engine . clear ( this . engine ) ;
117- Matter . Render . stop ( this . render ) ;
118- Matter . Runner . stop ( this . runner ) ;
119-
120- window . removeEventListener ( 'scroll' , this . onScrollThrottled ) ;
121- window . removeEventListener ( 'resize' , this . onResizeThrottled ) ;
122- } ,
123-
124- // Generate a random number within a range
125- randomize ( range ) {
126- let [ min , max ] = range ;
127- return Math . random ( ) * ( max - min ) + min ;
128- } ,
129-
130- // Create a hexagonal body with random properties
131- createBody ( viewportWidth , viewportHeight ) {
132- let x = this . randomize ( [ 0 , viewportWidth ] ) ;
133- let y = this . randomize ( [ 0 , viewportHeight ] ) ;
134- let radius = this . randomize ( this . options . radiusRange ) ;
135- let color = this . options . colors [ this . bodies . length % this . options . colors . length ] ;
136-
137- return Matter . Bodies . polygon ( x , y , 6 , radius , {
138- render : {
139- fillStyle : color ,
140- opacity : this . options . opacity
141- } ,
142- frictionAir : this . options . airFriction ,
143- collisionFilter : {
144- group : this . options . collisions ? 1 : - 1
145- } ,
146- plugin : {
147- wrap : {
148- min : { x : 0 , y : 0 } ,
149- max : { x : viewportWidth , y : viewportHeight }
150- }
151- }
152- } ) ;
153- } ,
154-
155- // Handle scroll events (throttled)
156- onScrollThrottled ( ) {
157- if ( ! this . scrollTimeout ) {
158- this . scrollTimeout = setTimeout ( this . onScroll . bind ( this ) , this . scrollDelay ) ;
159- }
160- } ,
161-
162- // Update body velocities based on scroll movement
163- onScroll ( ) {
164- this . scrollTimeout = null ;
165-
166- let delta = ( this . lastOffset - window . pageYOffset ) * this . options . scrollVelocity ;
167- this . bodies . forEach ( ( body ) => {
168- Matter . Body . setVelocity ( body , {
169- x : body . velocity . x + delta * this . randomize ( this . options . xVarianceRange ) ,
170- y : body . velocity . y + delta * this . randomize ( this . options . yVarianceRange )
171- } ) ;
172- } ) ;
173-
174- this . lastOffset = window . pageYOffset ;
175- } ,
176-
177- // Handle resize events (throttled)
178- onResizeThrottled ( ) {
179- if ( ! this . resizeTimeout ) {
180- this . resizeTimeout = setTimeout ( this . onResize . bind ( this ) , this . resizeDelay ) ;
181- }
182- } ,
183-
184- // Restart the engine with updated dimensions
185- onResize ( ) {
186- this . shutdown ( ) ;
187- this . init ( ) ;
188- }
34+ options : {
35+ canvasSelector : '' ,
36+ radiusRange : [ 30 , 60 ] ,
37+ xVarianceRange : [ 0.1 , 0.3 ] ,
38+ yVarianceRange : [ 0.5 , 1.5 ] ,
39+ airFriction : 0.03 ,
40+ opacity : 0.5 ,
41+ collisions : false ,
42+ scrollVelocity : 0.025 ,
43+ pixelsPerBody : 40000 ,
44+ colors : [ '#7ef2cf' , '#bea6ff' , '#8ccdff' ]
45+ } ,
46+
47+ scrollDelay : 100 ,
48+ resizeDelay : 400 ,
49+ lastOffset : undefined ,
50+ scrollTimeout : undefined ,
51+ resizeTimeout : undefined ,
52+ engine : undefined ,
53+ render : undefined ,
54+ runner : undefined ,
55+ bodies : undefined ,
56+
57+ init ( options ) {
58+ this . options = Object . assign ( { } , this . options , options ) ;
59+
60+ let viewportWidth = document . documentElement . clientWidth ;
61+ let documentHeight = Math . max (
62+ document . body . scrollHeight ,
63+ document . documentElement . scrollHeight
64+ ) ;
65+
66+ this . lastOffset = window . pageYOffset ;
67+ this . scrollTimeout = null ;
68+ this . resizeTimeout = null ;
69+
70+ this . engine = Matter . Engine . create ( ) ;
71+ this . engine . world . gravity . y = 0 ;
72+
73+ this . render = Matter . Render . create ( {
74+ canvas : document . querySelector ( this . options . canvasSelector ) ,
75+ engine : this . engine ,
76+ options : {
77+ width : viewportWidth ,
78+ height : documentHeight ,
79+ wireframes : false ,
80+ background : 'transparent'
81+ }
82+ } ) ;
83+ Matter . Render . run ( this . render ) ;
84+
85+ this . runner = Matter . Runner . create ( ) ;
86+ Matter . Runner . run ( this . runner , this . engine ) ;
87+
88+ this . bodies = [ ] ;
89+ let totalBodies = Math . round ( viewportWidth * documentHeight / this . options . pixelsPerBody ) ;
90+
91+ for ( let i = 0 ; i <= totalBodies ; i ++ ) {
92+ let body = this . createBody ( viewportWidth , documentHeight ) ;
93+ this . bodies . push ( body ) ;
94+ }
95+ Matter . World . add ( this . engine . world , this . bodies ) ;
96+
97+ window . addEventListener ( 'scroll' , this . onScrollThrottled . bind ( this ) ) ;
98+ window . addEventListener ( 'resize' , this . onResizeThrottled . bind ( this ) ) ;
99+ } ,
100+
101+ shutdown ( ) {
102+ Matter . Engine . clear ( this . engine ) ;
103+ Matter . Render . stop ( this . render ) ;
104+ Matter . Runner . stop ( this . runner ) ;
105+
106+ window . removeEventListener ( 'scroll' , this . onScrollThrottled ) ;
107+ window . removeEventListener ( 'resize' , this . onResizeThrottled ) ;
108+ } ,
109+
110+ randomize ( range ) {
111+ let [ min , max ] = range ;
112+ return Math . random ( ) * ( max - min ) + min ;
113+ } ,
114+
115+ createBody ( viewportWidth , documentHeight ) {
116+ let x = this . randomize ( [ 0 , viewportWidth ] ) ;
117+ let y = this . randomize ( [ 0 , documentHeight ] ) ;
118+ let radius = this . randomize ( this . options . radiusRange ) ;
119+ let color = this . options . colors [ this . bodies . length % this . options . colors . length ] ;
120+
121+ return Matter . Bodies . polygon ( x , y , 6 , radius , {
122+ render : {
123+ fillStyle : color ,
124+ opacity : this . options . opacity
125+ } ,
126+ frictionAir : this . options . airFriction ,
127+ collisionFilter : {
128+ group : this . options . collisions ? 1 : - 1
129+ } ,
130+ plugin : {
131+ wrap : {
132+ min : { x : 0 , y : 0 } ,
133+ max : { x : viewportWidth , y : documentHeight }
134+ }
135+ }
136+ } ) ;
137+ } ,
138+
139+ onScrollThrottled ( ) {
140+ if ( ! this . scrollTimeout ) {
141+ this . scrollTimeout = setTimeout ( this . onScroll . bind ( this ) , this . scrollDelay ) ;
142+ }
143+ } ,
144+
145+ onScroll ( ) {
146+ this . scrollTimeout = null ;
147+ let delta = ( this . lastOffset - window . pageYOffset ) * this . options . scrollVelocity ;
148+
149+ this . bodies . forEach ( ( body ) => {
150+ Matter . Body . setVelocity ( body , {
151+ x : body . velocity . x + delta * this . randomize ( this . options . xVarianceRange ) ,
152+ y : body . velocity . y + delta * this . randomize ( this . options . yVarianceRange )
153+ } ) ;
154+ } ) ;
155+
156+ this . lastOffset = window . pageYOffset ;
157+ } ,
158+
159+ onResizeThrottled ( ) {
160+ if ( ! this . resizeTimeout ) {
161+ this . resizeTimeout = setTimeout ( this . onResize . bind ( this ) , this . resizeDelay ) ;
162+ }
163+ } ,
164+
165+ onResize ( ) {
166+ this . shutdown ( ) ;
167+ this . init ( this . options ) ;
168+ }
189169} ;
190170
191- // Wait for the DOM content to load and initialize HexBokeh
192171window . addEventListener ( 'DOMContentLoaded' , ( ) => {
193172 Object . create ( hexBokeh ) . init ( {
194173 canvasSelector : '#bg1' ,
195174 radiusRange : [ 20 , 90 ] ,
196175 colors : [
197- 'rgba(87, 17, 148, 0.6)' , // Purple
198- 'rgba(30, 92, 143, 0.6)' , // Blue
199- 'rgba(231, 223, 105, 0.4)' , // Accent
176+ 'rgba(87, 17, 148, 0.6)' ,
177+ 'rgba(30, 92, 143, 0.6)' ,
178+ 'rgba(231, 223, 105, 0.4)' ,
200179 ] ,
201180 pixelsPerBody : 25000 ,
202181 scrollVelocity : 0.015 ,
@@ -205,26 +184,19 @@ window.addEventListener('DOMContentLoaded', () => {
205184 } ) ;
206185} ) ;
207186
208-
209-
210-
211- // Get the text content from the element with ID "type"
187+ // Typing effect
212188var string = document . getElementById ( "type" ) . textContent ;
213189var array = string . split ( "" ) ;
214190var timer ;
215191
216192function frameLooper ( ) {
217- if ( array . length > 0 ) {
218- // Append each character to the element with ID "type"
219- document . getElementById ( "type" ) . innerHTML += array . shift ( ) ;
220- } else {
221- // Clear the timer when the string is fully typed
222- clearTimeout ( timer ) ;
223- }
224- // Call the function again after the specified delay (70ms in this case)
225- timer = setTimeout ( frameLooper , 70 ) ; // change 70 for speed
193+ if ( array . length > 0 ) {
194+ document . getElementById ( "type" ) . innerHTML += array . shift ( ) ;
195+ } else {
196+ clearTimeout ( timer ) ;
197+ }
198+ timer = setTimeout ( frameLooper , 70 ) ;
226199}
227200
228- // Clear the initial text in the "type" element and start the typing effect
229201document . getElementById ( "type" ) . innerHTML = "" ;
230202frameLooper ( ) ;
0 commit comments