santa working

This commit is contained in:
MLH
2025-01-26 03:05:44 +01:00
parent 9f13a51559
commit f577c7535c
2 changed files with 140 additions and 5 deletions

View File

@ -14,4 +14,22 @@
width: 100%;
height: 100%;
pointer-events: none;
}
.santa {
position: fixed;
width: 100px;
height: auto;
z-index: 1000;
pointer-events: none;
transition: transform 0.3s;
}
.present {
position: fixed;
width: 50px;
height: auto;
z-index: 999;
pointer-events: none;
transition: top linear, opacity linear;
}

View File

@ -1,4 +1,4 @@
const santa = true; // enable/disable santa
const santaIsFlying = true; // enable/disable santa
let snowflakesCount = 500; // count of snowflakes (recommended values: 300-600)
const snowflakesCountMobile = 250; // count of snowflakes on mobile devices
const snowFallSpeed = 3; // speed of snowfall (recommended values: 0-5)
@ -31,7 +31,7 @@ function toggleSnowfall() {
if (!animationFrameId) {
initializeCanvas();
snowflakes = createSnowflakes(santaContainer);
animateSanta();
animateAll();
} else {
console.warn('could not initialize santa: animation frame is already running');
}
@ -59,7 +59,7 @@ function initializeCanvas() {
console.warn('Canvas already exists.');
return;
}
const container = document.querySelector('.santa-container');
if (!container) {
console.error('Error: No element with class "santa-container" found.');
@ -140,15 +140,131 @@ function updateSnowflakes() {
});
}
const presentImages = [
'images/gift1.png',
'images/gift2.png',
'images/gift3.png',
'images/gift4.png',
'images/gift5.png',
'images/gift6.png',
'images/gift7.png',
'images/gift8.png',
];
const santaImage = 'images/santa.gif';
/*
const presentImages = [
'seasonals/santa_images/gift1.png',
'seasonals/santa_images/gift2.png',
'seasonals/santa_images/gift3.png',
'seasonals/santa_images/gift4.png',
'seasonals/santa_images/gift5.png',
'seasonals/santa_images/gift6.png',
'seasonals/santa_images/gift7.png',
'seasonals/santa_images/gift8.png',
];
const santaImage = 'seasonals/santa_images/santa.gif';
*/
function createSantaElement() {
const santa = document.createElement('img');
santa.src = santaImage;
santa.classList.add('santa');
const santaContainer = document.querySelector('.santa-container');
santaContainer.appendChild(santa);
return santa;
}
function dropPresent(santa) {
const present = document.createElement('img');
present.src = presentImages[Math.floor(Math.random() * presentImages.length)];
present.classList.add('present');
const santaContainer = document.querySelector('.santa-container');
santaContainer.appendChild(present);
// Position present at Santa's current location
const rect = santa.getBoundingClientRect();
present.style.left = `${rect.left + rect.width / 2}px`;
present.style.top = `${rect.top + rect.height}px`;
// Calculate fall duration based on Santa's current height with variation
const fallDistance = window.innerHeight - rect.top - rect.height;
const baseDuration = fallDistance / 100; // 1 second per 100px
const variation = Math.random() * 2000 - 1000; // ±1 second
const fallDuration = baseDuration * 1000 + variation;
// Animate present falling
present.style.transition = `top ${fallDuration}ms linear, opacity ${fallDuration}ms linear`;
present.style.top = `${window.innerHeight}px`;
present.style.opacity = '0';
// Remove present after animation
setTimeout(() => {
present.remove();
}, fallDuration);
}
function animateSanta() {
const santa = createSantaElement();
const santaContainer = document.querySelector('.santa-container');
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
const fromLeft = Math.random() < 0.5;
const startX = fromLeft ? -100 : screenWidth + 100;
const endX = fromLeft ? screenWidth + 100 : -100;
const startY = Math.random() * (screenHeight / 2);
const endY = Math.random() * (screenHeight / 2);
const angle = Math.random() * 20 - 10; // -10 to 10 degrees
santa.style.left = `${startX}px`;
santa.style.top = `${startY}px`;
santa.style.transform = `rotate(${angle}deg) ${fromLeft ? 'scaleX(-1)' : 'scaleX(1)'}`; // Mirror if not from left
const duration = 10000; // 10 seconds
const deltaX = endX - startX;
const deltaY = endY - startY;
const startTime = performance.now();
function move() {
const currentTime = performance.now();
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
santa.style.left = `${startX + deltaX * progress}px`;
santa.style.top = `${startY + deltaY * progress - 100 * Math.sin(progress * Math.PI)}px`; // Parabolic path
if (progress < 1) {
requestAnimationFrame(move);
} else {
santa.remove();
const pause = Math.random() * 5000 + 3000; // 3-8 seconds pause
setTimeout(animateSanta, pause);
}
}
requestAnimationFrame(move);
// Drop presents every 2 seconds
const dropInterval = setInterval(() => dropPresent(santa), 2000);
// Clear interval after animation completes
setTimeout(() => {
clearInterval(dropInterval);
}, duration);
}
function animateAll() {
drawSnowflakes();
updateSnowflakes();
animationFrameId = requestAnimationFrame(animateSanta);
animationFrameId = requestAnimationFrame(animateAll);
}
// initialize santa
document.addEventListener('DOMContentLoaded', () => {
if (!santa) {
if (!santaIsFlying) {
console.warn('Sante is disabled.');
return; // exit if santa is disabled
}
@ -163,6 +279,7 @@ document.addEventListener('DOMContentLoaded', () => {
console.log('Santa enabled.');
initializeCanvas();
snowflakes = createSnowflakes(container);
animateAll();
animateSanta();
}
});