Bacon Screensaver (2018)
This is a tiny joke project with a serious constraint: keep it safe. Anything that looks like a “screensaver download” is a magnet for sketchy bundlers and weird executables, so the clean approach is to make a local animated page you can run yourself.
The end result is still the same vibe: bacon floating around the screen while you’re away from the keyboard.
What we’re making
A screensaver-style animation has three parts:
- A full-screen view.
- A loop that updates positions over time.
- A way to exit quickly (any key or mouse movement).
We can get 90% of that with a browser in full-screen mode and a local HTML file.
Assets: keep it simple (and make your own)
You only need a few bacon images (PNG or WebP with transparency). If you want to draw your own:
- Inkscape is great for vector shapes and clean outlines.
- GIMP is great for quick raster paint/texture work and exporting PNGs.
Aim for 2–6 variations so it doesn’t feel too repetitive.
A safe modern remake: local HTML + CSS + JS
Save this as bacon.html in a folder next to your image files (b1.png, b2.png, b3.png, etc). Then open it in a browser.
<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bacon</title>
<style>
html, body { height: 100%; }
body { margin: 0; background: #111; overflow: hidden; }
.b {
position: absolute;
width: 240px;
opacity: .85;
box-shadow: 0 18px 30px rgba(0,0,0,.45);
will-change: transform;
user-select: none;
pointer-events: none;
}
</style>
<script>
const images = ["b1.png", "b2.png", "b3.png"]; // local files
const count = 18;
const items = [];
function rand(min, max) { return Math.random() * (max - min) + min; }
for (let i = 0; i < count; i++) {
const el = document.createElement("img");
el.className = "b";
el.alt = "bacon";
el.src = images[i % images.length];
document.body.appendChild(el);
items.push({
el,
x: rand(0, window.innerWidth),
y: rand(0, window.innerHeight),
speed: rand(15, 55),
drift: rand(0.3, 1.2),
rot: rand(-40, 40),
phase: rand(0, Math.PI * 2)
});
}
let last = performance.now();
function frame(now) {
const dt = Math.min(0.05, (now - last) / 1000);
last = now;
for (const it of items) {
it.phase += dt * it.drift;
it.y += dt * it.speed;
it.x += Math.sin(it.phase) * 20 * dt;
if (it.y > window.innerHeight + 260) {
it.y = -260;
it.x = rand(0, window.innerWidth);
}
it.el.style.transform = `translate(${it.x}px, ${it.y}px) rotate(${it.rot}deg)`;
}
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
window.addEventListener("resize", () => {
// Keep things bounded when the screen size changes.
for (const it of items) {
it.x = Math.min(it.x, window.innerWidth);
it.y = Math.min(it.y, window.innerHeight);
}
});
</script>
Why requestAnimationFrame? It syncs updates to the browser’s paint loop and usually behaves better than timers for animation.
Running it like a screensaver
This depends on your OS and personal preference, but the simplest approach is:
- Open the file in a browser.
- Go full-screen.
- Hide the cursor if your browser/OS supports it.
If you want it to feel more “screensaver-like”, keep the page minimal: no UI, no links, no external resources.
Links we trust
Related
- Tools we use: /release1-2-tools.html
- Learning notes: /release1-2-railsgirls.html