Skip to content

Utility Modules Reference

DocuShark's core utility modules provide math primitives, color manipulation, file handling, and export functionality. All math types are immutable — every operation returns a new instance.

Math Utilities

Location: src/math/ — All re-exported from src/math/index.ts

Vec2 src/math/Vec2.ts

2D immutable vector. All methods return new instances.

Static Factories

MethodReturnsDescription
Vec2.zero()Vec2(0, 0)
Vec2.unitX()Vec2(1, 0)
Vec2.unitY()Vec2(0, 1)
Vec2.fromArray([x, y])Vec2From tuple
Vec2.fromObject({x, y})Vec2From plain object

Static Operations

MethodReturnsDescription
Vec2.add(a, b)Vec2Vector addition
Vec2.subtract(a, b)Vec2Vector subtraction
Vec2.multiply(v, scalar)Vec2Scalar multiplication
Vec2.divide(v, scalar)Vec2Scalar division (throws on zero)
Vec2.dot(a, b)numberDot product
Vec2.cross(a, b)numberCross product (z-component)
Vec2.distance(a, b)numberEuclidean distance
Vec2.distanceSquared(a, b)numberSquared distance (avoid sqrt)
Vec2.lerp(a, b, t)Vec2Linear interpolation
Vec2.min(a, b)Vec2Component-wise minimum
Vec2.max(a, b)Vec2Component-wise maximum
Vec2.negate(v)Vec2Negate both components

Instance Methods

MethodReturnsDescription
add(other)Vec2Add vectors
subtract(other)Vec2Subtract vectors
multiply(scalar)Vec2Scale
divide(scalar)Vec2Divide
dot(other)numberDot product
cross(other)numberCross product
negate()Vec2Negate
length()numberMagnitude
lengthSquared()numberSquared magnitude
normalize()Vec2Unit vector (handles zero)
rotate(angle)Vec2Rotate by radians (CCW)
rotateAround(center, angle)Vec2Rotate around point
lerp(other, t)Vec2Interpolate
distanceTo(other)numberDistance
angle()numberAngle in radians (atan2)
angleTo(other)numberAngle to other vector
perpendicular()Vec290° CCW rotation
equals(other, epsilon?)booleanApproximate equality
clone()Vec2Copy
toArray()[number, number]To tuple
toObject(){x, y}To plain object

Mat3 src/math/Mat3.ts

3x3 matrix for 2D affine transforms. Column-major order.

| a  c  e |   | m[0]  m[2]  m[4] |
| b  d  f | = | m[1]  m[3]  m[5] |
| 0  0  1 |   | 0     0     1    |

Static Factories

MethodReturnsDescription
Mat3.identity()Mat3Identity matrix
Mat3.translation(tx, ty)Mat3Translation matrix
Mat3.translationVec(v)Mat3Translation from Vec2
Mat3.rotation(angle)Mat3Rotation (CCW radians)
Mat3.rotationAt(angle, center)Mat3Rotation around point
Mat3.scale(s)Mat3Uniform scale
Mat3.scaleXY(sx, sy)Mat3Non-uniform scale
Mat3.scaleAt(sx, sy, center)Mat3Scale around point

Instance Methods

MethodReturnsDescription
multiply(other)Mat3Matrix multiply (applies other first)
preMultiply(other)Mat3Applies this first
transformPoint(point)Vec2Transform point (includes translation)
transformVector(vector)Vec2Transform direction (ignores translation)
inverse()Mat3 | nullInverse (null if singular)
determinant()numberMatrix determinant
translate(tx, ty)Mat3Chain translation
rotate(angle)Mat3Chain rotation
scale(s)Mat3Chain uniform scale
scaleXY(sx, sy)Mat3Chain non-uniform scale
applyToContext(ctx)voidApply as canvas transform
setOnContext(ctx)voidSet as canvas transform (replaces)
isIdentity(epsilon?)booleanCheck if identity
equals(other, epsilon?)booleanApproximate equality

TIP

a.multiply(b) applies b first, then a. This matches standard matrix composition order — the rightmost transform is applied first.


Box src/math/Box.ts

Axis-Aligned Bounding Box (AABB). Immutable, auto-normalizes on construction.

Static Factories

MethodReturnsDescription
Box.fromPoints(p1, p2)BoxFrom two corners
Box.fromPointArray(points)BoxEnclosing box for point array
Box.fromCenter(center, w, h)BoxFrom center and dimensions
Box.fromPositionSize(pos, w, h)BoxFrom top-left and dimensions
Box.empty()BoxZero-size box at origin
Box.infinite()BoxInfinite bounds

Properties

PropertyTypeDescription
minX, minY, maxX, maxYnumberBoundary edges
width, heightnumberDimensions
centerX, centerYnumberCenter coordinates
centerVec2Center as vector
topLeft, topRight, bottomLeft, bottomRightVec2Corner points
areanumberWidth × height
perimeternumber2 × (width + height)
isEmptybooleanZero area

Instance Methods

MethodReturnsDescription
containsPoint(point)booleanInclusive boundary
containsPointStrict(point)booleanExclusive boundary
containsBox(other)booleanFully contains other
intersects(other)booleanOverlaps (inclusive)
intersectsStrict(other)booleanOverlaps (exclusive)
union(other)BoxSmallest enclosing box
intersection(other)BoxOverlap region
expandToInclude(point)BoxGrow to include point
expand(amount)BoxExpand uniformly
expandXY(amountX, amountY)BoxExpand per-axis
shrink(amount)BoxContract uniformly
translate(offset)BoxMove by Vec2
scaleFromCenter(scale)BoxScale from center
clampPoint(point)Vec2Nearest point inside
distanceToPoint(point)number0 if inside
getCorners()[Vec2, Vec2, Vec2, Vec2][TL, TR, BR, BL]
toRBush(){minX, minY, maxX, maxY}For spatial index

