import type { Random } from "../data/random.js"; import { Shake } from "../device/shake.js"; import type { Canvas } from "./canvas.js"; import { RenderLoop } from "./render-loop.js"; /** * Provides the input as-is. * * This method exists only to make use of the template string tag in code, * which allows us to use in-IDE support for CSS, even if there is no build * process to interpret the tag. * {@link https://lit.dev/docs/components/styles/ | Lit styles}. * @param input - The CSS code. * @returns The CSS code as-is. */ export declare const css: (input: TemplateStringsArray) => string; /** * The CSS we inject into the document, if requested. */ export declare const CANVAS_SANDBOX_DEFAULT_CSS: string; /** * The options your application has to accept so it can interact with the {@linkcode CanvasSandbox}. */ export interface CanvasSandboxExpectedOptions { /** * Should your application run in dark mode? * You can ignore this setting and produce any colored output you want, * but the setting will be toggeled by the sandbox according to the user's * browser/OS preference. */ darkMode: boolean; /** * The seed for the PRNG. */ seed: number; /** * The part of the canvas that the targetted render kernel will handle. * This is ignored, unless you use multi-process rendering. */ viewport: { /** * Start of the viewport in fractional world-space. */ x: number; /** * Start of the viewport in fractional world-space. */ y: number; /** * Width of the viewport in fractional world-space. */ w: number; /** * Height of the viewport in fractional world-space. */ h: number; }; } /** * Describes an application running inside the {@linkcode CanvasSandbox}. * @typeParam TApplicationOptions - The type of the options object * with which the application is constructed. */ export interface CanvasSandboxApplication { /** * The options with which the application was constructed. */ options: TApplicationOptions; /** * The PRNG used in this application. */ random: Random; /** * Is the application currently paused? * Should be get/set, but can also be ignored, if the feature isn't used. */ paused: boolean; /** * Request the application to draw a new frame. * @param delta - How many milliseconds passed since the last frame draw. * @param timestamp - The current timestamp. */ onDraw(delta: number, timestamp: number): void; /** * Reconfigure the application with the given options and restart it. * @param canvas - The canvas to use. * @param options - The new options to use. */ reconfigure(canvas: TCanvas, options?: Partial): void; /** * Start the application. */ start(options?: Partial): void; /** * Pause rendering. * @param paused - Should rendering be paused (`true`) or unpaused (`false`)? */ pause(paused: boolean): void; } /** * Options for a {@linkcode CanvasSandbox}. */ export interface CanvasSandboxOptions { /** * Should the sandbox render developer information? * @defaultValue false */ devMode: boolean; /** * Should the sandbox default CSS be injected into the body? * @defaultValue true */ injectDefaultCss: boolean; } /** * The {@linkcode CanvasSandbox} provides a scaffold to quickly perform experiments * with a {@linkcode !HTMLCanvasElement} in a document. Common functionality for such * experiments is implemented in the sandbox already. * @example * ### `main.ts` * ```ts * import { Random, seedFromString } from "@oliversalzburg/js-utils/lib/random.js"; * import { Canvas } from "@oliversalzburg/js-utils/lib/graphics/canvas.js"; * import { getDocumentElementTypeByIdStrict } from "@oliversalzburg/js-utils/lib/dom/core.js"; * import { CanvasSandbox } from "@oliversalzburg/js-utils/lib/graphics/canvas-sandbox.js"; * * interface ApplicationOptions { * seed: string; * somethingElse: number; * } * * class Application { * canvas: Canvas; * options: ApplicationOptions; * random: Random; * * constructor(canvas:Canvas, options: ApplicationOptions) { * this.canvas = canvas; * this.options = options; * this.random = new Random(seedFromString(options.seed)); * } * * reconfigure(canvas:Canvas, options: Partial = {}) { * this.canvas = canvas; * this.options = { ...this.options, ...options }; * this.random = new Random(seedFromString(options.seed)); * } * * onDraw(delta:number, timestamp:number) { * // draw something on `this.canvas` * } * * start() {} * } * * const canvasNode = getDocumentElementTypeByIdStrict(document, "main", HTMLCanvasElement); * const canvasSandbox = new CanvasSandbox( * window, * canvasNode, * Application, * {seed: "foo", somethingElse: 12345} * ); * * // By running the sandbox, your `start()` and `onDraw()` methods will automatically be invoked * // by the sandbox. You shouldn't invoke those methods directly from your own code. * canvasSandbox.run(); * ``` * ### `index.html` * ```html * * * * * * * * * * * * ``` * @typeParam TApplicationOptions - The type of the options * the application in the sandbox will be constructed with. */ export declare class CanvasSandbox { #private; /** * The window the sandbox is running in. */ readonly window: Window; /** * The document the sandbox is interacting with. */ readonly document: Document; /** * The application running inside the sandbox. */ readonly application: CanvasSandboxApplication; /** * The canvas node that we're drawing into. */ readonly canvasNode: HTMLCanvasElement; /** * Our convenience canvas wrapper, which we provide to the application * to render to. */ readonly canvas: TCanvas; /** * The render loop we use to control frame rendering. */ readonly renderLoop: RenderLoop; /** * Our handler for device shaking. */ readonly shakeHandler: Shake; /** * The options for this sandbox. */ readonly sandboxOptions: Partial; /** * Construct a new {@linkcode CanvasSandbox}. * @param window - The window we're running inside. * @param canvasNode - The canvas node we're drawing to. * @param CanvasImpl - The canvas implementation you want to use in this sandbox. * see {@linkcode Canvas2D} and {@linkcode Canvas3D}. * @param Application - The application that is going to run in the sandbox. * @param options - The options that the application should be constructed with. * @param sandboxOptions - The options for the sandbox itself. */ constructor(window: Window, canvasNode: HTMLCanvasElement, CanvasImpl: new (canvasNode: HTMLCanvasElement) => TCanvas, Application: new ( /** * The canvas that the application will receive. */ canvas: TCanvas, /** * The options that will be passed to the application. */ options: TApplicationOptions) => CanvasSandboxApplication, options: TApplicationOptions, sandboxOptions?: Partial); /** * Injects our default CSS into the document, if it hasn't already been injected. * @see {@linkcode CANVAS_SANDBOX_DEFAULT_CSS} */ injectDefaultCss(): void; /** * Run the sandbox. */ run(): void; /** * Switch the sandbox to dark mode. */ toDarkMode(): void; /** * Switch the sandbox to light mode. */ toLightMode(): void; }