Hey everyone,
Today I want to share the story behind a fun little addition to hive.micro
: the animated bee that appears when you start typing a new post. This was a great suggestion from @themarkymark to add a bit of life to the page, and it turned into a fun little project.
The first step was to take the pixel art bee from the logo and prepare it for animation. I made its wings a bit more pronounced and added a small stinger.
From there, I created three distinct frames in GIMP to simulate a flapping motion:
To create a smooth, looping animation, the sequence of frames is: Wings Up -> Wings Gone -> Wings Down -> Wings Gone. This creates a full flapping cycle.
I then exported these layers as a GIF, with each frame having a 100ms delay and set to loop forever.
The final result is a simple but effective flapping bee.
To make it look like the bee is typing along with you, I used a little JavaScript trick. It's actually two separate images: a static one (wings_up.png
) and the animated GIF.
When the page loads, you see the static image. As soon as you start typing in the text area, a JavaScript event listener swaps the image source to the animated GIF. When you stop typing, a short timer waits 800 milliseconds and then swaps it back to the static image.
Here's the HTML where the two image live.
<div id="typingBee">
<img
id="typingBeeImg"
src="img/wings_up.png"
data-static="img/wings_up.png"
data-anim="img/flappy_bee.gif"
alt="Bee"
style="height: 48px; width: auto;"
/>
</div>
Here's the relevant JavaScript code that handles the logic:
// Abridged code for clarity
const ta = document.getElementById("postContent");
const typingBeeImg = document.getElementById("typingBeeImg");
let typingTimeout = null;
function setBeeAnimated(animated) {
if (!typingBeeImg) return;
const staticSrc = typingBeeImg.getAttribute("data-static");
const animSrc = typingBeeImg.getAttribute("data-anim");
typingBeeImg.src = animated ? animSrc : staticSrc;
}
if (ta) {
ta.addEventListener("input", function () {
const hasText = (ta.value || "").trim().length > 0;
if (hasText) {
setBeeAnimated(true);
if (typingTimeout) clearTimeout(typingTimeout);
typingTimeout = setTimeout(() => setBeeAnimated(false), 800);
} else {
setBeeAnimated(false);
}
});
ta.addEventListener("blur", function () {
setBeeAnimated(false);
});
// Ensure static image on load
setBeeAnimated(false);
}
It's a simple effect, but I think it adds a nice, playful touch to the interface.
As always,
Michael Garcia a.k.a. TheCrazyGM