sf-sky-gradient
v0.1.0
Published
Extract San Francisco sky gradients from current and archived camera images
Maintainers
Readme
sf-sky-gradient
Extract San Francisco sky gradients from current and archived FogCam images. Get CSS, hex and RGB stops, and actual capture times. The package supports Node.js 22 or later and Bun.
Use the package
bun add sf-sky-gradient
# or: npm install sf-sky-gradientimport { getSkyGradient } from "sf-sky-gradient";
const sky = await getSkyGradient({ at: "2026-10-28T18:00:00-07:00" });
console.log(sky.css);
console.log(sky.stops);
console.log(sky.capturedAt);Omit at for the latest frame. Use image for a local file or camera URL. Custom images have null capture metadata.
const sky = await getSkyGradient({
image: "/path/to/sky.jpg",
crop: { left: 0, top: 0, width: 1, height: 0.4 },
stops: 7,
});Get each hour of a day
import { getDayGradients } from "sf-sky-gradient";
const day = await getDayGradients({ day: "2026-10-28" });
for (const sample of day.hours) {
console.log(sample.hour, sample.gradient?.css, sample.error);
}The date uses San Francisco time. A normal day returns 24 samples. Daylight saving changes produce 23 or 25 samples. Repeated hours include their UTC offset in requestedAt and their time zone in hour.
A missing frame produces an entry with gradient: null and an error message. HTTP failures and invalid API responses stop the request. The tool does not fill missing hours with colors from another hour.
Use the CLI
npx sf-sky-gradient --at '2026-10-28T18:00:00-07:00' --format css
npx sf-sky-gradient --preview sky.svg
npx sf-sky-gradient --day 2026-10-28 > day.json
npx sf-sky-gradient --helpThe CLI binary is included in sf-sky-gradient. After installing that package, run it through your package manager or node_modules/.bin/sf-sky-gradient.
API
getSkyGradient(options?)reads one image. Options areat,image,crop,stops, andmaxGapSeconds.getDayGradients({ day, ...options })samples each local hour. It acceptscrop,stops, andmaxGapSeconds.extractGradient(bytes, crop?, count?)extracts colors from image bytes without a network request.getGradientSvg(stops)returns an SVG preview from extracted stops.
Both archive functions accept an optional second fetch argument for a cache or other HTTP transport. SkyGradientError identifies package errors. FrameUnavailableError extends it for missing, stale, or future frames.
Each gradient includes css, stops, crop, and image dimensions. Archive results also include source, requestedAt, capturedAt, differenceSeconds, and attribution. Stops run from the upper sky at 0% to the lower sky at 100%. RGB values use sRGB and range from 0 to 255.
Use an ISO time with Z or an explicit UTC offset. A bare local time causes an error. The default maximum capture gap is 300 seconds. Set maxGapSeconds within 0-86400. A positive differenceSeconds means that the image is later than the requested time. Future images are not available.
Camera limits
The default crop is { left: 0.18, top: 0.06, width: 0.06, height: 0.39 }. It follows a narrow strip of clear sky down to the lowest visible sky in the current FogCam view. Coordinates are fractions of the full image. Set another crop when the camera view changes or you use another image.
The tool divides that crop into nine horizontal bands. It takes the median of each RGB channel in each band. Set stops within 2-32 to change the band count. The tool does not identify sky pixels. Keep buildings, trees, and camera text outside your crop.
Exposure, white balance, clouds, and camera direction affect the result. An overexposed sky can produce a nearly white gradient. The tool cannot recover colors that the camera lost. It measures one campus view and discards horizontal color changes.
The archive uses Fog-Bank's public API. Day indexes use San Francisco dates. Image paths use UTC dates. Credit: FogCam, San Francisco State University, archived by Fog-Bank. Camera photos have separate source terms. The MIT license in this repository applies to the code.
Develop
This workspace uses Bippy's pnpm, Vite+, Vitest, and Changesets tools. Use Node.js 22.18+, 24.11+, or 26+ for the development tools.
pnpm install
pnpm check
pnpm typecheck
pnpm test
pnpm build
pnpm publint
pnpm test:builtCreate an hourly SVG report and JSON data:
pnpm day 2026-10-28The report goes in output/2026-10-28. Each tile includes a source thumbnail and actual capture time. Open gradients.svg in your browser. Reports and camera images stay out of Git and npm.
Use pnpm changeset for a release note. Use pnpm version to apply version changes and pnpm release to publish with your npm credentials. Check the packed files and run the checks before publishing.
