UNPKG

@g20/core

Version:

Geometric Algebra 2D Graphics Library

1,392 lines (1,352 loc) 44.3 kB
import { BehaviorSubject } from 'rxjs'; interface Bivector { b: number; } interface Scalar { /** * The scalar coordinate as a number. */ a: number; } interface Spinor extends Scalar, Bivector { } interface Vector { x: number; y: number; } type VectorLike = G20 | [x: number, y: number]; type SpinorLike = G20 | [a: number, b: number]; declare function vector_from_like(like: VectorLike): G20 | null; declare function spinor_from_like(like: SpinorLike): G20 | null; /** * A multivector for two dimensions with a Euclidean metric. */ declare class G20 { #private; readonly change$: Observable<this>; constructor(x?: number, y?: number, a?: number, b?: number); static scalar(a: number): G20; static bivector(b: number): G20; static spinor(a: number, b: number): G20; static vector(x: number, y: number): G20; /** * Determines whether this multivector is locked. * If the multivector is in the unlocked state then it is mutable. * If the multivector is in the locked state then it is immutable. */ isLocked(): boolean; isMutable(): boolean; /** * Locks this multivector (preventing any further mutation), * and returns a token that may be used to unlock it. */ lock(): number; /** * Unlocks this multivector (allowing mutation), * using a token that was obtained from a preceding lock method call. */ unlock(token: number): this; get a(): number; set a(a: number); get x(): number; set x(x: number); get y(): number; set y(y: number); get b(): number; set b(b: number); static readonly one: G20; static readonly zero: G20; static readonly ex: G20; static readonly ey: G20; static readonly I: G20; static add(v1: Readonly<G20>, v2: Readonly<G20>): G20; static copy(mv: Readonly<G20>): G20; static fromBivector(B: Readonly<Bivector>): G20; static fromScalar(alpha: Readonly<Scalar>): G20; static fromSpinor(R: Readonly<Spinor>): G20; static fromVector(v: Readonly<Vector>): G20; static rotorFromDirections(a: Vector, b: Vector): G20; static rotorFromVectorToVector(a: Vector, b: Vector): G20; static sub(v1: G20, v2: G20): G20; static subtract(v1: G20, v2: G20): G20; static ratioBetween(v1: Readonly<G20>, v2: Readonly<G20>): number; static angleBetween(v1: Readonly<Vector>, v2: Readonly<Vector>): number; static distanceBetween(v1: Readonly<Vector>, v2: Readonly<Vector>): number; static distanceBetweenSquared(v1: Readonly<Vector>, v2: Readonly<Vector>): number; /** * */ add2(a: Readonly<G20>, b: Readonly<G20>): G20; addPseudo(β: number): G20; /** * Adds a multiple of a scalar to this multivector. * @param a The scalar value to be added to this multivector. * @param α The fraction of (a * uom) to be added. Default is 1. * @returns this + (a * uom) * α */ addScalar(a: number, α?: number): G20; conj(): G20; /** * A convenience function for set(mv.x, mv.y, mv.a, mv.b). * Requires `this` multivector to be mutable. */ copy(mv: Readonly<G20>): this; /** * A convenience function for set(0, 0, spinor.a, spinor.b). * Requires `this` multivector to be mutable. */ copySpinor(spinor: Readonly<Spinor>): this; /** * A convenience function for set(vector.x, vector.y, 0, 0). * Requires `this` multivector to be mutable. */ copyVector(vector: Readonly<Vector>): this; /** * A convenience function for set(0, 0, 0, 0). * Requires `this` multivector to be mutable. */ clear(): this; clone(): G20; /** * @param rhs The multivector dividend. * @returns this / m; */ div(rhs: G20): G20; /** * @param m * @returns this ^ m */ ext(m: G20): G20; /** * Computes the right inverse of this multivector. * inv(X) satisfies X * inv(X) = 1. * @returns inverse(this) */ inv(): G20; lco(rhs: G20): G20; add(rhs: G20): G20; sub(rhs: G20): G20; /** * @param rhs * @returns this * m */ mul(rhs: G20): G20; neg(): G20; dot(v: G20): number; exp(): G20; magnitude(): number; quaditude(): number; normalize(): G20; distanceTo(v: G20): number; distanceToSquared(v: G20): number; rco(m: G20): G20; /** * If `this` is mutable, then sets `this` multivector to its reflection in the plane orthogonal to vector n. The result is mutable. * If `this` is immutable (locked), a copy of `this` is made, which is then reflected. The result is immutable (locked). * * i.e. The result is mutable (unlocked) iff `this` is mutable (unlocked). * * Mathematically, * * this ⟼ - n * this * n * * Geometrically, * * Reflects this multivector in the plane orthogonal to the unit vector, n. * This implementation does assume that n is a vector, but does not assume that it is normalized to unity. * * If n is not a unit vector then the result is scaled by n squared. * The scalar component gets an extra minus sign. The pseudoscalar component does not change sign. * The units of measure are carried through but in most cases n SHOULD be dimensionless. * * @param n The unit vector that defines the reflection plane. */ reflect(n: Readonly<Vector>): G20; /** * <p> * Computes a rotor, R, from two unit vectors, where * R = (|b||a| + b * a) / sqrt(2 * |b||a|(|b||a| + b << a)) * </p> * * The result is independent of the magnitudes of a and b. * * @param a The starting vector * @param b The ending vector * @returns The rotor representing a rotation from a to b. */ rotorFromDirections(a: Readonly<Vector>, b: Readonly<Vector>): G20; /** * Sets this multivector to a rotor that rotates through angle θ in the oriented plane defined by I. * * @param θ The rotation angle in radians when the rotor is applied on both sides as R * M * ~R */ rotorFromAngle(θ: number): G20; /** * R = sqrt(|b|/|a|) * (|b||a| + b * a) / sqrt(2 * |b||a|(|b||a| + b << a)) * * The result is depends on the magnitudes of a and b. */ rotorFromVectorToVector(a: Readonly<Vector>, b: Readonly<Vector>): G20; scale(α: number): G20; /** * @param m * @returns this | m */ scp(m: G20): G20; /** * Sets the coordinates of `this` multivector. * Requires `this` multivector to be mutable. * @param x The coordinate along the x-axis. * @param y The coordinate along the y-axis. * @param a The scalar coordinate. * @param b The bivector coordinate. */ set(x: number, y: number, a?: number, b?: number): this; equals(v: G20, eps?: number): boolean; lerp(v: G20, t: number): G20; /** * Determines whether this multivector is exactly 0 (zero). */ isZero(eps?: number): boolean; toString(): string; /** * reverse has a ++-- structure on the grades. * The scalar component, a, will not change. * The vector components, x and y, will not change. * The bivector component, b, will change sign. */ rev(): G20; rotate(radians: number): G20; /** * Subtracts a multiple of a scalar from this multivector. * @param a The scalar value to be subtracted from this multivector. * @param α The fraction of (a * uom) to be subtracted. Default is 1. * @returns this - (a * uom) * α */ subScalar(a: number, α?: number): G20; /** * <p> * <code>this ⟼ a * b</code> * </p> * Sets this Geometric2 to the geometric product a * b of the vector arguments. */ versor(a: Vector, b: Vector): G20; /** * */ __div__(rhs: G20 | number): G20; /** * */ __rdiv__(lhs: number | G20): G20; /** * */ __vbar__(rhs: number | G20): G20; /** * */ __rvbar__(lhs: number | G20): G20; /** * */ __wedge__(rhs: number | G20): G20; /** * */ __rwedge__(lhs: number | G20): G20; /** * */ __lshift__(rhs: number | G20): G20; /** * */ __rlshift__(lhs: number | G20): G20; /** * */ __rshift__(rhs: number | G20): G20; /** * */ __rrshift__(lhs: number | G20): G20; /** * */ __bang__(): G20; /** * */ __eq__(rhs: G20 | number): boolean; /** * */ __ne__(rhs: G20 | number): boolean; /** * */ __tilde__(): G20; /** * */ __add__(rhs: G20 | number): G20; /** * */ __radd__(lhs: G20 | number): G20; /** * */ __sub__(rhs: G20 | number): G20; /** * */ __rsub__(lhs: G20 | number): G20; /** * */ __pos__(): G20; /** * */ __neg__(): G20; /** * */ __mul__(rhs: G20 | number): G20; /** * */ __rmul__(lhs: G20 | number): G20; } /** * An object should be Disposable if its lifetime is bounded by the holder. * Such objects are normally created by the holding object. */ interface Disposable { dispose(): void; } /** * Calls `dispose()` on each element of `disposables`, traversing the array in reverse order. * When all dispose() calls have been made, the length of the disposables is set to zero. */ declare function dispose<T extends Disposable>(disposables: T[]): void; interface Observable<T> { subscribe(callback: (value: T) => void): Disposable; } declare class Anchor { #private; /** * default is zero. */ readonly origin: G20; readonly controls: { a: G20; b: G20; }; readonly change$: Observable<this>; /** * @param origin * @param ax The x position of the left handle point. * @param ay The y position of the left handle point. * @param bx The x position of the right handle point. * @param by The y position of the right handle point. * @param command The command to describe how to render. Applicable commands are {@link Commands} */ constructor(origin: G20 | [x: number, y: number], command?: "M" | "L" | "C" | "A" | "Z", ax?: number, ay?: number, bx?: number, by?: number); dispose(): void; get x(): number; set x(x: number); get y(): number; set y(y: number); get t(): number; set t(t: number); copy(v: Anchor): this; /** * Invoked when the path is automatic (not manual). */ ignore(): void; /** * Invoked when the path is manual (not automatic). */ listen(): void; /** * default is 'M'. */ get command(): "M" | "L" | "C" | "A" | "Z"; set command(command: "M" | "L" | "C" | "A" | "Z"); /** * default is true. */ get relative(): boolean; set relative(relative: boolean); /** * default is zero. */ get rx(): number; set rx(rx: number); /** * default is zero. */ get ry(): number; set ry(ry: number); /** * default is zero. */ get xAxisRotation(): number; set xAxisRotation(xAxisRotation: number); /** * default is zero. */ get largeArcFlag(): number; set largeArcFlag(largeArcFlag: number); /** * default is one. */ get sweepFlag(): number; set sweepFlag(sweepFlag: number); } /** * A Handle-Body pattern for interacting with a DOM. */ interface ViewDOM<T> { /** * A runtime typesafe assertion that the element has the type required. */ downcast(element: unknown): T; createSVGElement(name: string, attributes: { [name: string]: string; }): T; setAttribute(element: T, name: string, value: string): void; setAttributes(element: T, attributes: { [name: string]: string; }): void; removeAttribute(element: T, name: string): void; removeAttributes(element: T, attributes: { [name: string]: string; }): void; appendChild(parent: T, child: T): void; removeChild(parent: T, child: T): void; setTextContent(element: T, content: string): void; getParentNode(element: T): T | null; getLastChild(element: T): T | null; getElementDefs(svg: T): T; setStyle(element: T, name: "display" | "overflow" | "top", value: string): void; } /** * Abstraction of a Gradient or Texture. */ interface ColorProvider { /** * Indicates to the ColorProvider that it is being used in one more fill or stroke property. * The ColorProvider is expected to add itself to the SVG defs element when being used. */ incrementUse<T>(viewDOM: ViewDOM<T>, defs: T): void; /** * Indicates to the ColorProvider that it is being used in one less fill or stroke property. * The ColorProvider is expected to remove itself from the SVG defs element when no longer used. */ decrementUse<T>(viewDOM: ViewDOM<T>, defs: T): void; /** * Provide the value that will be used in the `fill` or `stroke` attribute of the consuming element. * Usually url(#${this.id}) for gradients and textures but may be e.g. an rgb() or #RRGGBB value. */ serialize(): string; } type Color = string | ColorProvider; declare function is_color_provider(x: Color): x is ColorProvider; declare function is_color(x: unknown): x is Color; /** * TODO: If this was iterable then there would be less need for the length and getAt. */ declare class Collection<T> { #private; readonly insert$: Observable<T[]>; readonly remove$: Observable<T[]>; readonly order$: Observable<void>; constructor(items: T[]); forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: unknown): void; get length(): number; getAt(index: number): T; get(): T[]; ping(): void; pop(): T; shift(): T; push(...items: T[]): number; unshift(...items: T[]): number; splice(start: number, deleteCount?: number, ...more: T[]): T[]; sort(compareFn: (a: T, b: T) => number): this; reverse(): this; indexOf(searchElement: T, fromIndex?: number): number; map<X>(callbackfn: (value: T, index: number, array: T[]) => X, thisArg?: any): X[]; } type Equals<T> = (a: T, b: T) => boolean; interface Readable<T> { get(): T; } interface Writable<T> { set(newValue: T): void; } interface State<T> extends Readable<T>, Writable<T> { } interface VariableOptions<T> { equals?: Equals<T>; } declare class Variable<T> implements State<T> { #private; constructor(bs: BehaviorSubject<T>, options?: VariableOptions<T>); get(): T; set(newValue: T): void; asObservable(): Observable<T>; } declare function variable<T>(initialValue: T, options?: VariableOptions<T>): Variable<T>; /** * Information that is shared between the model and the view. */ declare class ZZZ implements Disposable { #private; /** * */ readonly disposables: Disposable[]; readonly flags: { [flag: number]: boolean; }; appended?: boolean; readonly ismask$: Observable<boolean>; /** * SVGClipPathElement, TODO: Rename clipPath. */ svgClipPathElement?: unknown; context?: { ctx?: CanvasRenderingContext2D; }; /** * Used by the CanvasRenderer. */ effect?: CanvasPattern; /** * The visual element corresponding to some Shape. */ viewee?: unknown; /** * A flag that reminds us that the fill (ColorProvider) has been rendered into the SVGDefsElement. */ hasFillEffect?: boolean; /** * A flag that reminds us that the stroke (ColorProvider) has been rendered into the SVGDefsElement. */ hasStrokeEffect?: boolean; /** * SVGImageElement as a handle. */ image?: unknown; offset?: G20; readonly vertices: Anchor[]; readonly vertices_subject?: Variable<number>; readonly vertices$?: Observable<number>; dispose(): void; get ismask(): boolean; set ismask(ismask: boolean); } /** * The foundational object for the scenegraph. */ declare abstract class ElementBase implements Disposable { #private; parent: unknown; readonly zzz: ZZZ; constructor(id: string | null); dispose(): void; get id(): string | null; set id(id: string | null); } /** * 1st row is [a11,a12,a13], 2nd row is [a21,a22,a23], 3rd row is [a31,a32,a33] */ declare class Matrix { #private; constructor(a11?: number, a12?: number, a13?: number, a21?: number, a22?: number, a23?: number, a31?: number, a32?: number, a33?: number); get a(): number; get b(): number; get c(): number; get d(): number; get e(): number; get f(): number; get a11(): number; get a12(): number; get a13(): number; get a21(): number; get a22(): number; get a23(): number; get a31(): number; get a32(): number; get a33(): number; toString(): string; set(a11: number, a12: number, a13: number, a21: number, a22: number, a23: number, a31: number, a32: number, a33: number): this; /** * Copy the matrix of one to the current instance. */ copy(m: Matrix): this; /** * Sets matrix to the identity, like resetting. */ identity(): this; isNaN(): boolean; isOne(): boolean; multiply(b11: number, b12: number, b13: number, b21: number, b22: number, b23: number, b31: number, b32: number, b33: number): this; multiply_vector(x?: number, y?: number, z?: number): [number, number, number]; multiply_by_scalar(s: number): this; scale(sx: number, sy: number): this; /** * @param angle The rotation angle in radians. * @returns */ rotate(angle: number): this; translate(translation: { x: number; y: number; }): this; /** * Skew the matrix by an angle in the x axis direction. * * @param skewX The skew angle in radians. */ skewX(skewX: number): this; /** * Skew the matrix by an angle in the y axis direction. * * @param skewY The skew angle in radians. */ skewY(skewY: number): this; } /** * A more specific representation of the attributes that are permitted on SVG elements. * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute * The value of all attributes MUST be string. */ interface SVGAttributes { [name: string]: string; class?: string; "clip-rule"?: "nonzero" | "evenodd" | "inherit"; cx?: string; cy?: string; /** * Defines the path to be drawn as a list of path commands and their parameters. */ d?: string; direction?: "ltr" | "rtl"; /** * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dominant-baseline */ "dominant-baseline"?: "auto" | "text-bottom" | "alphabetic" | "ideographic" | "middle" | "central" | "mathematical" | "hanging" | "text-top"; dx?: string; dy?: string; fill?: string; "fill-opacity"?: string; "font-family"?: string; "font-size"?: string; "font-style"?: "normal" | "italic" | "oblique"; "font-weight"?: "normal" | "bold" | "bolder" | "lighter" | string; fx?: string; fy?: string; gradientUnits?: "userSpaceOnUse" | "objectBoundingBox"; height?: string; href?: string; id?: string; "line-height"?: string; /** * TODO: offset is not a documented SVG attribute. How do we account for it? */ offset?: string; opacity?: string; "text-anchor"?: "start" | "middle" | "end"; r?: string; spreadMethod?: "pad" | "reflect" | "repeat"; "stop-color"?: string; "stop-opacity"?: string; stroke?: string; "stroke-dasharray"?: string; "stroke-dashoffset"?: string; "stroke-linecap"?: "butt" | "round" | "square"; "stroke-linejoin"?: "arcs" | "bevel" | "miter" | "miter-clip" | "round"; "stroke-miterlimit"?: string; "stroke-opacity"?: string; "stroke-width"?: string; "text-decoration"?: string; /** * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform */ transform?: string; "vector-effect"?: "none" | "non-scaling-stroke" | "non-scaling-size" | "non-rotation" | "fixed-position"; visibility?: "visible" | "hidden" | "collapse"; width?: string; x?: string; x1?: string; x2?: string; y?: string; y1?: string; y2?: string; } /** * */ interface Shape extends Disposable { id: string | null; parent: unknown; get matrix(): Matrix; get X(): G20; set X(X: G20 | [x: number, y: number] | { x: number; y: number; }); get R(): G20; set R(R: G20); sx: number; sy: number; skewX: number; skewY: number; opacity: number; visibility: "visible" | "hidden" | "collapse"; collapse(): this; getBoundingBox(shallow?: boolean): { top?: number; left?: number; right?: number; bottom?: number; }; hasBoundingBox(): boolean; hide(): this; render<T>(viewDOM: ViewDOM<T>, parentElement: T, svgElement: T): void; viewee(): unknown; show(): this; } interface Parent { update?(): void; } interface ShapeOptions { id?: string; opacity?: number; position?: VectorLike; attitude?: SpinorLike; visibility?: "visible" | "hidden" | "collapse"; plumb?: boolean; sx?: number; sy?: number; } declare abstract class ShapeBase extends ElementBase implements Shape { #private; readonly board: Board; abstract getBoundingBox(shallow?: boolean): { top?: number; left?: number; right?: number; bottom?: number; }; abstract hasBoundingBox(): boolean; constructor(board: Board, options?: ShapeOptions); dispose(): void; render<T>(viewDOM: ViewDOM<T>, parentElement: T, svgElement: T): void; update(): this; viewee(): unknown; get X(): G20; set X(X: G20 | [x: number, y: number] | { x: number; y: number; }); get plumb(): boolean; set plumb(plumb: boolean); get R(): G20; set R(R: G20); get scale(): number; set scale(scale: number | [sx: number, sy: number]); get sx(): number; set sx(sx: number); get sy(): number; set sy(sy: number); get skewX(): number; set skewX(skewX: number); get skewY(): number; set skewY(skewY: number); get mask(): Shape | null; set mask(mask: Shape | null); get matrix(): Matrix; get opacity(): number; set opacity(opacity: number); get visibility(): "visible" | "hidden" | "collapse"; set visibility(visible: "visible" | "hidden" | "collapse"); show(): this; hide(): this; collapse(): this; get worldMatrix(): Matrix; set worldMatrix(worldMatrix: Matrix); } interface ColoredShapeOptions extends ShapeOptions { position?: VectorLike; attitude?: SpinorLike; id?: string; dashes?: number[]; fillColor?: Color; fillOpacity?: number; strokeColor?: Color; strokeOpacity?: number; strokeWidth?: number; sx?: number; sy?: number; vectorEffect?: null | "non-scaling-stroke" | "none"; visibility?: "visible" | "hidden" | "collapse"; } declare abstract class ColoredShapeBase extends ShapeBase { #private; constructor(board: Board, options?: ColoredShapeOptions); /** * Array of numbers. Odd indices represent dash length. Even indices represent dash space. * A list of numbers that represent the repeated dash length and dash space applied to the stroke of the text. * @see {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray} for more information on the SVG stroke-dasharray attribute. */ get dashes(): number[]; set dashes(dashes: number[]); get fillColor(): Color; set fillColor(fill: Color); get fillOpacity(): number; set fillOpacity(fillOpacity: number); get strokeColor(): Color; set strokeColor(stroke: Color); get strokeOpacity(): number; set strokeOpacity(strokeOpacity: number); get strokeWidth(): number; set strokeWidth(strokeWidth: number); get vectorEffect(): null | "non-scaling-stroke" | "non-scaling-size" | "non-rotation" | "fixed-position" | "none"; set vectorEffect(vectorEffect: null | "non-scaling-stroke" | "non-scaling-size" | "non-rotation" | "fixed-position" | "none"); /** * A convenience method for setting the `fill` attribute to "none". */ noFill(): this; /** * A convenience method for setting the `stroke` attribute to "none". */ noStroke(): this; render<T>(viewDOM: ViewDOM<T>, parentElement: unknown, svgElement: unknown): void; } interface PathOptions extends ColoredShapeOptions { id?: string; dashes?: number[]; opacity?: number; position?: VectorLike; attitude?: SpinorLike; vectorEffect?: null | "non-scaling-stroke" | "none"; visibility?: "visible" | "hidden" | "collapse"; /** * The value of what the path should be filled in with. * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/color_value} for more information on CSS's colors as `String`. */ fillColor?: Color; fillOpacity?: number; /** * The value of what the path should be outlined in with. * @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/color_value} for more information on CSS's colors as `String`. */ strokeColor?: Color; strokeOpacity?: number; strokeWidth?: number; } declare class Path extends ColoredShapeBase { #private; /** * @param vertices A list of {@link Anchor}s that represent the order and coordinates to construct the rendered shape. * @param closed Describes whether the path is closed or open. * @param curved Describes whether the path automatically calculates bezier handles for each vertex. * @param manual Describes whether the developer controls how vertices are plotted. */ constructor(owner: Board, vertices?: Anchor[], closed?: boolean, curved?: boolean, manual?: boolean, options?: PathOptions); render<T>(viewDOM: ViewDOM<T>, parentElement: T, svgElement: T): void; center(): this; corner(): this; getBoundingBox(shallow?: boolean): { top?: number; left?: number; right?: number; bottom?: number; }; hasBoundingBox(): boolean; /** * TODO: Bad name. This function is called for its side effects which are to modify the Anchor. * Originally the function appears to promote a Vector and return an Anchor, but this is not used * and the call always involves an Anchor. * There is a return value but it is not being used. * @param t Percentage value describing where on the {@link Path} to estimate and assign coordinate values. * @param anchor - Object to apply calculated x, y to. If none available returns new `Object`. * @description Given a float `t` from 0 to 1, return a point or assign a passed `obj`'s coordinates to that percentage on this {@link Path}'s curve. */ getPointAt(t: number, anchor: Anchor): Anchor; /** * Based on closed / curved and sorting of vertices, plot where all points should be and where the respective handles should be too. */ plot(): this; /** * Insert an anchor at the midpoint between every vertex. * @param limit - How many times to recurse subdivisions. */ subdivide(limit: number): this; update(): this; flagReset(dirtyFlag?: boolean): this; get automatic(): boolean; set automatic(automatic: boolean); get beginning(): number; set beginning(beginning: number); /** * Defines the shape to be used at the end of open subpaths when they are stroked. * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap */ get cap(): "butt" | "round" | "square"; set cap(cap: "butt" | "round" | "square"); get closed(): boolean; set closed(closed: boolean); get curved(): boolean; set curved(curved: boolean); get ending(): number; set ending(ending: number); get join(): "arcs" | "bevel" | "miter" | "miter-clip" | "round"; set join(join: "arcs" | "bevel" | "miter" | "miter-clip" | "round"); get length(): number; get lengths(): number[]; get miterLimit(): number; set miterLimit(miterlimit: number); get vertices(): Collection<Anchor>; set vertices(vertices: Collection<Anchor>); } interface ArcSegmentOptions extends PathOptions { innerRadius?: number; outerRadius?: number; startAngle?: number; endAngle?: number; resolution?: number; id?: string; fillColor?: Color; fillOpacity?: number; strokeColor?: Color; strokeOpacity?: number; strokeWidth?: number; } declare class ArcSegment extends Path { #private; constructor(owner: Board, options?: ArcSegmentOptions); dispose(): void; update(): this; get startAngle(): number; set startAngle(startAngle: number); get endAngle(): number; set endAngle(endAngle: number); get innerRadius(): number; set innerRadius(innerRadius: number); get outerRadius(): number; set outerRadius(outerRadius: number); } interface ArrowOptions extends PathOptions { id?: string; headAngle?: number; headLength?: number; position?: VectorLike; attitude?: SpinorLike; strokeColor?: Color; strokeOpacity?: number; strokeWidth?: number; vectorEffect?: null | "non-scaling-stroke"; visibility?: "hidden" | "visible" | "collapse"; } declare class Arrow extends Path { #private; constructor(owner: Board, axis: VectorLike, options?: ArrowOptions); dispose(): void; update(): this; flagReset(dirtyFlag?: boolean): this; get axis(): G20; set axis(axis: VectorLike); get headAngle(): number; set headAngle(headAngle: number); get headLength(): number; set headLength(headLength: number); get origin(): G20; set origin(origin: VectorLike); } interface CircleOptions extends PathOptions { position?: VectorLike; attitude?: SpinorLike; radius?: number; fillColor?: Color; fillOpacity?: number; strokeColor?: Color; strokeOpacity?: number; strokeWidth?: number; resolution?: number; } declare class Circle extends Path { #private; constructor(owner: Board, options?: CircleOptions); dispose(): void; update(): this; get radius(): G20; set radius(radius: G20 | number); } interface EllipseOptions extends PathOptions { id?: string; fillColor?: Color; fillOpacity?: number; position?: VectorLike; attitude?: SpinorLike; rx?: number | VectorLike; ry?: number | VectorLike; strokeColor?: Color; strokeOpacity?: number; strokeWidth?: number; resolution?: number; visibility?: "visible" | "hidden" | "collapse"; } declare class Ellipse extends Path { #private; constructor(owner: Board, options?: EllipseOptions); dispose(): void; update(): this; get rx(): G20; set rx(rx: number | VectorLike); get ry(): G20; set ry(ry: number | VectorLike); } interface LineOptions extends PathOptions { id?: string; dashes?: number[]; strokeColor?: Color; strokeOpacity?: number; strokeWidth?: number; vectorEffect?: null | "non-scaling-stroke" | "none"; visibility?: "visible" | "hidden" | "collapse"; } declare class Line extends Path { constructor(owner: Board, point1: VectorLike, point2: VectorLike, options?: LineOptions); dispose(): void; get point1(): G20; set point1(point1: VectorLike); get point2(): G20; set point2(point2: VectorLike); } interface GroupOptions extends ShapeOptions { id?: string; } declare class Group extends ShapeBase { #private; constructor(owner: Board, shapes?: Shape[], options?: GroupOptions); dispose(): void; hasBoundingBox(): boolean; render<T>(viewDOM: ViewDOM<T>, parentElement: T, svgElement: T): void; /** * Orient the children of the group to the center of that group. */ center(): this; getById(id: string): Shape; getByType(type: any): Shape[]; add(...shapes: Shape[]): this; remove(...shapes: Shape[]): this; getBoundingBox(shallow?: boolean): { top: number; left: number; right: number; bottom: number; }; update(): this; flagReset(dirtyFlag?: boolean): this; /** * A list of all the children in the scenegraph. */ get children(): Shape[]; set children(children: Shape[]); } type TextDecoration = "none" | "underline" | "overline" | "line-through"; interface TextOptions extends Omit<ColoredShapeOptions, "strokeColor" | "strokeOpacity" | "strokeWidth"> { anchor?: "start" | "middle" | "end"; baseline?: "auto" | "text-bottom" | "alphabetic" | "ideographic" | "middle" | "central" | "mathematical" | "hanging" | "text-top"; decoration?: TextDecoration[]; direction?: "ltr" | "rtl"; dx?: number | string; dy?: number | string; fillColor?: Color; fillOpacity?: number; fontFamily?: string; fontStyle?: "normal" | "italic" | "oblique"; fontWeight?: "normal" | "bold" | "bolder" | "lighter" | number; id?: string; opacity?: number; position?: VectorLike; attitude?: SpinorLike; fontSize?: number; sx?: number; sy?: number; value?: string; visibility?: "visible" | "hidden" | "collapse"; } declare class Text extends ColoredShapeBase { #private; beginning: number; ending: number; length: number; constructor(owner: Board, content: string, options?: TextOptions); render<T>(viewDOM: ViewDOM<T>, parentElement: T, svgElement: T): void; static Measure(text: Text): { width: number; height: number; }; getBoundingBox(shallow?: boolean): { top: number; left: number; right: number; bottom: number; }; hasBoundingBox(): boolean; subdivide(limit: number): this; flagReset(dirtyFlag?: boolean): this; get anchor(): "start" | "middle" | "end"; set anchor(anchor: "start" | "middle" | "end"); get baseline(): "auto" | "text-bottom" | "alphabetic" | "ideographic" | "middle" | "central" | "mathematical" | "hanging" | "text-top"; set baseline(baseline: "auto" | "text-bottom" | "alphabetic" | "ideographic" | "middle" | "central" | "mathematical" | "hanging" | "text-top"); get content(): string; set content(value: string); get decoration(): TextDecoration[]; set decoration(v: TextDecoration[]); get direction(): "ltr" | "rtl"; set direction(direction: "ltr" | "rtl"); get dx(): number | string; set dx(dx: number | string); get dy(): number | string; set dy(dy: number | string); get fontFamily(): string; set fontFamily(family: string); get fontSize(): number; set fontSize(size: number); get fontStyle(): "normal" | "italic" | "oblique"; set fontStyle(fontStyle: "normal" | "italic" | "oblique"); get fontWeight(): number | "normal" | "bold" | "bolder" | "lighter"; set fontWeight(fontWeight: number | "normal" | "bold" | "bolder" | "lighter"); } interface RectangleOptions extends PathOptions { id?: string; opacity?: number; position?: VectorLike; attitude?: SpinorLike; width?: number | VectorLike; height?: number | VectorLike; visibility?: "visible" | "hidden" | "collapse"; fillColor?: Color; fillOpacity?: number; strokeColor?: Color; strokeOpacity?: number; strokeWidth?: number; } declare class Rectangle extends Path implements Disposable { #private; constructor(owner: Board, attributes?: RectangleOptions); dispose(): void; update(): this; flagReset(dirtyFlag?: boolean): this; get height(): G20; set height(height: number | VectorLike); get origin(): G20; set origin(origin: VectorLike); get width(): G20; set width(width: number | VectorLike); } interface PointOptions extends Pick<TextOptions, "anchor" | "baseline" | "dx" | "dy" | "fontFamily" | "fontSize"> { id?: string; hideIcon?: boolean; iconColor?: Color; iconKind?: "ellipse" | "rectangle"; iconOpacity?: number; text?: string; textColor?: Color; textOpacity?: number; strokeWidth?: number; visibility?: "visible" | "hidden" | "collapse"; } declare class Point extends Group { constructor(owner: Board, position: VectorLike, options?: PointOptions); get icon(): Ellipse | Rectangle; get text(): Text; } interface PolygonOptions extends PathOptions { id?: string; opacity?: number; fillColor?: Color; fillOpacity?: number; strokeColor?: Color; strokeOpacity?: number; strokeWidth?: number; } declare class Polygon extends Path { constructor(owner: Board, points?: VectorLike[], options?: PolygonOptions); } declare class Defaults { readonly board: Board; readonly arc: Pick<ArcSegmentOptions, "fillColor" | "fillOpacity" | "strokeColor" | "strokeOpacity" | "strokeWidth">; readonly arrow: Pick<ArrowOptions, "fillColor" | "fillOpacity" | "headAngle" | "headLength" | "strokeColor" | "strokeOpacity" | "strokeWidth">; readonly circle: Pick<CircleOptions, "fillColor" | "fillOpacity" | "strokeColor" | "strokeOpacity" | "strokeWidth">; readonly ellipse: Pick<EllipseOptions, "fillColor" | "fillOpacity" | "strokeColor" | "strokeOpacity" | "strokeWidth">; readonly line: Pick<LineOptions, "fillColor" | "fillOpacity" | "strokeColor" | "strokeOpacity" | "strokeWidth">; readonly point: Pick<PointOptions, "iconColor" | "iconOpacity" | "hideIcon" | "iconKind" | "textColor" | "textOpacity" | "strokeWidth">; readonly polygon: Pick<PolygonOptions, "fillColor" | "fillOpacity" | "strokeColor" | "strokeOpacity" | "strokeWidth">; readonly rectangle: Pick<RectangleOptions, "fillColor" | "fillOpacity" | "strokeColor" | "strokeOpacity" | "strokeWidth">; readonly text: Pick<TextOptions, "fillColor" | "fillOpacity" | "fontFamily" | "fontSize">; constructor(board: Board); reset(): void; } interface Board extends Disposable { arc(options?: ArcSegmentOptions): ArcSegment; arrow(axis: VectorLike, options?: ArrowOptions): Arrow; circle(options?: CircleOptions): Circle; curve(closed: boolean, points: (Anchor | G20 | [x: number, y: number])[], options?: PathOptions): Path; ellipse(options?: EllipseOptions): Ellipse; line(point1: VectorLike, point2: VectorLike, options?: LineOptions): Line; path(closed: boolean, points: (Anchor | G20 | [x: number, y: number])[], options?: PathOptions): Path; point(position: VectorLike, options?: PointOptions): Point; polygon(points: VectorLike[], options?: PolygonOptions): Polygon; rectangle(options?: RectangleOptions): Rectangle; text(message: string, options?: TextOptions): Text; add(...shapes: Shape[]): this; remove(...shapes: Shape[]): this; getBoundingBox(): { left: number; top: number; right: number; bottom: number; }; update(): void; get crazy(): boolean; get defaults(): Defaults; get goofy(): boolean; get frameCount(): number; get scene(): Group; width: number; height: number; get sx(): number; get sy(): number; } /** * A Handle-Body pattern for interacting with a DOM. */ interface ElementDOM<E, T> { getElementById(elementId: string): E; getAttribute(element: E, qname: string): string; getBoundingClientRect(element: E): { width: number; height: number; }; appendChild(parent: E, child: T): void; addEventListener(target: E, name: "resize", callback: () => void): void; removeEventListener(target: E, name: "resize", callback: () => void): void; isDocumentBody(element: E): boolean; } interface View<T> { /** * HTMLCanvasElement or SVGElement (or something else). */ domElement: T; height: number; width: number; render(): void; setSize(size: { width: number; height: number; }, ratio: number): void; } interface ViewFactory<T> { /** * * @param viewBox The topmost group that contains the scene group. * @param containerId The HTML id property of the element that contains the view. */ createView(viewBox: Group, containerId: string): View<T>; } interface GraphicsBoardOptions { boundingBox?: { left: number; top: number; right: number; bottom: number; }; } declare class GraphicsBoard<E, T> implements Board { #private; readonly defaults: Defaults; constructor(elementOrId: string | E, elementDOM: ElementDOM<E, T>, viewDOM: ViewDOM<T>, viewFactory: ViewFactory<T>, options?: GraphicsBoardOptions); dispose(): void; get goofy(): boolean; get crazy(): boolean; get frameCount(): number; get sx(): number; set sx(sx: number); get sy(): number; set sy(sy: number); get scene(): Group; get width(): number; set width(width: number); get height(): number; set height(height: number); get ratio(): number; set ratio(ratio: number); appendTo(container: E): this; getBoundingBox(): Readonly<{ left: number; top: number; right: number; bottom: number; }>; /** * A number representing how much time has elapsed since the last frame in milliseconds. */ getElapsedTime(fractionalDigits?: number): number | null; /** * Update positions and calculations in one pass before rendering. */ update(): void; add(...shapes: Shape[]): this; remove(...shapes: Shape[]): this; circle(options?: CircleOptions): Circle; ellipse(options?: EllipseOptions): Ellipse; line(point1: VectorLike, point2: VectorLike, options?: LineOptions): Line; point(position: VectorLike, options?: PointOptions): Point; polygon(points?: VectorLike[], options?: PolygonOptions): Polygon; rectangle(options?: RectangleOptions): Rectangle; text(message: string, options?: TextOptions): Text; arrow(axis: VectorLike, options?: ArrowOptions): Arrow; curve(closed: boolean, points: (Anchor | G20 | [x: number, y: number])[], options?: PathOptions): Path; path(closed: boolean, points: (Anchor | G20 | [x: number, y: number])[], options?: PathOptions): Path; arc(options?: ArcSegmentOptions): ArcSegment; group(...shapes: Shape[]): Group; } /** * */ declare class TreeView<T> implements View<T> { #private; /** * The topmost svg element. */ readonly domElement: T; readonly viewBox: Group; constructor(viewDOM: ViewDOM<T>, viewBox: Group, containerId: string); get width(): number; set width(width: number); get height(): number; set height(height: number); setSize(size: { width: number; height: number; }, ratio: number): this; render(): this; } declare const Commands: { readonly move: "M"; readonly line: "L"; readonly curve: "C"; readonly arc: "A"; readonly close: "Z"; }; export { Anchor, ArcSegment, type ArcSegmentOptions, Arrow, type ArrowOptions, type Bivector, type Board, Circle, type CircleOptions, Collection, type Color, type ColorProvider, Commands, Defaults, type Disposable, ElementBase, type ElementDOM, Ellipse, type EllipseOptions, G20, GraphicsBoard, type GraphicsBoardOptions, Group, type GroupOptions, Line, type LineOptions, Matrix, type Observable, type Parent, Path, type PathOptions, Point, type PointOptions, Polygon, type PolygonOptions, Rectangle, type RectangleOptions, type SVGAttributes, type Scalar, type Shape, ShapeBase, type ShapeOptions, type Spinor, type SpinorLike, type State, Text, type TextDecoration, type TextOptions, TreeView, Variable, type Vector, type VectorLike, type View, type ViewDOM, type ViewFactory, ZZZ, dispose, is_color, is_color_provider, spinor_from_like, variable, vector_from_like };