In dieser Rubrik findest Du eine sorgfältig zusammengestellte Auswahl an Webseiten, die Schneeflocken-JavaScript-Lösungen anbieten. Mit diesen Skripten kannst du deine Homepage zur Weihnachtszeit einen stimmungsvollen Schneefall-Effekt verleihen und so für eine festliche Atmosphäre sorgen. Viele der vorgestellten Snowflakes-Plugins sind kostenlos nutzbar und lassen sich einfach in Ihre bestehende Webseite integrieren.
Hier ein Beispiel für einen Schneeflocken / Wintereffekt:
Webseiten, auf denen du einen Schneeflocken-Effekt für deine Homepage bekommen kannst:
Unseren Beispiel-Wintereffekt haben wir mit ChatGPT erstellt – hier der Code (Nutzung auf eigenes Risiko, ohne Gewähr):
Notwendiges Javascript:
<script>
/*
Winter Snowfall in a Div (Canvas) — MIT License
Copyright (c) 2025
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
*/
(() => {
"use strict";
class WinterSnowInDiv {
constructor(container, opts = {}) {
if (!container) throw new Error("Container element is required.");
this.container = container;
this.opts = {
// Schneefall
flakeCount: 220,
wind: 0.25,
windGust: 0.35,
gravityMin: 0.35,
gravityMax: 1.35,
sizeMin: 0.8,
sizeMax: 3.2,
sway: 0.9,
blur: 0.0,
// Hintergrund
backgroundStars: 0.15,
haze: 0.10,
// Performance
maxDpr: 2,
...opts
};
const cs = getComputedStyle(this.container);
if (cs.position === "static") this.container.style.position = "relative";
this.dpr = Math.max(1, Math.min(this.opts.maxDpr, window.devicePixelRatio || 1));
this.canvas = document.createElement("canvas");
this.canvas.setAttribute("aria-hidden", "true");
this.canvas.style.width = "100%";
this.canvas.style.height = "100%";
this.canvas.style.display = "block";
this.canvas.style.pointerEvents = "none";
this.container.appendChild(this.canvas);
this.ctx = this.canvas.getContext("2d", { alpha: true });
this.width = 1;
this.height = 1;
this.running = false;
this._raf = null;
this._resizeObserver = new ResizeObserver(() => this.resize());
this._resizeObserver.observe(this.container);
this._stars = [];
this._flakes = [];
this._t = 0;
this.resize();
this._initScene();
this.start();
// Optional: Pause, wenn Tab nicht sichtbar (Performance)
document.addEventListener("visibilitychange", () => {
if (document.hidden) this.stop();
else this.start();
});
}
resize() {
const r = this.container.getBoundingClientRect();
this.width = Math.max(1, Math.floor(r.width));
this.height = Math.max(1, Math.floor(r.height));
this.canvas.width = Math.floor(this.width * this.dpr);
this.canvas.height = Math.floor(this.height * this.dpr);
this.ctx.setTransform(this.dpr, 0, 0, this.dpr, 0, 0);
this._initScene(true);
}
destroy() {
this.stop();
this._resizeObserver?.disconnect();
this.canvas?.remove();
this._stars = [];
this._flakes = [];
}
rand(min, max) {
return min + Math.random() * (max - min);
}
clamp(n, a, b) {
return Math.max(a, Math.min(b, n));
}
start() {
if (this.running) return;
this.running = true;
const loop = () => {
if (!this.running) return;
this._raf = requestAnimationFrame(loop);
this._t += 1;
this._update();
this._draw();
};
loop();
}
stop() {
this.running = false;
if (this._raf) cancelAnimationFrame(this._raf);
this._raf = null;
}
_initScene(isResize = false) {
// Sterne (dezente Punkte im Himmel)
const starTarget = Math.floor(this.width * this.height * (0.00006 * this.opts.backgroundStars));
if (!isResize || this._stars.length === 0) {
this._stars = [];
for (let i = 0; i < starTarget; i++) {
this._stars.push({
x: this.rand(0, this.width),
y: this.rand(0, this.height * 0.6),
a: this.rand(0.08, 0.22),
r: this.rand(0.6, 1.4)
});
}
} else {
this._stars = this._stars.slice(0, starTarget);
while (this._stars.length < starTarget) {
this._stars.push({
x: this.rand(0, this.width),
y: this.rand(0, this.height * 0.6),
a: this.rand(0.08, 0.22),
r: this.rand(0.6, 1.4)
});
}
for (const s of this._stars) {
s.x = this.rand(0, this.width);
s.y = this.rand(0, this.height * 0.6);
}
}
// Schneeflocken
const target = Math.max(30, Math.floor(this.opts.flakeCount));
if (!isResize || this._flakes.length === 0) {
this._flakes = [];
for (let i = 0; i < target; i++) this._flakes.push(this._newFlake(true));
} else {
this._flakes = this._flakes.slice(0, target);
while (this._flakes.length < target) this._flakes.push(this._newFlake(true));
}
}
_newFlake(randomY = false) {
const z = this.rand(0, 1); // Tiefe: 0 nah/groß, 1 fern/klein
const size = this.rand(this.opts.sizeMin, this.opts.sizeMax) * (1.2 - 0.75 * z);
const speed = this.rand(this.opts.gravityMin, this.opts.gravityMax) * (1.15 - 0.65 * z);
return {
x: this.rand(0, this.width),
y: randomY ? this.rand(0, this.height) : -10,
r: size,
vy: speed,
phase: this.rand(0, Math.PI * 2),
sway: this.rand(0.25, 1.0) * this.opts.sway * (1.05 - 0.55 * z),
drift: this.rand(-0.25, 0.25),
alpha: this.clamp(this.rand(0.35, 0.9) * (1.1 - 0.55 * z), 0.18, 0.95)
};
}
_update() {
const gust =
Math.sin(this._t / 160) * this.opts.windGust +
Math.sin(this._t / 57) * (this.opts.windGust * 0.35);
const wind = this.opts.wind + gust;
for (const f of this._flakes) {
const sx = Math.sin((this._t / 60) + f.phase) * f.sway;
f.x += wind + f.drift + sx * 0.08;
f.y += f.vy;
if (f.x < -10) f.x = this.width + 10;
if (f.x > this.width + 10) f.x = -10;
if (f.y > this.height + 12) {
f.x = this.rand(0, this.width);
f.y = -12;
f.phase = this.rand(0, Math.PI * 2);
}
}
}
_drawBackground(ctx) {
// Himmel – Winterverlauf
const g = ctx.createLinearGradient(0, 0, 0, this.height);
g.addColorStop(0.00, "#0b1b3a");
g.addColorStop(0.45, "#163a6b");
g.addColorStop(1.00, "#2b5b86");
ctx.fillStyle = g;
ctx.fillRect(0, 0, this.width, this.height);
// Sterne (dezente Punkte)
ctx.save();
ctx.fillStyle = "#ffffff";
for (const s of this._stars) {
ctx.globalAlpha = s.a;
ctx.beginPath();
ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
ctx.fill();
}
ctx.restore();
// Nebelschleier
if (this.opts.haze > 0) {
ctx.save();
ctx.globalAlpha = Math.min(this.opts.haze, 0.3);
const hz = ctx.createLinearGradient(0, this.height * 0.2, 0, this.height);
hz.addColorStop(0, "rgba(255,255,255,0)");
hz.addColorStop(1, "rgba(255,255,255,1)");
ctx.fillStyle = hz;
ctx.fillRect(0, 0, this.width, this.height);
ctx.restore();
}
// Schneehügel (statische Layer)
const drawHill = (yBase, amp, color, alpha) => {
ctx.save();
ctx.globalAlpha = alpha;
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(0, this.height);
for (let x = 0; x <= this.width; x += Math.max(28, this.width / 22)) {
const y =
yBase +
Math.sin((x / this.width) * Math.PI * 2) * amp +
Math.sin((x / this.width) * Math.PI * 5) * (amp * 0.25);
ctx.lineTo(x, y);
}
ctx.lineTo(this.width, this.height);
ctx.closePath();
ctx.fill();
ctx.restore();
};
const h = this.height;
drawHill(h * 0.72, h * 0.03, "#e9f1ff", 0.95);
drawHill(h * 0.80, h * 0.05, "#d6e6ff", 0.92);
drawHill(h * 0.88, h * 0.08, "#c3ddff", 0.90);
// Vordergrund-Schnee
ctx.save();
ctx.globalAlpha = 0.96;
ctx.fillStyle = "#f4f8ff";
ctx.fillRect(0, this.height * 0.92, this.width, this.height * 0.08);
ctx.restore();
}
_drawFlakes(ctx) {
const blur = this.clamp(this.opts.blur, 0, 1);
if (blur > 0) {
ctx.shadowColor = "rgba(255,255,255,0.55)";
ctx.shadowBlur = 6 * blur;
} else {
ctx.shadowBlur = 0;
}
ctx.save();
ctx.globalCompositeOperation = "lighter";
ctx.fillStyle = "#ffffff";
for (const f of this._flakes) {
ctx.globalAlpha = f.alpha;
ctx.beginPath();
ctx.arc(f.x, f.y, f.r, 0, Math.PI * 2);
ctx.fill();
}
ctx.restore();
}
_draw() {
const ctx = this.ctx;
ctx.globalCompositeOperation = "source-over";
ctx.globalAlpha = 1;
ctx.clearRect(0, 0, this.width, this.height);
this._drawBackground(ctx);
this._drawFlakes(ctx);
}
}
// ===== Initialisierung =====
const box = document.getElementById("winterBox");
if (!box) return;
new WinterSnowInDiv(box, {
// Beispiel-Tuning:
// flakeCount: 260,
// wind: 0.18,
// haze: 0.12,
// blur: 0.2
});
})();
</script>
Notwendiges HTML:
<div id="winterBox"></div>
Notwendiges CSS:
#winterBox{
width: 100%;
height: 500px;
position: relative;
overflow: hidden; /* bleibt im Container */
border-radius: 12px;
border: 1px solid #d7dde6;
}