Новогодний снегопад с поздравлением для любого сайта, скрипт

Украсить ваш сайт снежинками и поздравлениями с новым годом:

Код вставляем перерд закрывающим

Пздравления и снег:

[js_run]
(function() {
‘use strict’;

const CONFIG = {
back: {
count: 35,
minSize: 3,
maxSize: 6,
minSpeed: 0.2,
maxSpeed: 0.7,
swayAmplitude: 1.0,
rotationSpeed: 0.004,
opacityMin: 0.15,
opacityMax: 0.35,
colors: [‘30,100,220’, ‘50,120,230’, ‘70,140,240’]
},
front: {
count: 18,
minSize: 5,
maxSize: 10,
minSpeed: 0.6,
maxSpeed: 1.6,
swayAmplitude: 1.5,
rotationSpeed: 0.012,
opacityMin: 0.6,
opacityMax: 1.0,
colors: [‘20,80,200’, ‘30,100,220’, ‘40,110,235’, ‘60,130,245’]
},
greetingInterval: 60000,
greetingDuration: 6000,
greetings: [
‘🎄 С Новым годом! 🎄’,
‘❄️ Счастья и удачи в новом году! ❄️’,
‘🎁 Пусть всё загаданное сбудется! 🎁’,
‘✨ С Новым годом, дорогие друзья! ✨’,
‘⛄ Мира, тепла и волшебства! ⛄’,
‘🥂 За новый счастливый год! 🥂’
]
};

const canvas = document.createElement(‘canvas’);
canvas.style.cssText = ‘position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9998;’;
canvas.setAttribute(‘aria-hidden’, ‘true’);
document.body.appendChild(canvas);

const ctx = canvas.getContext(‘2d’, { alpha: true });
let W = window.innerWidth, H = window.innerHeight;

function resize() {
W = window.innerWidth; H = window.innerHeight;
const dpr = Math.min(window.devicePixelRatio || 1, 2);
canvas.width = W * dpr; canvas.height = H * dpr;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
}
resize();
let resizeTimer;
window.addEventListener(‘resize’, function(){ clearTimeout(resizeTimer); resizeTimer = setTimeout(resize, 200); });

const SPRITE_PADDING = 4;
const spriteCache = {};

function makeSnowflakeSprite(size, color) {
const key = color + ‘|’ + size.toFixed(1);
if (spriteCache[key]) return spriteCache[key];
const half = Math.ceil(size + SPRITE_PADDING);
const full = half * 2;
const dpr = Math.min(window.devicePixelRatio || 1, 2);
const spr = document.createElement(‘canvas’);
spr.width = full * dpr; spr.height = full * dpr;
const sctx = spr.getContext(‘2d’);
sctx.setTransform(dpr, 0, 0, dpr, 0, 0);
sctx.translate(half, half);
const lineWidth = Math.max(0.6, size * 0.09);
const stroke = ‘rgba(‘ + color + ‘,1)’;
sctx.strokeStyle = stroke; sctx.fillStyle = stroke;
sctx.lineWidth = lineWidth; sctx.lineCap = ’round’;
for (let i = 0; i < 6; i++) { const angle = (Math.PI / 3) * i; const dx = Math.cos(angle), dy = Math.sin(angle); sctx.beginPath(); sctx.moveTo(0, 0); sctx.lineTo(dx * size, dy * size); sctx.stroke(); const branchPositions = [0.4, 0.7]; const branchLength = size * 0.35; const branchAngle = Math.PI / 5; for (let b = 0; b < branchPositions.length; b++) { const pos = branchPositions[b]; const bx = dx * size * pos, by = dy * size * pos; const bLen = branchLength * (b === 0 ? 1 : 0.7); sctx.beginPath(); sctx.moveTo(bx, by); sctx.lineTo(bx + Math.cos(angle - branchAngle) * bLen, by + Math.sin(angle - branchAngle) * bLen); sctx.stroke(); sctx.beginPath(); sctx.moveTo(bx, by); sctx.lineTo(bx + Math.cos(angle + branchAngle) * bLen, by + Math.sin(angle + branchAngle) * bLen); sctx.stroke(); } } sctx.beginPath(); sctx.arc(0, 0, lineWidth * 0.9, 0, Math.PI * 2); sctx.fill(); const sprite = { canvas: spr, half: half }; spriteCache[key] = sprite; return sprite; } function snapSize(s) { return Math.round(s * 2) / 2; } function createFlake(layer, randomY) { const rawSize = layer.minSize + Math.random() * (layer.maxSize - layer.minSize); const size = snapSize(rawSize); const color = layer.colors[(Math.random() * layer.colors.length) | 0]; const sprite = makeSnowflakeSprite(size, color); return { x: Math.random() * W, y: randomY ? Math.random() * H : -20, size: size, sprite: sprite, speed: layer.minSpeed + Math.random() * (layer.maxSpeed - layer.minSpeed), sway: Math.random() * Math.PI * 2, swaySpeed: 0.01 + Math.random() * 0.02, rotation: Math.random() * Math.PI * 2, rotationSpeed: (Math.random() - 0.5) * layer.rotationSpeed * 2, opacity: layer.opacityMin + Math.random() * (layer.opacityMax - layer.opacityMin), layer: layer }; } function createLayer(cfg) { const arr = new Array(cfg.count); for (let i = 0; i < cfg.count; i++) arr[i] = createFlake(cfg, true); return arr; } const backFlakes = createLayer(CONFIG.back); const frontFlakes = createLayer(CONFIG.front); function updateFlakes(flakes, dt) { for (let i = 0; i < flakes.length; i++) { const f = flakes[i]; f.y += f.speed * dt; f.sway += f.swaySpeed * dt; f.rotation += f.rotationSpeed * dt; const x = f.x + Math.sin(f.sway) * f.layer.swayAmplitude; const spr = f.sprite; ctx.globalAlpha = f.opacity < 0.99 ? f.opacity : 1; ctx.save(); ctx.translate(x, f.y); if (f.rotation !== 0) ctx.rotate(f.rotation); ctx.drawImage(spr.canvas, -spr.half, -spr.half, spr.half * 2, spr.half * 2); ctx.restore(); if (f.y - f.size > H) flakes[i] = createFlake(f.layer, false);
}
ctx.globalAlpha = 1;
}

let lastTime = performance.now();
function animate(now) {
const dt = Math.min((now — lastTime) / 16.67, 3);
lastTime = now;
ctx.clearRect(0, 0, W, H);
updateFlakes(backFlakes, dt);
updateFlakes(frontFlakes, dt);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

const greetingEl = document.createElement(‘div’);
greetingEl.style.cssText = [
‘position:fixed’,’top:50%’,’left:50%’,
‘transform:translate(-50%,-50%) scale(0.6)’,
‘background:linear-gradient(135deg,#0a1f4a,#143a80,#1e5bc8)’,
‘color:#fff’,’padding:28px 44px’,’border-radius:20px’,
‘font-family:-apple-system,»Segoe UI»,Roboto,Arial,sans-serif’,
‘font-size:clamp(20px,4vw,42px)’,’font-weight:700′,’text-align:center’,
‘box-shadow:0 0 40px rgba(50,130,255,0.7),0 0 80px rgba(30,100,220,0.4)’,
‘border:1px solid rgba(120,180,255,0.5)’,
‘text-shadow:0 0 12px rgba(120,180,255,0.9)’,
‘pointer-events:none’,’opacity:0′,
‘transition:opacity 0.6s ease,transform 0.6s cubic-bezier(0.18,0.89,0.32,1.28)’,
‘z-index:9999′,’max-width:90vw’,’line-height:1.3′
].join(‘;’);
greetingEl.setAttribute(‘aria-hidden’, ‘true’);
document.body.appendChild(greetingEl);

let lastGreetingIndex = -1;
function showGreeting() {
let idx;
do { idx = (Math.random() * CONFIG.greetings.length) | 0; }
while (idx === lastGreetingIndex && CONFIG.greetings.length > 1);
lastGreetingIndex = idx;
greetingEl.textContent = CONFIG.greetings[idx];
greetingEl.style.opacity = ‘1’;
greetingEl.style.transform = ‘translate(-50%,-50%) scale(1)’;
setTimeout(function() {
greetingEl.style.opacity = ‘0’;
greetingEl.style.transform = ‘translate(-50%,-50%) scale(0.6)’;
}, CONFIG.greetingDuration);
}
setTimeout(showGreeting, 2000);
setInterval(showGreeting, CONFIG.greetingInterval);
})();
[/js_run]

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

🧮 Проверка безопасности
9 - 3 = ?