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:

  • Immutability — Vec2, 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 multiplication — a.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.