import * as monaco from "monaco-editor/esm/vs/editor/editor.api" import React from "react" /* -------------------------------------------------- */ /* Client State */ /* -------------------------------------------------- */ export interface Data { isReadOnly: boolean settings: { fontSize: number isDarkMode: boolean isCodeOpen: boolean isStyleOpen: boolean } currentStyle: ShapeStyles camera: { point: number[] zoom: number } brush?: Bounds boundsRotation: number selectedIds: Set pointedId?: string hoveredId?: string currentPageId: string currentCodeFileId: string codeControls: Record document: { pages: Record code: Record } } /* -------------------------------------------------- */ /* Document */ /* -------------------------------------------------- */ export interface Page { id: string type: "page" childIndex: number name: string shapes: Record } export enum ShapeType { Dot = "dot", Circle = "circle", Ellipse = "ellipse", Line = "line", Ray = "ray", Polyline = "polyline", Rectangle = "rectangle", } // Consider: // Glob = "glob", // Spline = "spline", // Cubic = "cubic", // Conic = "conic", export type ShapeStyles = Partial> export interface BaseShape { id: string type: ShapeType parentId: string childIndex: number isGenerated: boolean name: string point: number[] rotation: number style: ShapeStyles } export interface DotShape extends BaseShape { type: ShapeType.Dot } export interface CircleShape extends BaseShape { type: ShapeType.Circle radius: number } export interface EllipseShape extends BaseShape { type: ShapeType.Ellipse radiusX: number radiusY: number } export interface LineShape extends BaseShape { type: ShapeType.Line direction: number[] } export interface RayShape extends BaseShape { type: ShapeType.Ray direction: number[] } export interface PolylineShape extends BaseShape { type: ShapeType.Polyline points: number[][] } export interface RectangleShape extends BaseShape { type: ShapeType.Rectangle size: number[] radius: number } export type MutableShape = | DotShape | CircleShape | EllipseShape | LineShape | RayShape | PolylineShape | RectangleShape export type Shape = Readonly export interface Shapes { [ShapeType.Dot]: Readonly [ShapeType.Circle]: Readonly [ShapeType.Ellipse]: Readonly [ShapeType.Line]: Readonly [ShapeType.Ray]: Readonly [ShapeType.Polyline]: Readonly [ShapeType.Rectangle]: Readonly } export type ShapeByType = Shapes[T] export interface CodeFile { id: string name: string code: string } /* -------------------------------------------------- */ /* Editor UI */ /* -------------------------------------------------- */ export interface PointerInfo { target: string pointerId: number origin: number[] point: number[] shiftKey: boolean ctrlKey: boolean metaKey: boolean altKey: boolean } export enum Edge { Top = "top_edge", Right = "right_edge", Bottom = "bottom_edge", Left = "left_edge", } export enum Corner { TopLeft = "top_left_corner", TopRight = "top_right_corner", BottomRight = "bottom_right_corner", BottomLeft = "bottom_left_corner", } export interface Bounds { minX: number minY: number maxX: number maxY: number width: number height: number } export interface RotatedBounds extends Bounds { rotation: number } export interface ShapeBounds extends Bounds { id: string } export interface PointSnapshot extends Bounds { nx: number nmx: number ny: number nmy: number } export interface BoundsSnapshot extends PointSnapshot { nw: number nh: number } export type Difference = A extends B ? never : A export type ShapeSpecificProps = Pick< T, Difference > export type ShapeIndicatorProps = ShapeSpecificProps export type ShapeUtil = { create(props: Partial): K getBounds(shape: K): Bounds hitTest(shape: K, test: number[]): boolean hitTestBounds(shape: K, bounds: Bounds): boolean rotate(shape: K): K translate(shape: K, delta: number[]): K scale(shape: K, scale: number): K stretch(shape: K, scaleX: number, scaleY: number): K render(shape: K): JSX.Element } export enum MoveType { Backward, Forward, ToFront, ToBack, } export enum AlignType { Top, CenterVertical, Bottom, Left, CenterHorizontal, Right, } export enum StretchType { Horizontal, Vertical, } export enum DistributeType { Horizontal, Vertical, } /* -------------------------------------------------- */ /* Code Editor */ /* -------------------------------------------------- */ export type IMonaco = typeof monaco export type IMonacoEditor = monaco.editor.IStandaloneCodeEditor export enum ControlType { Number = "number", Vector = "vector", Text = "text", Select = "select", } export interface BaseCodeControl { id: string type: ControlType label: string } export interface NumberCodeControl extends BaseCodeControl { type: ControlType.Number min?: number max?: number value: number step: number format?: (value: number) => number } export interface VectorCodeControl extends BaseCodeControl { type: ControlType.Vector value: number[] isNormalized: boolean format?: (value: number[]) => number[] } export interface TextCodeControl extends BaseCodeControl { type: ControlType.Text value: string format?: (value: string) => string } export interface SelectCodeControl extends BaseCodeControl { type: ControlType.Select value: T options: T[] format?: (string: T) => string } export type CodeControl = | NumberCodeControl | VectorCodeControl | TextCodeControl | SelectCodeControl