跪拜 Guibai
← Back to the summary

Pixel Effects as Code: 244 JavaScript FX with a Live Gallery and a Claude Code Skill

When making games, effects like fire, explosions, frost, and lightning are a common pain point: you want them to feel dynamic, but hand-drawing them takes time; finding ready-made images often means you can't change colors or scale, and they may not fit your game.

pixelfx is an open-source pixel effect library. It encodes each effect as a short piece of JavaScript code and currently includes 244 effects. You can open a webpage to watch animations, search by category, and change color schemes. If one suits you, you can drop the code straight into your game, or export it as sprite sheets.

Project repo: patch-gg/pixelfx Online gallery: Open pixelfx Gallery

244 effects, viewable from a webpage

The effects are grouped by use case: fire, explosion, water, ice, lightning, magic, weather, items, UI animations, and more. You'll find campfires, fireballs, frost novas, coin pickups, crit numbers — most common game effects are covered.

The online gallery isn't a set of static images; effects animate live. You can browse by category or search by keyword; click into an effect to adjust playback speed, background, color, and orientation. Some effects accept a random seed, letting you see different variations of the same effect.

More than "just show an effect" — character motion is considered

pixelfx has a practical design: some attack effects don't only describe sparks or blade trails; they also record when the character winds up, when the attack lands, how long the hit-stop lasts, and how the target recoils.

The same glowing effect feels very different when pasted onto a static character versus matched with swing, hit, and recovery animations. The project encodes this attack timing as data; with the built-in character, you can preview character and effect together. If you use your own character, you can still reference the timing included.

Effects are code, not images

Each effect is usually a file under src/fx/category/name.js. For a campfire, src/fx/fire/campfire.js describes the logs, charcoal, flames, smoke, sparks, and embers. Each time it draws a frame, it computes the position and appearance of these parts based on time.

This means an effect isn't locked into a single image: it can play at runtime, accept a different palette, be mirrored or rotated. JavaScript games can call the code directly; other engines like Godot or Unity can use the exported sprite sheets and matching JSON.

How the core code fits together?

Think of it as three parts: effect code decides what to draw, the core utilities decide how to draw, and the game decides when to update and display.

1. Each effect declares its info and drawing approach

An effect file provides basic info such as name, canvas size, playback duration, whether it loops, and default colors. Drawing comes in two forms:

Both approaches are simple for the caller: create the effect, update it, draw it to the canvas.

2. Painter turns code into pixels

The core drawing tool lives in src/core/painter.js. It provides methods for drawing pixels, lines, circles, glows, and more; effect files call these to write colors into the frame.

It also splits the frame into two layers: one for normal pixel colors, one for extra glow effects, then composites them. This way a fire isn't just an orange shape; warm light surrounds it. Explosion highlights stand out more than ordinary particles.

3. createFx manages playback

createFx in src/core/fx.js turns an effect module into a playable instance. Each game frame calls update(dt) to advance time, then draw(frame) to render. Position, flipping, palette, and other options are passed in at creation.

The README shows a usage pattern roughly like this:

import { createFrame, clearFrame, createFx, composite } from "pixelfx";
import * as frostNova from "pixelfx/fx/ice/frost-nova";

const frame = createFrame(320, 180);
const img = new ImageData(320, 180);
const fx = createFx(frostNova, { x: 160, y: 140 });

function tick(dt) {
  fx.update(dt);
  clearFrame(frame);
  fx.draw(frame);
  composite(frame, img.data, backgroundColor);
  ctx.putImageData(img, 0, 0);
}

In short, the game supplies time and position; pixelfx draws the corresponding pixels; the game displays them. The project also supports exporting sprite sheets for engines that don't run JavaScript directly.

A campfire is more than a flame

Take campfire.js as an example: it doesn't simply draw a flame outline. It decomposes the scene into many pieces: crossed logs, charcoal underneath, flames of varying height and width, drifting smoke, occasional sparks, slowly rising embers, and warm light on the ground.

Each part changes at a different speed: flames flicker, smoke disperses, embers rise; but the campfire must loop, so these changes have to loop back naturally. The code uses a fixed random seed to arrange details, so under the same seed the effect reproduces reliably and animation export is stable.

When reading the code, you don't need to understand every math calculation first. Look at the meta for name, size, and options, then see how draw(p, t, o) calls the drawing methods for fire, smoke, and lighting; that gives you a rough picture of how an effect is assembled.

Who is this for?

If you're making a pixel-art game, pixelfx works as a ready-made effect library and as a reference for how to decompose and draw effects. Even non-developers can browse the online gallery: watch how a fire sways, see how a character pauses on hit, and observe how a piece of code becomes a tiny animation.

The project also includes a Claude Code skill to help modify existing effects or create new ones. Whether or not you use that feature, pixelfx's core idea is straightforward: treat an effect as a drawing that changes over time, not as an image that can't be edited.

The project is MIT licensed; code and effects can be used in commercial projects.