Xmas silliness
This commit is contained in:
27
web/assets/bell.svg
Normal file
27
web/assets/bell.svg
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<svg viewBox="0 0 100 120" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<!-- Bell body -->
|
||||||
|
<path d="M 30,40 Q 30,35 35,35 L 65,35 Q 70,35 70,40 Q 70,60 50,70 Q 30,60 30,40" fill="#FFD700" stroke="#DAA520" stroke-width="2"/>
|
||||||
|
|
||||||
|
<!-- Bell shine/highlight -->
|
||||||
|
<ellipse cx="45" cy="45" rx="8" ry="6" fill="#FFED4E" opacity="0.6"/>
|
||||||
|
|
||||||
|
<!-- Bell clapper -->
|
||||||
|
<circle cx="50" cy="65" r="4" fill="#8B4513"/>
|
||||||
|
<path d="M 50,65 Q 48,75 47,85" stroke="#8B4513" stroke-width="2" fill="none"/>
|
||||||
|
|
||||||
|
<!-- Top of bell (rope/hanging part) -->
|
||||||
|
<rect x="47" y="25" width="6" height="10" fill="#DAA520" rx="2"/>
|
||||||
|
|
||||||
|
<!-- Loop -->
|
||||||
|
<path d="M 48,25 Q 40,20 50,15 Q 60,20 52,25" stroke="#DAA520" stroke-width="2" fill="none"/>
|
||||||
|
|
||||||
|
<!-- Decorative berries around bell -->
|
||||||
|
<circle cx="25" cy="50" r="2" fill="#E74C3C"/>
|
||||||
|
<circle cx="75" cy="50" r="2" fill="#E74C3C"/>
|
||||||
|
<circle cx="28" cy="60" r="2" fill="#E74C3C"/>
|
||||||
|
<circle cx="72" cy="60" r="2" fill="#E74C3C"/>
|
||||||
|
|
||||||
|
<!-- Holly leaves -->
|
||||||
|
<path d="M 20,45 L 18,48 L 20,50 L 18,52 L 20,55" stroke="#228B22" stroke-width="1.5" fill="none"/>
|
||||||
|
<path d="M 80,45 L 82,48 L 80,50 L 82,52 L 80,55" stroke="#228B22" stroke-width="1.5" fill="none"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
10
web/assets/candycane.svg
Normal file
10
web/assets/candycane.svg
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<svg viewBox="0 0 100 120" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<!-- Candy cane curve -->
|
||||||
|
<path d="M 50,10 Q 30,30 30,60 Q 30,90 50,100" stroke="#E74C3C" stroke-width="12" fill="none" stroke-linecap="round"/>
|
||||||
|
|
||||||
|
<!-- White stripe -->
|
||||||
|
<path d="M 50,10 Q 30,30 30,60 Q 30,90 50,100" stroke="#FFFFFF" stroke-width="6" fill="none" stroke-linecap="round" stroke-dasharray="8,8"/>
|
||||||
|
|
||||||
|
<!-- Highlight -->
|
||||||
|
<path d="M 48,15 Q 32,32 32,60 Q 32,88 48,98" stroke="#FFFFFF" stroke-width="2" fill="none" stroke-linecap="round" opacity="0.6"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 546 B |
25
web/assets/gift.svg
Normal file
25
web/assets/gift.svg
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<svg viewBox="0 0 100 120" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<!-- Box -->
|
||||||
|
<rect x="15" y="30" width="70" height="70" fill="#E74C3C" stroke="#C0392B" stroke-width="2"/>
|
||||||
|
|
||||||
|
<!-- Box lid/3D effect -->
|
||||||
|
<polygon points="15,30 25,20 85,20 75,30" fill="#C0392B"/>
|
||||||
|
<polygon points="75,30 85,20 85,90 75,100" fill="#A93226"/>
|
||||||
|
|
||||||
|
<!-- Ribbon vertical -->
|
||||||
|
<rect x="42" y="20" width="16" height="85" fill="#FFD700" stroke="#DAA520" stroke-width="1"/>
|
||||||
|
|
||||||
|
<!-- Ribbon horizontal -->
|
||||||
|
<rect x="10" y="57" width="80" height="16" fill="#FFD700" stroke="#DAA520" stroke-width="1"/>
|
||||||
|
|
||||||
|
<!-- Bow on top -->
|
||||||
|
<ellipse cx="35" cy="18" rx="10" ry="8" fill="#FFD700" stroke="#DAA520" stroke-width="1"/>
|
||||||
|
<ellipse cx="65" cy="18" rx="10" ry="8" fill="#FFD700" stroke="#DAA520" stroke-width="1"/>
|
||||||
|
<circle cx="50" cy="20" r="5" fill="#DAA520"/>
|
||||||
|
|
||||||
|
<!-- Pattern on box -->
|
||||||
|
<circle cx="30" cy="50" r="3" fill="#FFFFFF" opacity="0.5"/>
|
||||||
|
<circle cx="70" cy="60" r="3" fill="#FFFFFF" opacity="0.5"/>
|
||||||
|
<circle cx="50" cy="75" r="3" fill="#FFFFFF" opacity="0.5"/>
|
||||||
|
<circle cx="35" cy="80" r="3" fill="#FFFFFF" opacity="0.5"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
39
web/assets/reindeer.svg
Normal file
39
web/assets/reindeer.svg
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<svg viewBox="0 0 100 120" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<!-- Antlers -->
|
||||||
|
<path d="M 35,25 Q 25,10 20,5" stroke="#8B4513" stroke-width="3" fill="none"/>
|
||||||
|
<path d="M 65,25 Q 75,10 80,5" stroke="#8B4513" stroke-width="3" fill="none"/>
|
||||||
|
<path d="M 33,22 Q 22,15 15,8" stroke="#8B4513" stroke-width="2" fill="none"/>
|
||||||
|
<path d="M 67,22 Q 78,15 85,8" stroke="#8B4513" stroke-width="2" fill="none"/>
|
||||||
|
|
||||||
|
<!-- Head -->
|
||||||
|
<circle cx="50" cy="35" r="15" fill="#8B4513"/>
|
||||||
|
|
||||||
|
<!-- Ears -->
|
||||||
|
<ellipse cx="38" cy="22" rx="5" ry="8" fill="#8B4513"/>
|
||||||
|
<ellipse cx="62" cy="22" rx="5" ry="8" fill="#8B4513"/>
|
||||||
|
|
||||||
|
<!-- Eyes -->
|
||||||
|
<circle cx="45" cy="32" r="2" fill="#000000"/>
|
||||||
|
<circle cx="55" cy="32" r="2" fill="#000000"/>
|
||||||
|
|
||||||
|
<!-- Nose (red) -->
|
||||||
|
<circle cx="50" cy="40" r="4" fill="#E74C3C"/>
|
||||||
|
|
||||||
|
<!-- Mouth -->
|
||||||
|
<path d="M 48,45 Q 50,47 52,45" stroke="#000000" stroke-width="1" fill="none"/>
|
||||||
|
|
||||||
|
<!-- Neck -->
|
||||||
|
<rect x="43" y="48" width="14" height="8" fill="#8B4513"/>
|
||||||
|
|
||||||
|
<!-- Body -->
|
||||||
|
<ellipse cx="50" cy="70" rx="20" ry="25" fill="#8B4513"/>
|
||||||
|
|
||||||
|
<!-- Legs -->
|
||||||
|
<rect x="35" y="90" width="6" height="25" fill="#8B4513"/>
|
||||||
|
<rect x="45" y="90" width="6" height="25" fill="#8B4513"/>
|
||||||
|
<rect x="55" y="90" width="6" height="25" fill="#8B4513"/>
|
||||||
|
<rect x="65" y="90" width="6" height="25" fill="#8B4513"/>
|
||||||
|
|
||||||
|
<!-- Tail -->
|
||||||
|
<circle cx="68" cy="65" r="5" fill="#FFFFFF"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
37
web/assets/santa.svg
Normal file
37
web/assets/santa.svg
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<svg viewBox="0 0 100 120" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<!-- Santa hat -->
|
||||||
|
<polygon points="20,20 80,20 75,35 25,35" fill="#E74C3C"/>
|
||||||
|
<circle cx="50" cy="18" r="8" fill="#E74C3C"/>
|
||||||
|
<circle cx="77" cy="28" r="6" fill="#FFFFFF"/>
|
||||||
|
|
||||||
|
<!-- Face -->
|
||||||
|
<circle cx="50" cy="50" r="18" fill="#F5DEB3"/>
|
||||||
|
|
||||||
|
<!-- Eyes -->
|
||||||
|
<circle cx="42" cy="45" r="2.5" fill="#000000"/>
|
||||||
|
<circle cx="58" cy="45" r="2.5" fill="#000000"/>
|
||||||
|
|
||||||
|
<!-- Nose -->
|
||||||
|
<circle cx="50" cy="52" r="2" fill="#E74C3C"/>
|
||||||
|
|
||||||
|
<!-- Beard -->
|
||||||
|
<path d="M 35,58 Q 35,65 50,68 Q 65,65 65,58" fill="#FFFFFF"/>
|
||||||
|
|
||||||
|
<!-- Mouth -->
|
||||||
|
<path d="M 42,60 Q 50,63 58,60" stroke="#000000" stroke-width="1" fill="none"/>
|
||||||
|
|
||||||
|
<!-- Body -->
|
||||||
|
<rect x="35" y="68" width="30" height="25" rx="5" fill="#E74C3C"/>
|
||||||
|
|
||||||
|
<!-- Belt -->
|
||||||
|
<rect x="32" y="85" width="36" height="4" fill="#000000"/>
|
||||||
|
<circle cx="68" cy="87" r="2.5" fill="#FFD700"/>
|
||||||
|
|
||||||
|
<!-- Arms -->
|
||||||
|
<rect x="15" y="75" width="20" height="6" rx="3" fill="#F5DEB3"/>
|
||||||
|
<rect x="65" y="75" width="20" height="6" rx="3" fill="#F5DEB3"/>
|
||||||
|
|
||||||
|
<!-- Legs -->
|
||||||
|
<rect x="40" y="93" width="8" height="20" fill="#000000"/>
|
||||||
|
<rect x="52" y="93" width="8" height="20" fill="#000000"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
17
web/assets/tree.svg
Normal file
17
web/assets/tree.svg
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<svg viewBox="0 0 100 120" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<!-- Tree trunk -->
|
||||||
|
<rect x="40" y="80" width="20" height="25" fill="#8B4513"/>
|
||||||
|
|
||||||
|
<!-- Tree layers -->
|
||||||
|
<polygon points="50,10 20,50 30,50 10,80 40,80 5,110 50,110 95,110 60,80 90,80 70,50 80,50" fill="#228B22"/>
|
||||||
|
|
||||||
|
<!-- Tree highlights -->
|
||||||
|
<circle cx="50" cy="35" r="4" fill="#FFD700" opacity="0.7"/>
|
||||||
|
<circle cx="35" cy="55" r="3" fill="#FFD700" opacity="0.7"/>
|
||||||
|
<circle cx="65" cy="60" r="3" fill="#FFD700" opacity="0.7"/>
|
||||||
|
<circle cx="45" cy="80" r="3" fill="#FFD700" opacity="0.7"/>
|
||||||
|
<circle cx="55" cy="90" r="3" fill="#FFD700" opacity="0.7"/>
|
||||||
|
|
||||||
|
<!-- Star on top -->
|
||||||
|
<polygon points="50,5 55,15 65,15 57,20 60,30 50,25 40,30 43,20 35,15 45,15" fill="#FFD700"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 758 B |
335
web/index.html
335
web/index.html
@@ -132,6 +132,226 @@
|
|||||||
grid-template-columns: 1fr; /* Stack columns on smaller screens */
|
grid-template-columns: 1fr; /* Stack columns on smaller screens */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Christmas toggle switch */
|
||||||
|
.christmas-toggle {
|
||||||
|
position: absolute;
|
||||||
|
right: 20px;
|
||||||
|
top: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
color: white;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-checkbox {
|
||||||
|
width: 50px;
|
||||||
|
height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
appearance: none;
|
||||||
|
background-color: #555;
|
||||||
|
border-radius: 12px;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-checkbox:checked {
|
||||||
|
background-color: #27ae60;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-checkbox::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: white;
|
||||||
|
top: 2px;
|
||||||
|
left: 2px;
|
||||||
|
transition: left 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-checkbox:checked::before {
|
||||||
|
left: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Santa hat styles */
|
||||||
|
.santa-hat {
|
||||||
|
position: absolute;
|
||||||
|
width: 60px;
|
||||||
|
height: 50px;
|
||||||
|
top: -20px;
|
||||||
|
transform: rotate(-20deg);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.santa-hat::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 70%;
|
||||||
|
background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
|
||||||
|
clip-path: polygon(0 0, 100% 0, 90% 100%, 10% 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.santa-hat::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
bottom: -5px;
|
||||||
|
right: -8px;
|
||||||
|
box-shadow: -15px 5px 0 -5px white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Jingle bell styles */
|
||||||
|
.jingle-bell {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
width: 12px;
|
||||||
|
height: 14px;
|
||||||
|
margin: 0 2px;
|
||||||
|
animation: jingle 0.4s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jingle-bell::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #f1c40f;
|
||||||
|
border-radius: 50% 50% 50% 0;
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.jingle-bell::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 3px;
|
||||||
|
height: 6px;
|
||||||
|
background: #d4a500;
|
||||||
|
top: -6px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes jingle {
|
||||||
|
0%, 100% { transform: rotate(0deg); }
|
||||||
|
25% { transform: rotate(5deg); }
|
||||||
|
75% { transform: rotate(-5deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Snow animation */
|
||||||
|
.snowflake {
|
||||||
|
position: fixed;
|
||||||
|
top: -10px;
|
||||||
|
color: white;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 0 0 5px rgba(255,255,255,0.8);
|
||||||
|
z-index: 1;
|
||||||
|
user-select: none;
|
||||||
|
pointer-events: none;
|
||||||
|
animation: snowfall linear infinite;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes snowfall {
|
||||||
|
to {
|
||||||
|
transform: translateY(100vh) translateX(100px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.christmas-active .snowflake {
|
||||||
|
animation: snowfall linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Festive header when active */
|
||||||
|
body.christmas-active header {
|
||||||
|
background: linear-gradient(90deg, #27ae60 0%, #e74c3c 50%, #27ae60 100%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: festive-pulse 3s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes festive-pulse {
|
||||||
|
0%, 100% { background-position: 0% 0%; }
|
||||||
|
50% { background-position: 100% 0%; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Jingle bells in header when active */
|
||||||
|
body.christmas-active h1::before {
|
||||||
|
content: '🔔 ';
|
||||||
|
animation: jingle 0.4s ease-in-out infinite;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 30px;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.christmas-active h1::after {
|
||||||
|
content: ' 🔔';
|
||||||
|
animation: jingle 0.4s ease-in-out infinite;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 30px;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Corner decorations */
|
||||||
|
.corner-decoration {
|
||||||
|
position: fixed;
|
||||||
|
font-size: 80px;
|
||||||
|
z-index: 5;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.9;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.corner-decoration img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bottom decorations */
|
||||||
|
.bottom-decoration {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
z-index: 5;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-decoration img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.corner-decoration.bottom-left {
|
||||||
|
bottom: 10px;
|
||||||
|
left: 10px;
|
||||||
|
animation: sway 3s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.corner-decoration.bottom-right {
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
animation: sway 3s ease-in-out infinite reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes sway {
|
||||||
|
0%, 100% { transform: rotate(0deg); }
|
||||||
|
50% { transform: rotate(-5deg); }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -191,6 +411,118 @@
|
|||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// Christmas mode toggle functionality
|
||||||
|
function initChristmasMode() {
|
||||||
|
// Check URL parameter first for override
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const christmasParam = urlParams.get('christmas');
|
||||||
|
|
||||||
|
let shouldEnable = false;
|
||||||
|
|
||||||
|
if (christmasParam === 'on') {
|
||||||
|
shouldEnable = true;
|
||||||
|
} else if (christmasParam === 'off') {
|
||||||
|
shouldEnable = false;
|
||||||
|
} else {
|
||||||
|
// Auto-enable for December
|
||||||
|
const now = new Date();
|
||||||
|
shouldEnable = now.getMonth() === 11; // December is month 11 (0-indexed)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldEnable) {
|
||||||
|
enableChristmasMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableChristmasMode() {
|
||||||
|
document.body.classList.add('christmas-active');
|
||||||
|
|
||||||
|
// Create falling snowflakes
|
||||||
|
function createSnowflake() {
|
||||||
|
const snowflake = document.createElement('div');
|
||||||
|
snowflake.classList.add('snowflake');
|
||||||
|
snowflake.textContent = '❄';
|
||||||
|
snowflake.style.left = Math.random() * window.innerWidth + 'px';
|
||||||
|
snowflake.style.animationDuration = (Math.random() * 5 + 8) + 's';
|
||||||
|
snowflake.style.animationDelay = Math.random() * 2 + 's';
|
||||||
|
|
||||||
|
document.body.appendChild(snowflake);
|
||||||
|
|
||||||
|
setTimeout(() => snowflake.remove(), 13000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create snowflakes periodically
|
||||||
|
const snowInterval = setInterval(() => {
|
||||||
|
if (!document.body.classList.contains('christmas-active')) {
|
||||||
|
clearInterval(snowInterval);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
createSnowflake();
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
// Add corner decorations
|
||||||
|
const leftCorner = document.createElement('div');
|
||||||
|
leftCorner.classList.add('corner-decoration', 'bottom-left');
|
||||||
|
const treeImg = document.createElement('img');
|
||||||
|
treeImg.src = 'assets/tree.svg';
|
||||||
|
treeImg.alt = 'Christmas Tree';
|
||||||
|
leftCorner.appendChild(treeImg);
|
||||||
|
leftCorner.id = 'corner-left';
|
||||||
|
document.body.appendChild(leftCorner);
|
||||||
|
|
||||||
|
const rightCorner = document.createElement('div');
|
||||||
|
rightCorner.classList.add('corner-decoration', 'bottom-right');
|
||||||
|
const santaImg = document.createElement('img');
|
||||||
|
santaImg.src = 'assets/santa.svg';
|
||||||
|
santaImg.alt = 'Santa';
|
||||||
|
rightCorner.appendChild(santaImg);
|
||||||
|
rightCorner.id = 'corner-right';
|
||||||
|
document.body.appendChild(rightCorner);
|
||||||
|
|
||||||
|
// Add bottom decorations in a row
|
||||||
|
const bottomDecorations = [
|
||||||
|
{ src: 'assets/reindeer.svg', alt: 'Reindeer' },
|
||||||
|
{ src: 'assets/bell.svg', alt: 'Bell' },
|
||||||
|
{ src: 'assets/gift.svg', alt: 'Gift' },
|
||||||
|
{ src: 'assets/candycane.svg', alt: 'Candy Cane' },
|
||||||
|
{ src: 'assets/bell.svg', alt: 'Bell' },
|
||||||
|
{ src: 'assets/gift.svg', alt: 'Gift' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const screenWidth = window.innerWidth;
|
||||||
|
const totalDecorations = bottomDecorations.length;
|
||||||
|
const spacing = screenWidth / (totalDecorations + 1);
|
||||||
|
|
||||||
|
bottomDecorations.forEach((deco, index) => {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.classList.add('bottom-decoration');
|
||||||
|
div.style.left = (spacing * (index + 1) - 40) + 'px'; // 40 is half the width
|
||||||
|
div.style.animation = `sway ${3 + index * 0.5}s ease-in-out infinite`;
|
||||||
|
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = deco.src;
|
||||||
|
img.alt = deco.alt;
|
||||||
|
div.appendChild(img);
|
||||||
|
div.id = `bottom-deco-${index}`;
|
||||||
|
|
||||||
|
document.body.appendChild(div);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function disableChristmasMode() {
|
||||||
|
document.body.classList.remove('christmas-active');
|
||||||
|
|
||||||
|
// Remove corner decorations
|
||||||
|
document.getElementById('corner-left')?.remove();
|
||||||
|
document.getElementById('corner-right')?.remove();
|
||||||
|
|
||||||
|
// Remove bottom decorations
|
||||||
|
document.querySelectorAll('[id^="bottom-deco-"]').forEach(deco => deco.remove());
|
||||||
|
|
||||||
|
// Remove snowflakes
|
||||||
|
document.querySelectorAll('.snowflake').forEach(flake => flake.remove());
|
||||||
|
}
|
||||||
|
|
||||||
let wsConnection = null;
|
let wsConnection = null;
|
||||||
|
|
||||||
// ICAO code to airport name cache
|
// ICAO code to airport name cache
|
||||||
@@ -395,6 +727,9 @@
|
|||||||
|
|
||||||
// Load data on page load
|
// Load data on page load
|
||||||
window.addEventListener('load', function() {
|
window.addEventListener('load', function() {
|
||||||
|
// Initialize Christmas mode
|
||||||
|
initChristmasMode();
|
||||||
|
|
||||||
loadArrivals();
|
loadArrivals();
|
||||||
loadDepartures();
|
loadDepartures();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user