mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
103 lines
3.0 KiB
TypeScript
103 lines
3.0 KiB
TypeScript
import useSpecialThemeStore from '../stores/use-special-theme-store';
|
|
|
|
interface SnowOptions {
|
|
flakeCount: number;
|
|
}
|
|
|
|
// Add this new variable to track manual override
|
|
let manualSnowOverride: boolean | null = null;
|
|
|
|
export const initSnow = ({ flakeCount }: SnowOptions): void => {
|
|
const randomRange = (min: number, max: number): number => {
|
|
min = Math.ceil(min);
|
|
max = Math.floor(max);
|
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
};
|
|
|
|
const snowflakeName = 'js-snowflake';
|
|
|
|
let rule = `.${snowflakeName} {
|
|
position: absolute;
|
|
width: 10px;
|
|
height: 10px;
|
|
background: linear-gradient(white, white);
|
|
border-radius: 50%;
|
|
filter: drop-shadow(0 0 10px white);
|
|
}`;
|
|
|
|
for (let i = 1; i < flakeCount; i++) {
|
|
const randomX = Math.random() * 100;
|
|
const randomOffset = randomRange(-100000, 100000) * 0.0001;
|
|
const randomXEnd = randomX + randomOffset;
|
|
const randomXEndYoyo = randomX + randomOffset / 2;
|
|
const randomYoyoTime = randomRange(30000, 80000) / 100000;
|
|
const randomYoyoY = randomYoyoTime * 100;
|
|
const randomScale = Math.random() * (1.0 - 0.2) + 0.2;
|
|
const fallDuration = randomRange(10, 30);
|
|
const fallDelay = (Math.floor(Math.random() * 30) + 1) * -1;
|
|
const alpha = Math.random() * (1.0 - 0.1) + 0.1;
|
|
|
|
rule += `
|
|
.${snowflakeName}:nth-child(${i}) {
|
|
opacity: ${alpha};
|
|
transform: translate(${randomX}vw, -10px) scale(${randomScale});
|
|
animation: fall-${i} ${fallDuration}s ${fallDelay}s linear infinite;
|
|
}
|
|
|
|
@keyframes fall-${i} {
|
|
${randomYoyoTime * 100}% {
|
|
transform: translate(${randomXEnd}vw, ${randomYoyoY}vh) scale(${randomScale});
|
|
}
|
|
|
|
to {
|
|
transform: translate(${randomXEndYoyo}vw, 100vh) scale(${randomScale});
|
|
}
|
|
}`;
|
|
}
|
|
|
|
const container = document.createElement('div');
|
|
container.id = 'js-snowfield';
|
|
container.style.position = 'fixed';
|
|
container.style.top = '0';
|
|
container.style.pointerEvents = 'none';
|
|
container.style.zIndex = '9999';
|
|
|
|
for (let i = 1; i < flakeCount; i++) {
|
|
const flake = document.createElement('div');
|
|
flake.className = snowflakeName;
|
|
container.appendChild(flake);
|
|
}
|
|
|
|
const css = document.createElement('style');
|
|
css.type = 'text/css';
|
|
css.textContent = rule;
|
|
document.getElementsByTagName('head')[0].appendChild(css);
|
|
document.body.appendChild(container);
|
|
};
|
|
|
|
export const removeSnow = (): void => {
|
|
const element = document.getElementById('js-snowfield');
|
|
if (element) {
|
|
element.parentNode?.removeChild(element);
|
|
}
|
|
};
|
|
|
|
export const shouldShowSnow = (): boolean => {
|
|
const isEnabled = useSpecialThemeStore.getState().isEnabled;
|
|
|
|
// Check store value first
|
|
if (isEnabled !== null) {
|
|
return isEnabled;
|
|
}
|
|
|
|
// Check manual override second
|
|
if (manualSnowOverride !== null) {
|
|
return manualSnowOverride;
|
|
}
|
|
|
|
const today = new Date();
|
|
const month = today.getMonth();
|
|
const day = today.getDate();
|
|
return month === 11 && (day === 24 || day === 25);
|
|
};
|