11document . addEventListener ( 'DOMContentLoaded' , ( ) => {
2- const randomPalettes = [
3- // Palette 1
4- {
5- '--bg-color' : '#f0e6f2' ,
6- '--text-color' : '#4a235a' ,
7- '--link-color' : '#8e44ad' ,
8- '--caption-color' : '#c0392b' ,
9- '--header-color' : '#4a235a' ,
10- '--body-bg-color' : '#f0e6f2' ,
11- '--body-text-color' : '#4a235a'
12- } ,
13- // Palette 2
14- {
15- '--bg-color' : '#e8f8f5' ,
16- '--text-color' : '#117a65' ,
17- '--link-color' : '#1abc9c' ,
18- '--caption-color' : '#d35400' ,
19- '--header-color' : '#117a65' ,
20- '--body-bg-color' : '#e8f8f5' ,
21- '--body-text-color' : '#117a65'
22- } ,
23- // Palette 3
24- {
25- '--bg-color' : '#fef9e7' ,
26- '--text-color' : '#b07e0c' ,
27- '--link-color' : '#f39c12' ,
28- '--caption-color' : '#2c3e50' ,
29- '--header-color' : '#b07e0c' ,
30- '--body-bg-color' : '#fef9e7' ,
31- '--body-text-color' : '#b07e0c'
32- } ,
33- // Palette 4
34- {
35- '--bg-color' : '#e3f2fd' ,
36- '--text-color' : '#1565c0' ,
37- '--link-color' : '#2196f3' ,
38- '--caption-color' : '#d32f2f' ,
39- '--header-color' : '#1565c0' ,
40- '--body-bg-color' : '#e3f2fd' ,
41- '--body-text-color' : '#1565c0'
42- } ,
43- // Palette 5
44- {
45- '--bg-color' : '#fce4ec' ,
46- '--text-color' : '#c2185b' ,
47- '--link-color' : '#e91e63' ,
48- '--caption-color' : '#00796b' ,
49- '--header-color' : '#c2185b' ,
50- '--body-bg-color' : '#fce4ec' ,
51- '--body-text-color' : '#c2185b'
52- } ,
53- // Palette 6
54- {
55- '--bg-color' : '#f1f8e9' ,
56- '--text-color' : '#558b2f' ,
57- '--link-color' : '#8bc34a' ,
58- '--caption-color' : '#fbc02d' ,
59- '--header-color' : '#558b2f' ,
60- '--body-bg-color' : '#f1f8e9' ,
61- '--body-text-color' : '#558b2f'
62- } ,
63- // Palette 7
64- {
65- '--bg-color' : '#e0f7fa' ,
66- '--text-color' : '#00838f' ,
67- '--link-color' : '#00bcd4' ,
68- '--caption-color' : '#e65100' ,
69- '--header-color' : '#00838f' ,
70- '--body-bg-color' : '#e0f7fa' ,
71- '--body-text-color' : '#00838f'
72- } ,
73- // Palette 8
74- {
75- '--bg-color' : '#fff3e0' ,
76- '--text-color' : '#ef6c00' ,
77- '--link-color' : '#ff9800' ,
78- '--caption-color' : '#607d8b' ,
79- '--header-color' : '#ef6c00' ,
80- '--body-bg-color' : '#fff3e0' ,
81- '--body-text-color' : '#ef6c00'
82- } ,
83- // Palette 9
84- {
85- '--bg-color' : '#e8eaf6' ,
86- '--text-color' : '#303f9f' ,
87- '--link-color' : '#5c6bc0' ,
88- '--caption-color' : '#cddc39' ,
89- '--header-color' : '#303f9f' ,
90- '--body-bg-color' : '#e8eaf6' ,
91- '--body-text-color' : '#303f9f'
92- } ,
93- // Palette 10
94- {
95- '--bg-color' : '#eceff1' ,
96- '--text-color' : '#37474f' ,
97- '--link-color' : '#607d8b' ,
98- '--caption-color' : '#f44336' ,
99- '--header-color' : '#37474f' ,
100- '--body-bg-color' : '#eceff1' ,
101- '--body-text-color' : '#37474f'
102- }
103- ] ;
2+ // Define a set of random color palettes for the 'random' theme
3+ const randomPalettes = [
4+ // Palette 1
5+ {
6+ '--bg-color' : '#f0e6f2' ,
7+ '--text-color' : '#4a235a' ,
8+ '--link-color' : '#8e44ad' ,
9+ '--caption-color' : '#c0392b' ,
10+ '--header-color' : '#4a235a' ,
11+ '--body-bg-color' : '#f0e6f2' ,
12+ '--body-text-color' : '#4a235a'
13+ } ,
14+ // Palette 2
15+ {
16+ '--bg-color' : '#e8f8f5' ,
17+ '--text-color' : '#117a65' ,
18+ '--link-color' : '#1abc9c' ,
19+ '--caption-color' : '#d35400' ,
20+ '--header-color' : '#117a65' ,
21+ '--body-bg-color' : '#e8f8f5' ,
22+ '--body-text-color' : '#117a65'
23+ } ,
24+ // Palette 3
25+ {
26+ '--bg-color' : '#fef9e7' ,
27+ '--text-color' : '#b07e0c' ,
28+ '--link-color' : '#f39c12' ,
29+ '--caption-color' : '#2c3e50' ,
30+ '--header-color' : '#b07e0c' ,
31+ '--body-bg-color' : '#fef9e7' ,
32+ '--body-text-color' : '#b07e0c'
33+ } ,
34+ // Palette 4
35+ {
36+ '--bg-color' : '#e3f2fd' ,
37+ '--text-color' : '#1565c0' ,
38+ '--link-color' : '#2196f3' ,
39+ '--caption-color' : '#d32f2f' ,
40+ '--header-color' : '#1565c0' ,
41+ '--body-bg-color' : '#e3f2fd' ,
42+ '--body-text-color' : '#1565c0'
43+ } ,
44+ // Palette 5
45+ {
46+ '--bg-color' : '#fce4ec' ,
47+ '--text-color' : '#c2185b' ,
48+ '--link-color' : '#e91e63' ,
49+ '--caption-color' : '#00796b' ,
50+ '--header-color' : '#c2185b' ,
51+ '--body-bg-color' : '#fce4ec' ,
52+ '--body-text-color' : '#c2185b'
53+ } ,
54+ // Palette 6
55+ {
56+ '--bg-color' : '#f1f8e9' ,
57+ '--text-color' : '#558b2f' ,
58+ '--link-color' : '#8bc34a' ,
59+ '--caption-color' : '#fbc02d' ,
60+ '--header-color' : '#558b2f' ,
61+ '--body-bg-color' : '#f1f8e9' ,
62+ '--body-text-color' : '#558b2f'
63+ } ,
64+ // Palette 7
65+ {
66+ '--bg-color' : '#e0f7fa' ,
67+ '--text-color' : '#00838f' ,
68+ '--link-color' : '#00bcd4' ,
69+ '--caption-color' : '#e65100' ,
70+ '--header-color' : '#00838f' ,
71+ '--body-bg-color' : '#e0f7fa' ,
72+ '--body-text-color' : '#00838f'
73+ } ,
74+ // Palette 8
75+ {
76+ '--bg-color' : '#fff3e0' ,
77+ '--text-color' : '#ef6c00' ,
78+ '--link-color' : '#ff9800' ,
79+ '--caption-color' : '#607d8b' ,
80+ '--header-color' : '#ef6c00' ,
81+ '--body-bg-color' : '#fff3e0' ,
82+ '--body-text-color' : '#ef6c00'
83+ } ,
84+ // Palette 9
85+ {
86+ '--bg-color' : '#e8eaf6' ,
87+ '--text-color' : '#303f9f' ,
88+ '--link-color' : '#5c6bc0' ,
89+ '--caption-color' : '#cddc39' ,
90+ '--header-color' : '#303f9f' ,
91+ '--body-bg-color' : '#e8eaf6' ,
92+ '--body-text-color' : '#303f9f'
93+ } ,
94+ // Palette 10
95+ {
96+ '--bg-color' : '#eceff1' ,
97+ '--text-color' : '#37474f' ,
98+ '--link-color' : '#607d8b' ,
99+ '--caption-color' : '#f44336' ,
100+ '--header-color' : '#37474f' ,
101+ '--body-bg-color' : '#eceff1' ,
102+ '--body-text-color' : '#37474f'
103+ }
104+ ] ;
104105
106+ // Select the theme toggle button and body
105107 const themeToggle = document . getElementById ( 'theme-toggle' ) ;
108+ const body = document . body ;
109+
110+ // Easter egg variables
111+ let matrixSequence = '' ;
112+ const matrixTrigger = 'matrix' ;
113+ let exitSequence = '' ;
114+ const exitTrigger = 'exit' ;
115+ let matrixIntervalId = null ;
116+
106117 if ( themeToggle ) {
107- const body = document . body ;
108118 const savedTheme = localStorage . getItem ( 'theme' ) ;
109119 const savedRandomIndex = localStorage . getItem ( 'randomIndex' ) ;
110120 let currentTheme = 'light' ;
111121
122+ // Initialize theme based on local storage or system preference
112123 if ( savedTheme ) {
113124 currentTheme = savedTheme ;
114125 if ( currentTheme === 'random' && savedRandomIndex !== null ) {
115- // Use the saved random palette index
116126 applyRandomTheme ( body , randomPalettes , savedRandomIndex ) ;
117127 } else {
118128 body . classList . add ( currentTheme ) ;
@@ -126,8 +136,10 @@ const randomPalettes = [
126136 }
127137 }
128138
139+ // Initial toggle button text update
129140 updateToggleText ( themeToggle , currentTheme ) ;
130141
142+ // Add click event listener to the theme toggle button
131143 themeToggle . addEventListener ( 'click' , ( ) => {
132144 if ( currentTheme === 'dark' ) {
133145 currentTheme = 'light' ;
@@ -153,6 +165,31 @@ const randomPalettes = [
153165 } ) ;
154166 }
155167
168+ // Add keydown event listener for the Easter eggs
169+ document . addEventListener ( 'keydown' , ( event ) => {
170+ const key = event . key . toLowerCase ( ) ;
171+
172+ // Logic for the "matrix" egg
173+ matrixSequence += key ;
174+ if ( matrixSequence . length > matrixTrigger . length ) {
175+ matrixSequence = matrixSequence . slice ( - matrixTrigger . length ) ;
176+ }
177+ if ( matrixSequence === matrixTrigger ) {
178+ activateMatrixAnimation ( ) ;
179+ }
180+
181+ // Logic for the "exit" egg
182+ exitSequence += key ;
183+ if ( exitSequence . length > exitTrigger . length ) {
184+ exitSequence = exitSequence . slice ( - exitTrigger . length ) ;
185+ }
186+ if ( exitSequence === exitTrigger ) {
187+ deactivateMatrixAnimation ( ) ;
188+ }
189+ } ) ;
190+
191+ // --- Helper Functions ---
192+
156193 // Helper function to update button text
157194 function updateToggleText ( button , theme ) {
158195 if ( theme === 'dark' ) {
@@ -181,4 +218,59 @@ const randomPalettes = [
181218 body . style . removeProperty ( property ) ;
182219 }
183220 }
221+
222+ // --- Easter Egg Functions ---
223+
224+ function activateMatrixAnimation ( ) {
225+ if ( document . getElementById ( 'matrix-canvas' ) ) {
226+ return ;
227+ }
228+
229+ const canvas = document . createElement ( 'canvas' ) ;
230+ canvas . id = 'matrix-canvas' ;
231+ document . body . appendChild ( canvas ) ;
232+
233+ const context = canvas . getContext ( '2d' ) ;
234+ canvas . width = window . innerWidth ;
235+ canvas . height = window . innerHeight ;
236+
237+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*()_+-={}[]:";\'<>,.?/~`' ;
238+ const fontSize = 16 ;
239+ const columns = canvas . width / fontSize ;
240+ const drops = Array ( Math . floor ( columns ) ) . fill ( 1 ) ;
241+
242+ function draw ( ) {
243+ context . fillStyle = 'rgba(0, 0, 0, 0.05)' ;
244+ context . fillRect ( 0 , 0 , canvas . width , canvas . height ) ;
245+
246+ context . fillStyle = '#0F0' ;
247+ context . font = `${ fontSize } px monospace` ;
248+
249+ for ( let i = 0 ; i < drops . length ; i ++ ) {
250+ const text = characters . charAt ( Math . floor ( Math . random ( ) * characters . length ) ) ;
251+ context . fillText ( text , i * fontSize , drops [ i ] * fontSize ) ;
252+
253+ if ( drops [ i ] * fontSize > canvas . height && Math . random ( ) > 0.975 ) {
254+ drops [ i ] = 0 ;
255+ }
256+ drops [ i ] ++ ;
257+ }
258+ }
259+
260+ matrixIntervalId = setInterval ( draw , 33 ) ;
261+
262+ canvas . style . position = 'fixed' ;
263+ canvas . style . top = '0' ;
264+ canvas . style . left = '0' ;
265+ canvas . style . zIndex = '9999' ;
266+ canvas . style . pointerEvents = 'none' ;
267+ }
268+
269+ function deactivateMatrixAnimation ( ) {
270+ const canvas = document . getElementById ( 'matrix-canvas' ) ;
271+ if ( canvas ) {
272+ clearInterval ( matrixIntervalId ) ;
273+ canvas . remove ( ) ;
274+ }
275+ }
184276} ) ;
0 commit comments