Geometry Functions src/math/geometry.ts

Standalone geometry helpers used throughout the engine.

Point-in-Shape Tests

FunctionDescription
pointInRect(point, x, y, w, h)Axis-aligned rectangle
pointInRotatedRect(point, x, y, w, h, rotation)Rotated rectangle
pointInCircle(point, cx, cy, r)Circle
pointInEllipse(point, cx, cy, rx, ry)Axis-aligned ellipse
pointInRotatedEllipse(point, cx, cy, rx, ry, rotation)Rotated ellipse

Line Intersection & Distance

FunctionReturnsDescription
lineIntersection(p1, p2, p3, p4)LineIntersectionInfinite line intersection
segmentIntersection(p1, p2, p3, p4)Vec2 | nullLine segment intersection
distanceToLine(point, start, end)numberDistance to infinite line
distanceToSegment(point, start, end)numberDistance to line segment
closestPointOnSegment(point, start, end)Vec2Nearest point on segment
pointOnSegment(point, start, end, tol?)booleanIs point on segment?
boxIntersectsSegment(box, p1, p2)booleanAABB vs line segment

Angle & Rotation

FunctionReturnsDescription
angleBetween(v1, v2)number[0, π] radians
signedAngleBetween(v1, v2)number[-π, π] (CCW positive)
rotatedRectBounds(cx, cy, w, h, rot)BoxAABB of rotated rect
normalizeAngle(angle)numberNormalize to [-π, π]
degToRad(degrees)numberDegrees → radians
radToDeg(radians)numberRadians → degrees

Utility

FunctionReturnsDescription
lerp(a, b, t)numberLinear interpolation
easeInOutCubic(t)numberCubic easing for animations
clamp(value, min, max)numberClamp to range
approxEqual(a, b, epsilon?)booleanFloat comparison (default ε=1e-10)

Color Utilities src/utils/color.ts

Color conversion and manipulation functions.

Types

typescript
interface RGB { r: number; g: number; b: number }     // 0-255
interface RGBA extends RGB { a: number }               // a: 0-1
interface HSL { h: number; s: number; l: number }      // h: 0-360, s/l: 0-100

Functions

FunctionReturnsDescription
hexToRgb(hex)RGB | nullParse #RGB, #RRGGBB, #RRGGBBAA
hexToRgba(hex)RGBA | nullParse with alpha channel
rgbToHex(rgb)string#RRGGBB
rgbaToHex(rgba)string#RRGGBBAA
rgbToHsl(rgb)HSLRGB → HSL conversion
hslToRgb(hsl)RGBHSL → RGB conversion
lighten(hex, amount)stringLighten by 0–100
darken(hex, amount)stringDarken by 0–100
isLightColor(hex)booleanUses relative luminance
getContrastColor(bg)stringReturns '#000000' or '#ffffff'

TIP

Use getContrastColor() for text on colored backgrounds to ensure readability.


File Utilities src/utils/fileUtils.ts

File type detection, formatting, and validation helpers.

Types

typescript
type FileCategory = 'pdf' | 'spreadsheet' | 'image' | 'audio' | 'video' | 'text' | 'generic';

Functions

FunctionReturnsDescription
detectFileCategory(mimeType, fileName)FileCategoryCategorize for viewer selection
getMimeType(fileName)stringGuess MIME from extension
isPreviewableFile(mimeType)booleanHas specialized viewer?
formatFileSize(bytes)string"1.5 MB", "128 B", etc.
validateFileForEmbed(file)string | nullError message or null if valid
sanitizeFileName(name)stringRemove invalid chars, limit 200

Constants

ConstantValueDescription
MAX_EMBEDDED_FILE_SIZE50 MBMaximum embedded file size

Export Utilities src/utils/exportUtils.ts

Canvas and SVG export for diagrams.

Types

typescript
interface ExportOptions {
  format: 'png' | 'svg';
  scope: 'all' | 'selection';
  scale: number;              // 1, 2, 3 for PNG
  background: string | null;  // hex or null for transparent
  padding: number;            // pixels
  filename: string;
  flattenGroups?: boolean;
  includeWhiteboard?: boolean;
}

Functions

FunctionReturnsDescription
exportToPng(data, options)Promise<Blob>Render to PNG blob
exportToSvg(data, options)stringGenerate SVG XML string
getExportBounds(data, scope)Box | nullCalculate export bounds

TIP

Group handling: If a group is explicitly selected, the entire group exports. If only some children are selected, only those children export without the group container.


Design Conventions

Key patterns used across all utility modules:

  • ImmutabilityVec2, Mat3, and Box all return new instances from every operation. Never mutate in place.
  • Tolerance — Float comparisons use epsilon = 1e-10 by default. Pass a custom epsilon when comparing values at different scales.
  • Angles — All angles are in radians, counter-clockwise positive. Use degToRad() / radToDeg() for conversion.
  • Matrix multiplicationa.multiply(b) applies b first, then a. This follows standard linear algebra convention.
  • Performance — Use lengthSquared() / distanceSquared() to avoid sqrt when you only need relative comparisons (e.g., "is A closer than B?").

Released under the AGPL-3.0 License.