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

lumi-crop

v0.2.0

Published

Framework-agnostic, dependency-free image cropping library

Readme

LumiCrop

A lightweight, framework-agnostic, and dependency-free image cropping engine for modern web applications. LumiCrop provides a headless architecture, featuring a fixed crop box, smooth panning and pinch-to-zoom, rotation support, and pixel-perfect canvas export.

Features

  • Zero Dependencies: Built entirely with standard Web APIs (Canvas, Touch Events, Pointer Events).
  • Framework Agnostic: Works seamlessly with Vanilla JS, React, Vue, Angular, or any other web framework.
  • Headless Architecture: You provide the UI controls; LumiCrop handles the complex math, rendering, and interactions.
  • TypeScript Ready: Strongly typed for excellent developer experience.

Installation

npm install lumi-crop

Quick Start

import { LumiCrop } from 'lumi-crop';

// 1. Get your canvas element
const canvasElement = document.getElementById('crop-preview-canvas');

// 2. Initialize the cropper
const cropper = new LumiCrop({
    canvas: canvasElement,
    image: 'path/to/image.jpg', // Can be a URL, a File object, or an HTMLImageElement
    aspectRatio: 16 / 9         // Optional: Lock aspect ratio
});

// 3. Wait for the image to load and the engine to initialize
await cropper.ready();

// 4. Export the cropped result when the user confirms
const blob = await cropper.toBlob({ 
    type: 'image/jpeg', 
    quality: 0.95 
});

// Use the blob (e.g., upload to server or display)
const objectUrl = URL.createObjectURL(blob);
console.log('Cropped image blob:', blob);

API Reference

LumiCropOptions

Configuration object passed to the LumiCrop constructor.

| Property | Type | Default | Description | | :--- | :--- | :--- | :--- | | canvas | HTMLCanvasElement | (Required) | The target canvas element used for viewport rendering. | | image | string \| File \| HTMLImageElement | (Required) | The source image to be cropped. | | aspectRatio | number | undefined | Optional initial aspect ratio lock (e.g., 16/9). | | devicePixelRatio | number | window.devicePixelRatio | Pixel ratio for rendering crispness on high-DPI displays. | | idleAutoFitDelayMs | number | 0 (Disabled) | Delay in milliseconds before auto-fitting/auto-centering the image after an interaction ends. | | idleAutoFitAnimationDurationMs | number | 280 | Duration of the auto-fit transition animation in milliseconds. | | style | object | {} | Complete styling configuration to customize crop handles, colors, and grid. See below. |

Styling Options (style)

Pass an optional style object to customize the crop overlay UI.

| Property | Type | Default | Description | | :--- | :--- | :--- | :--- | | handleColor | string | '#ffffff' | Color of the L-shaped resize corner handles and edge handles. | | handleLineWidth | number | 4 | Stroke width (thickness) of the crop handles in pixels. | | handleLength | number | 20 | Visual length of the corner handles and edge handles. | | cropBorderColor | string | '#ffffff' | Color of the main thin crop box border. | | cropBorderLineWidth | number | 1 | Stroke width of the main crop box border. | | gridColor | string | 'rgba(255, 255, 255, 0.3)' | Color of the rule-of-thirds internal grid lines. | | gridLineWidth | number | 1 | Stroke width of the internal grid lines. | | maskColor | string | 'rgba(0, 0, 0, 0.5)' | Color and opacity of the darkened mask outside the crop area. |

Instance Methods

The LumiCrop instance exposes the following methods for interacting with the crop engine.

| Method | Returns | Description | | :--- | :--- | :--- | | ready() | Promise<void> | Resolves when the source image has fully loaded and the engine is ready for interaction. | | setAspectRatio(ratio: number \| null) | void | Updates the crop box constraint. Pass null for a freeform crop box (no aspect ratio). | | setCropBox(box: CropBox) | void | Manually sets the crop box dimensions and position. | | getCropBox() | CropBox | Returns the current crop box coordinates ({ x, y, width, height }). | | rotate90(clockwise: boolean = true) | void | Rotates the image by 90 degrees around its anchor point. | | setRotation(degrees: number) | void | Sets an absolute rotation value in degrees (0 to 360). | | flipX() | void | Flips the image horizontally. | | flipY() | void | Flips the image vertically. | | setZoom(scale: number) | void | Sets an absolute zoom scale factor. | | zoomBy(delta: number) | void | Adjusts the current zoom by a relative delta. | | fitCropBoxToViewport() | void | Forces the crop box to center and fit within the visible canvas viewport boundaries. | | getZoom() | number | Returns the current effective zoom scale. | | toBlob(options?: ToBlobOptions) | Promise<Blob> | Renders the cropped area and returns it as a Blob. See ToBlobOptions below. | | destroy() | void | Cleans up event listeners, removes internal DOM elements, and frees memory. |

ToBlobOptions

Options for the toBlob export method.

| Property | Type | Default | Description | | :--- | :--- | :--- | :--- | | type | 'image/png' \| 'image/jpeg' \| 'image/webp' | 'image/png' | The MIME type of the exported image. | | quality | number | undefined | Compression quality for JPEG or WEBP formats (between 0.0 and 1.0). | | maxWidth | number | undefined | Maximum width in pixels for the output image. Ratio is preserved. | | maxHeight | number | undefined | Maximum height in pixels for the output image. Ratio is preserved. |

TODO

  • [x] Publish to NPM
  • [x] Customizable Handle
  • [ ] Customizable Grid

License

Copyright 2026 Khalif. Licensed under the Apache License 2.0.