Seamark

A seamark is a fixed thing you can see from the water and steer by. This library does the same for a web page: it reads real values out of rendered graphics.

It reads the picture. You get the numbers.

Coordinates

SVG user units, CSS pixels, an iframe's viewport and screenshot space, with every conversion explicit. Mixing two gives plausible numbers, never an error.

Curves

Sample a drawn path into data space, find where it crosses a level, fit a circle from a partial arc, and tell linear from quadratic from exponential.

Expressions

Compare rendered maths by fingerprint over several sample points. x(x+8) and x²+8x share no characters and agree at exactly the point you would test first.

Widgets

Pick the iframe that is actually visible, pin labels to the edges and points they annotate, plan the drags a dot plot needs, and click in a way frameworks accept.

Draw something. It only measures what's on screen.

Measured from the drawing

Samples
x range
y range
Crosses y=0 at
Branch
Family
Circle fit

Every number is derived from the rendered path: sampled, mapped out of SVG user units, and reported in grid coordinates. The demo never hands over the points it drew with.

Runs everywhere.

The same measurements, in six languages, on whatever you have in front of you.

iPhone & iPad

A native SwiftUI app. Draw with a finger, read the numbers.

Build from source →

Mac

Same app, same engine, a real window and a trackpad.

Build from source →

Android

Native Compose app. Same engine, ported to Kotlin.

Build from source →

Windows & Linux

The Compose app packaged as an installer, MSI or DEB.

Build from source →

Web

Nothing to install. The demo above is the whole thing.

Try it →

In your code

A small JavaScript library with no dependencies.

npm install seamark →

Harder than it looks.

A picture on a web page is measured in four different rulers at once: the drawing's own units, the page's pixels, the little frame it sits in, and the screenshot you took of it. Mix up any two and you get a number that looks perfectly reasonable and is quietly wrong. Seamark keeps every ruler straight, reads the curve the way a person would, and checks that two formulas really are the same by testing them at several points, not just the one that always agrees.

Use it.

import { samplePath, crossings, fitCircle, family, makeDataSpace } from 'seamark';

const space = makeDataSpace(originInPagePx, oneUnitInPagePx);
const points = samplePath(document.querySelector('svg path'), space.toData);

crossings(points);   // x values where the curve meets y = 0
fitCircle(points);   // { cx, cy, r }, works on a partial arc
family(points);      // 'linear' | 'quadratic' | 'exponential' | null