import Command from './commands/Command';
import { Mat33, Rect2, Point2, Vec2, Vec3 } from '@js-draw/math';
import { StrokeDataPoint } from './types';
type PointDataType<T extends Point2 | StrokeDataPoint | number> = T extends Point2 ? Point2 : number;
export declare abstract class ViewportTransform extends Command {
    abstract readonly transform: Mat33;
}
type TransformChangeCallback = (oldTransform: Mat33, newTransform: Mat33) => void;
export declare class Viewport {
    private onTransformChangeCallback;
    private static ViewportTransform;
    /** Converts from canvas to screen coordinates */
    private transform;
    /** Converts from screen to canvas coordinates */
    private inverseTransform;
    private screenRect;
    constructor(onTransformChangeCallback: TransformChangeCallback);
    /**
     * @returns a temporary copy of `this` that does not notify when modified. This is
     * useful when rendering with a temporarily different viewport.
     */
    getTemporaryClone(): Viewport;
    /** Resizes the screen rect to the given size. @internal */
    updateScreenSize(screenSize: Vec2): void;
    /** Get the screen's visible region transformed into canvas space. */
    get visibleRect(): Rect2;
    /** @returns the given point, but in canvas coordinates */
    screenToCanvas(screenPoint: Point2): Point2;
    /** @returns the given point transformed into screen coordinates. */
    canvasToScreen(canvasPoint: Point2): Point2;
    /**
     * @returns a command that transforms the canvas by `transform`.
     *
     * For example, `Viewport.transformBy(moveRight).apply(editor)` would move the canvas to the right
     * (and thus the viewport to the left):
     * ```ts,runnable
     * import { Editor, Viewport, Mat33, Vec2 } from 'js-draw';
     * const editor = new Editor(document.body);
     * const moveRight = Mat33.translation(Vec2.unitX.times(500));
     * // Move the **canvas** right by 500 units:
     * Viewport.transformBy(moveRight).apply(editor);
     * ```
     */
    static transformBy(transform: Mat33): ViewportTransform;
    /**
     * Updates the transformation directly. Using `transformBy` is preferred.
     * @param newTransform - should map from canvas coordinates to screen coordinates.
     */
    resetTransform(newTransform?: Mat33): void;
    get screenToCanvasTransform(): Mat33;
    get canvasToScreenTransform(): Mat33;
    /** @returns the size of the visible region in pixels (screen units). */
    getScreenRectSize(): Vec2;
    /** Alias for `getScreenRectSize`. @deprecated */
    getResolution(): Vec3;
    /** @returns the amount a vector on the canvas is scaled to become a vector on the screen. */
    getScaleFactor(): number;
    /**
     * @returns `getScaleFactor()` rounded to the nearest power of 10.
     * For example, if `getScaleFactor()` returns 101, `getScaleFactorToNearestPowerOfTen()`
     * should return `100` because `100` is the nearest power of 10 to 101.
     */
    getScaleFactorToNearestPowerOfTen(): number;
    private getScaleFactorToNearestPowerOf;
    /** Returns the size of a grid cell (in canvas units) as used by {@link snapToGrid}. */
    static getGridSize(scaleFactor: number): number;
    /**
     * Snaps `canvasPos` to the nearest grid cell corner.
     *
     * @see {@link getGridSize}.
     */
    snapToGrid(canvasPos: Point2): {
        readonly x: number;
        readonly y: number;
        readonly z: number;
        readonly xy: {
            x: number;
            y: number;
        };
        at(idx: number): number;
        length(): number;
        magnitude(): number;
        magnitudeSquared(): number;
        squareDistanceTo(p: Vec3): number;
        distanceTo(p: Vec3): number;
        maximumEntryMagnitude(): number;
        angle(): number;
        normalized(): Vec3;
        normalizedOrZero(): Vec3;
        times(c: number): Vec3;
        plus(v: Vec3): Vec3;
        minus(v: Vec3): Vec3;
        dot(other: Vec3): number;
        cross(other: Vec3): Vec3;
        scale(other: Vec3 | number): Vec3;
        orthog(): Vec3;
        extend(distance: number, direction: Vec3): Vec3;
        lerp(target: Vec3, fractionTo: number): Vec3;
        zip(other: Vec3, zip: (componentInThis: number, componentInOther: number) => number): Vec3;
        map(fn: (component: number, index: number) => number): Vec3;
        asArray(): [number, number, number];
        eq(other: Vec3, fuzz?: number): boolean;
        toString(): string;
    };
    /** Returns the size of one screen pixel in canvas units. */
    getSizeOfPixelOnCanvas(): number;
    /**
     * @returns the angle of the canvas in radians.
     * This is the angle by which the canvas is rotated relative to the screen.
     *
     * Returns an angle in the range $[-\pi, \pi]$ (the same range as {@link Vec3.angle}).
     */
    getRotationAngle(): number;
    /**
     * Rounds the given `point` to a multiple of 10 such that it is within `tolerance` of
     * its original location. This is useful for preparing data for base-10 conversion.
     */
    static roundPoint<T extends Point2 | number>(point: T, tolerance: number): PointDataType<T>;
    /** Round a point with a tolerance of ±1 screen unit. */
    roundPoint(point: Point2): Point2;
    static roundScaleRatio(scaleRatio: number, roundAmount?: number): number;
    computeZoomToTransform(toMakeVisible: Rect2, allowZoomIn?: boolean, allowZoomOut?: boolean): Mat33;
    zoomTo(toMakeVisible: Rect2, allowZoomIn?: boolean, allowZoomOut?: boolean): Command;
}
export default Viewport;
