Skip to content

Instantly share code, notes, and snippets.

@thecompez
Last active December 18, 2025 07:19
Show Gist options
  • Select an option

  • Save thecompez/d217ded54ffa76e81e46ad1a3cce75ab to your computer and use it in GitHub Desktop.

Select an option

Save thecompez/d217ded54ffa76e81e46ad1a3cce75ab to your computer and use it in GitHub Desktop.
Snowing
import <iostream>;
import <vector>;
import <string>;
import <random>;
import <chrono>;
import <thread>;
import <cmath>;
import <cstdlib>;
import <algorithm>;
#include <locale>
struct Snowflake {
int x, y; // position
int speed; // frames per movement
int counter; // for speed timing
std::string symbol; // Unicode snowflake
double brightness; // simulate fade-in/out
};
int main() {
std::setlocale(LC_ALL, ""); // enable UTF-8 output
const int width = 80;
const int height = 24;
const int numFlakes = 120;
std::vector<Snowflake> flakes(numFlakes);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> xDist(0, width-1);
std::uniform_int_distribution<> yDist(0, height-1);
std::uniform_int_distribution<> speedDist(1,4);
std::uniform_int_distribution<> symbolDist(0,3);
std::uniform_real_distribution<> brightnessDist(0.3,1.0);
std::uniform_int_distribution<> driftDist(-1,1);
const std::vector<std::string> symbols = {"*", "❄", "❅", "❆"};
for (auto &f : flakes) {
f.x = xDist(gen);
f.y = yDist(gen);
f.speed = speedDist(gen);
f.counter = 0;
f.symbol = symbols[symbolDist(gen)];
f.brightness = brightnessDist(gen);
}
double wind = 0.0;
double targetWind = 0.0;
std::uniform_real_distribution<> windDist(-0.3,0.3);
while (true) {
// gradually change wind
targetWind += windDist(gen) * 0.05;
wind += (targetWind - wind) * 0.05;
// clear screen
#ifdef _WIN32
std::system("cls");
#else
std::cout << "\x1B[2J\x1B[H";
#endif
// frame buffer
std::vector<std::string> frame(height, std::string(width,' '));
// update flakes
for (auto &f : flakes) {
f.counter++;
if(f.counter >= f.speed) {
f.y++;
f.x += static_cast<int>(std::round(driftDist(gen) + wind));
if(f.x < 0) f.x = 0;
if(f.x >= width) f.x = width-1;
if(f.y >= height) {
f.y = 0;
f.x = xDist(gen);
f.symbol = symbols[symbolDist(gen)];
f.brightness = brightnessDist(gen);
f.speed = speedDist(gen);
}
f.counter = 0;
}
// simulate fade: dim flakes near top
int color = static_cast<int>(232 + f.brightness * 23); // grayscale ANSI
std::cout << "\033[" << f.y+1 << ";" << f.x+1 << "H"
<< "\033[38;5;" << color << "m" << f.symbol;
}
std::cout << "\033[0m"; // reset color
std::cout.flush();
std::this_thread::sleep_for(std::chrono::milliseconds(80));
}
return 0;
}
main.qml:
import QtQuick 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
visible: true
width: 1200
height: 800
title: "Merry Christmas ❄️"
Rectangle {
anchors.fill: parent
color: "#0b1c2d" // night sky
}
Snow { anchors.fill: parent }
Text {
anchors.centerIn: parent
text: "πŸŽ„ Merry Christmas πŸŽ…"
color: "white"
font.pixelSize: 48
font.bold: true
}
}
Snow.qml:
import QtQuick 2.15
import QtQuick.Particles 2.15
Item {
id: root
anchors.fill: parent
ParticleSystem {
id: ps
}
// ❄️ Emitter (randomized at birth)
Emitter {
system: ps
width: parent.width
height: 1
anchors.top: parent.top
emitRate: 100
lifeSpan: 6000
lifeSpanVariation: 6000
size: 10
sizeVariation: 12
velocity: AngleDirection {
angle: 270 // down
angleVariation: 15
magnitude: 60
magnitudeVariation: 80
}
}
// 🌬 Random wind per particle (not shared)
Wander {
system: ps
xVariance: 120
yVariance: 10
pace: 40
}
// ⬇ Gravity (subtle, not uniform)
Gravity {
system: ps
magnitude: 12
}
// ❄ Unicode snowflakes (no images)
ItemParticle {
system: ps
delegate: Text {
text: {
// random snow symbol per particle
const flakes = ["❄", "❅", "❆", "✻"];
flakes[Math.floor(Math.random() * flakes.length)];
}
color: "white"
opacity: 0.4 + Math.random() * 0.6
font.pixelSize: 8 + Math.random() * 18
font.family: "Arial"
// 🎲 Unique rotation per particle
RotationAnimator on rotation {
from: Math.random() * 360
to: from + (Math.random() * 720 - 360)
duration: 2000 + Math.random() * 4000
loops: Animation.Infinite
}
}
}
}
<div id="snow-container"></div>
/* Snow container */
#snow-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
overflow: hidden;
z-index: 9999;
}
/* Snowflake */
.snowflake {
position: absolute;
top: -10px;
color: white;
font-size: 1em;
user-select: none;
opacity: 0.8;
animation-name: fall;
animation-timing-function: linear;
}
/* Falling animation */
@keyframes fall {
to {
transform: translateY(110vh);
}
}
<script>
(() => {
const snowContainer = document.getElementById("snow-container");
const snowflakesCount = 80; // ❄️ adjust amount
function createSnowflake() {
const snowflake = document.createElement("div");
snowflake.className = "snowflake";
snowflake.innerHTML = "❄";
const size = Math.random() * 12 + 8;
const left = Math.random() * 100;
const duration = Math.random() * 5 + 5;
const opacity = Math.random() * 0.5 + 0.3;
snowflake.style.fontSize = `${size}px`;
snowflake.style.left = `${left}%`;
snowflake.style.animationDuration = `${duration}s`;
snowflake.style.opacity = opacity;
snowContainer.appendChild(snowflake);
// Remove after animation
setTimeout(() => {
snowflake.remove();
}, duration * 1000);
}
// Generate snow continuously
setInterval(() => {
if (snowContainer.children.length < snowflakesCount) {
createSnowflake();
}
}, 200);
})();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment