/** * CRC - Canvas Render Components (alpha) * * MIT License * * Copyright 2020 Ben Lesh * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ export interface CompEl

{ type: CompFn

; props: P; } type FalsyNodes = undefined | false | null | '' | 0; export type CRCNode = CompEl | void | FalsyNodes; export type Canvas = HTMLCanvasElement | OffscreenCanvas; export type RenderingContext2D = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D; export type CompFn

= (props: P, ctx: RenderingContext2D) => CRCNode[] | CRCNode | void; export type CRCMouseEventListener = (e: CRCMouseEvent) => void; interface CRCEventRegistry { click: Set<(e: MouseEvent) => void>; dblclick: Set<(e: MouseEvent) => void>; mousemove: Set<(e: MouseEvent) => void>; mouseover: Set<(e: MouseEvent) => void>; mouseout: Set<(e: MouseEvent) => void>; mousedown: Set<(e: MouseEvent) => void>; mouseup: Set<(e: MouseEvent) => void>; contextmenu: Set<(e: MouseEvent) => void>; } export type PixelGridAlignment = 'none' | 'round' | 'ceil' | 'floor'; /** * Useful for testing and HMR. * DO NOT USE IN PROD */ export declare function clearSharedState(): void; /** * Mounts or updates a canvas render component on a given HTMLCanvasElement * @param canvas The canvas to render on * @param element The CRC element to render */ export declare function crc

(canvas: HTMLCanvasElement, element: CompEl

, config?: { signal?: AbortSignal; }): void; /** * Creates a simple structure representing a component to be rendered. * DOES NOT RENDER. * @param comp The render function for a component * @param props The props to pass to that render function on render * @returns A structure that represents a component to be mounted or updated during render */ export declare function createElement

(comp: CompFn

, props: P): CompEl

; /** * Used to convert a component render function to a function that will return a component element. * This is useful for now because setting up JSX is still annoying. * @param compFn A component to create a simplfied function for */ export declare function defineComp

(compFn: CompFn

): (props: P) => CompEl

; export interface ClipProps { path: Path2D; fillRule?: CanvasFillRule; children: CRCNode[]; } export declare function Clip(props: ClipProps, ctx: RenderingContext2D): CRCNode[]; export declare const clip: (props: ClipProps) => CompEl; interface CRCRef { current: T | undefined; } /** * Hook: Creates a reference object, similar to React's useRef. * @param init The initial reference value * @returns A reference with a `current` property containing the value */ export declare function crcRef(init?: T): CRCRef; export type StateUpdater = (update: T | ((oldValue: T) => T)) => void; /** * Hook: creates a tuple of state and a state setter. Setting the state with the * state setter will cause the entire canvas CRC instance to be scheduled for * rerender. If you set the state multiple times before the next animation frame, * it will only rerender with whatever the most recent state is as of that animation frame. * @param init The initial state * @returns A tuple with the state, and a setter function */ export declare function crcState(init?: T): readonly [T, StateUpdater]; /** * Hook: creates a memoized value, similar to React's `useMemo`. * @param create The factory to create the memoized value. * @param deps The deps to check to see if the memoized value needs to be updated. * @returns The memoized value */ export declare function crcMemo(create: () => T, deps: any[]): T; /** * Does a shallow diff check on the deps. If they've changed, it will synchronously * call the provided call back. This is not like useEffect, but it's useful when * a developer wants to diff a value. Also allows for a teardown to be returned that * is called when deps change (very, very similar to useEffect, just ALWAYS synchronous). * If you have work in here that only sets state, you should be using {@link crcMemo} * instead. * @param callback The SYNCHRONOUS callback when the deps have changed * @param deps The deps to check for changes. */ export declare function crcWhenChanged(callback: () => (() => void) | void, deps?: any[]): void; export interface CRCMouseEvent { x: number; y: number; originalEvent: MouseEvent; } /** * Hook: For wiring up changes to the CSS cursor style while over a corresponding path. * NOTE: If the path reference changes between, the click event will be * torn down and re-registered. Be sure use the same instance of a Path if * it doesn't change. {@link crcMemo} may be useful for this. */ export declare function crcCursor({ path, style, fill, lineInteractionWidth, }: { path?: Path2D; style?: string; fill?: boolean; lineInteractionWidth?: number; }): void; /** * Creates a memoized Path2D for a rectangle. Useful when * defining events efficiently. * @returns A memoized Path2D */ export declare function crcRectPath(x: number, y: number, width: number, height: number, config?: { alignToPixelGrid?: PixelGridAlignment; lineWidth?: number; }): Path2D; /** * Creates a memoized Path2D for a set of line coordinates. * @returns A memoized Path2D */ export declare function crcLinePath(coords: [number, number][], config?: { closePath?: boolean; }): Path2D; /** * Creates a memoized Path2D for an SVG data string. * @returns A memoized Path2D */ export declare function crcSvgPath(svgPathData: string): Path2D; export interface CRCBasicMouseEvents { onClick?: (e: CRCMouseEvent) => void; onDblClick?: (e: CRCMouseEvent) => void; onMouseMove?: (e: CRCMouseEvent) => void; onMouseOver?: (e: CRCMouseEvent) => void; onMouseOut?: (e: CRCMouseEvent) => void; onContextMenu?: (e: CRCMouseEvent) => void; onMouseDown?: (e: CRCMouseEvent) => void; onMouseUp?: (e: CRCMouseEvent) => void; } export type FillStyle = CanvasRenderingContext2D['fillStyle']; export type StrokeStyle = CanvasRenderingContext2D['strokeStyle']; interface IntrinsicProps { key?: string; } export interface AlphaProps { alpha?: number; } export interface StrokeStyleProps { strokeStyle?: StrokeStyle; lineWidth?: number; } export interface FillStyleProps { fillStyle?: FillStyle; } export interface CursorStyleProps { cursor?: string; } export interface PathProps extends IntrinsicProps, CRCBasicMouseEvents, FillStyleProps, StrokeStyleProps, CursorStyleProps, AlphaProps { path: Path2D; lineInteractionWidth?: number; } /** * Creates a renderable Path component element. */ export declare const path: (props: PathProps) => CompEl; export interface RectProps extends IntrinsicProps, CRCBasicMouseEvents, FillStyleProps, StrokeStyleProps, AlphaProps, CursorStyleProps { x: number; y: number; width: number; height: number; alignToPixelGrid?: PixelGridAlignment; } export declare function crcEvent(type: K, handler?: CRCMouseEventListener, path?: Path2D, fill?: boolean, lineInteractionWidth?: number): void; /** * Creates a renderable Rect component element. */ export declare const rect: (props: RectProps) => CompEl; export interface LineProps extends IntrinsicProps, CRCBasicMouseEvents, CursorStyleProps, StrokeStyleProps { coords: [number, number][]; lineInteractionWidth?: number; } export declare function Line(props: LineProps, ctx: RenderingContext2D): void; /** * Creates a renderable Line component element. */ export declare const line: (props: LineProps) => CompEl; export interface VerticalLineProps extends IntrinsicProps, CRCBasicMouseEvents, CursorStyleProps, StrokeStyleProps { x: number; top?: number; bottom?: number; alignToPixelGrid?: PixelGridAlignment; lineInteractionWidth?: number; } export declare function VerticalLine(props: VerticalLineProps, ctx: RenderingContext2D): void; /** * Creates a renderable VerticalLine component element. */ export declare const verticalLine: (props: VerticalLineProps) => CompEl; export interface HorizontalLineProps extends IntrinsicProps, CRCBasicMouseEvents, CursorStyleProps, StrokeStyleProps { y: number; left?: number; right?: number; alignToPixelGrid?: PixelGridAlignment; lineInteractionWidth?: number; } export declare function HorizontalLine(props: HorizontalLineProps, ctx: RenderingContext2D): void; /** * Creates a renderable HorizontalLine component element */ export declare const horizontalLine: (props: HorizontalLineProps) => CompEl; export interface ImgProps extends IntrinsicProps, CRCBasicMouseEvents, AlphaProps, CursorStyleProps, StrokeStyleProps { src: string; x: number; y: number; width?: number; height?: number; alignToPixelGrid?: PixelGridAlignment; } /** * Creates a renderable Img component element. */ export declare const img: (props: ImgProps) => CompEl; export interface SvgPathProps extends IntrinsicProps, CRCBasicMouseEvents, FillStyleProps, StrokeStyleProps, AlphaProps, CursorStyleProps { d: string; } /** * Creates a renderable SvgPath component element. */ export declare const svgPath: (props: SvgPathProps) => CompEl; export interface GProps extends IntrinsicProps { children: CRCNode[]; scaleX?: number; scaleY?: number; rotate?: number; rotateOrigin?: [number, number]; x?: number; y?: number; skewX?: number; skewY?: number; clipFillRule?: CanvasFillRule; } export interface TextProps extends IntrinsicProps, CRCBasicMouseEvents, FillStyleProps, StrokeStyleProps, AlphaProps, CursorStyleProps { text: string; x: number; y: number; maxWidth?: number; maxHeight?: number; lineHeight?: number; overflow?: 'visible' | 'squish' | 'ellipsis' | 'clip'; wordWrap?: boolean; font?: string; textBaseline?: CanvasTextBaseline; textAlign?: CanvasTextAlign; } export declare function Text(props: TextProps, ctx: RenderingContext2D): void; export declare const text: (props: TextProps) => CompEl; /** * Creates a group element that can be used to define transformations on a set * of related CRC elements. */ export declare const g: (props: GProps) => CompEl; export interface LayerProps extends IntrinsicProps { render: CompEl; width?: number; height?: number; } export declare function Layer(props: LayerProps, ctx: RenderingContext2D): void; export declare const layer: (props: LayerProps) => CompEl; export {};