npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

computer-graphics

v0.2.2

Published

CPU-based computer graphics playground for JS: 2D/3D transforms, ImageData, simple projection.

Readme

Computer Graphics in JS (Canvas, CPU-Based)

Demo GIFs

1) 3D Box: wireframe rotation with simple projection

3D Box Rotation

  • Shows live 2D transformations on polygons/rectangles using a simple animation loop.
  • The center-compensation keeps objects rotating/scaling around their centroid.

2) ImageData: per-pixel rendering as a vector and transformation

ImageData Translate

  • The image is drawn pixel-by-pixel via ImageData and moved with a simple translate.
  • Indexing uses base = (y * width + x) * 4 to access RGBA channels correctly.

3) 2D Transforms: rotate, scale, shear

2D Transforms

  • A minimal 3D-to-2D pipeline renders a rotating cube in wireframe.
  • Mouse-driven rotation simulates a camera-like experience.

A playground to learn and implement core computer graphics techniques in JavaScript on the CPU, step by step.

This project aims to demonstrate matrices, vectors, transformations (translate/rotate/scale/shear), a simple 3D → 2D projection, and pixel-level operations (ImageData) with an approachable, experiment-friendly setup. Everything intentionally runs on the CPU; the goal is learning rather than performance.

Contents & Architecture

  • 2D module (shapes/shapes2d.js)
    • Types: Point, Pixel
    • Transform base: translate, rotate, scale, shearX/Y/XY (with center compensation)
    • Polygon, Rectangle, Triangle (Triangle = Polygon[3])
    • ImageShape: builds pixels from ImageData and renders 1×1 fillRects (RGBA)
  • 3D module (shapes/shapes3d.js)
    • Transform3D and Box (wireframe cube)
    • A simple perspective approach and 2D projection (minimal teaching pipeline)
  • Canvas bootstrap (canvas/canvas.js)
    • Returns { canvas, ctx, dpr, clearCanvas, resize } and also sets window.__canvas__, window.__ctx__ for convenience
  • Vector/Matrix helpers (VectorJS/vector.js)
    • dot (matrix multiplication), normalize, 2D rotation helpers

Installation

npm i
npm run dev

Vite is used only for development (devDependency). A production-ready dist/ build or alternative bundlers can be added later.

Quick Start

The snippet below adds a rectangle and a polygon to the scene and applies basic transforms:

import { initCanvas, Rectangle, Polygon } from "computer-graphics";

const { clearCanvas } = initCanvas("canvas1", window.innerWidth, window.innerHeight);

const rect = new Rectangle(100, 100, 120, 80);
const poly = new Polygon([300, 300], [360, 220], [420, 320], [340, 360]);

function animate() {
  clearCanvas();
  rect.rotate(1);
  poly.shearX(Math.sin(0.01));
  rect.draw();
  poly.draw(true);
  requestAnimationFrame(animate);
}

animate();

Working with ImageData (Pixel Level)

  • Draw the image onto the canvas, then grab the pixel buffer with getImageData.
  • Correct indexing: base = (y * width + x) * 4 → iterate [r,g,b,a] in order.
  • ImageShape converts pixels into Pixel objects and paints them with 1×1 fillRects.
import { initCanvas, ImageShape } from "computer-graphics";

const { ctx } = initCanvas("canvas1", window.innerWidth, window.innerHeight);

const image = new Image();
image.src = "./assets/img.jpg";
image.onload = () => {
  const w = image.naturalWidth, h = image.naturalHeight;
  ctx.drawImage(image, 0, 0, w, h);
  const { data } = ctx.getImageData(0, 0, w, h);
  const img = new ImageShape(0, 0, data, w, h);
  img.translate(200, 200);
  img.rotate(37);
  img.draw();
};

Note: If you want to use alpha in the 0–1 range, divide by 255 (a/255).

3D → 2D Projection (Educational)

  • A Box is created in 3D space and projected to 2D before drawing.
  • Rotations (rotateX/Y/Z) operate directly on 3D vertices, around the shape’s center.
  • Camera model/focal length and related parameters can be extended later.
import { initCanvas, Box } from "computer-graphics";

const { clearCanvas } = initCanvas("canvas1", window.innerWidth, window.innerHeight);
const box = new Box([500, 500, 1.5], 500);

function animate() {
  clearCanvas();
  box.rotateY(1);
  box.draw();
  requestAnimationFrame(animate);
}
animate();

Design Choices & Learning Notes

  • As long as transforms are affine, a shape’s centroid moves linearly; center handling matters.
  • For GUI slider inputs, prefer “absolute” semantics (e.g., scale relative to the original, not cumulatively per frame).
  • If canvas CSS size differs from its real resolution, you might see blur; consider devicePixelRatio.
  • We return ctx and also expose a global for convenience; prefer passing ctx explicitly for encapsulation/testing.

Roadmap

  • [ ] Camera parameters (orthographic/perspective, f, near/far, view matrix)
  • [ ] Absolute T·R·S model matrix per frame (reduce cumulative errors)
  • [ ] Triangle rasterization, barycentric coordinates, z-buffer (depth test)
  • [ ] Basic lighting (Lambert/Phong) — CPU-based
  • [ ] OffscreenCanvas / Worker experiment for pixel rendering
  • [ ] Production package (ESM/CJS) and a minimal demo page

Run / Development

npm run dev   # development server
# npm run build  # production build (planned)

Contributing

  • Feel free to open issues or PRs for bugs and improvements.
  • Since the goal is learning, small, focused PRs with explanatory commit messages are appreciated.

This repository is meant to be a practical toolbox for “Computer Graphics 101”. Code and comments are intentionally simple to maximize learnability and experimentation. Have fun!