dotting
Version:
Dotting is a pixel art editor component library for react
219 lines (218 loc) • 10 kB
TypeScript
import React, { KeyboardEvent } from "react";
import { ButtonDirection } from "./config";
import { AddGridIndicesParams, BRUSH_PATTERN_ELEMENT, BrushTool, CanvasBrushChangeParams, CanvasDataChangeParams, CanvasGridChangeParams, CanvasHoverPixelChangeParams, CanvasInfoChangeParams, CanvasStrokeEndParams, ColorChangeItem, Coord, DeleteGridIndicesParams, Dimensions, GridIndices, ImageDownloadOptions, LayerChangeParams, LayerProps, PanZoom, PixelModifyItem, SelectAreaRange } from "./types";
import { Action } from "../../actions/Action";
import EventDispatcher from "../../utils/eventDispatcher";
import { TouchyEvent } from "../../utils/touch";
export default class Editor extends EventDispatcher {
private gridLayer;
private interactionLayer;
private dataLayer;
private foregroundCanvasElement;
private backgroundCanvasElement;
private foregroundCtx;
private backgroundCtx;
private zoomSensitivity;
private maxScale;
private minScale;
private extensionAllowanceRatio;
private pinchZoomDiff;
private width;
private height;
private originalLayerIdsInOrderForHistory;
private topRowIndex;
private leftColumnIndex;
private lastRenderAllCall;
private initialIsGridVisible;
private panZoom;
private panPoint;
private dpr;
private brushColor;
private gridSquareLength;
private maxHistoryCount;
private undoHistory;
private redoHistory;
private extensionPoint;
private isPanZoomable;
private isAltPressed;
private mouseMode;
private brushTool;
private originalBrushTool;
private mouseDownWorldPos;
private mouseDownPanZoom;
private mouseMoveWorldPos;
private previousMouseMoveWorldPos;
private renderDataLayerTimeout;
private isDrawingEnabled;
private isInteractionApplicable;
private element;
private resizeUnit;
private maxColumnCount;
private maxRowCount;
private minColumnCount;
private minRowCount;
constructor({ gridCanvas, interactionCanvas, dataCanvas, backgroundCanvas, foregroundCanvas, initLayers, gridSquareLength, width, height, initAutoScale, dpr, }: {
gridCanvas: HTMLCanvasElement;
interactionCanvas: HTMLCanvasElement;
dataCanvas: HTMLCanvasElement;
backgroundCanvas: HTMLCanvasElement;
foregroundCanvas: HTMLCanvasElement;
initLayers?: Array<LayerProps>;
gridSquareLength?: number;
width: number;
height: number;
initAutoScale?: boolean;
dpr?: number;
});
initialize(): void;
adjustInitialZoomScale(dimensions: Dimensions, initScale?: number): void;
emitCurrentGridStatus(): void;
emitCurrentHoverPixelStatus(): void;
emitCurrentData(): void;
emitCurrentBrushTool(): void;
emitCurrentLayerStatus(): void;
emitCurrentCanvasInfoStatus(baseColumnCount?: number, baseRowCount?: number): void;
emitCanvasInfoChangeEvent(parmas: CanvasInfoChangeParams): void;
emitDataChangeEvent(params: CanvasDataChangeParams): void;
emitGridChangeEvent(params: CanvasGridChangeParams): void;
emitStrokeEndEvent(params: CanvasStrokeEndParams): void;
emitHoverPixelChangeEvent(params: CanvasHoverPixelChangeParams): void;
emitBrushChangeEvent(params: CanvasBrushChangeParams): void;
emitLayerChangeEvent(params: LayerChangeParams): void;
setBrushPattern(pattern: Array<Array<BRUSH_PATTERN_ELEMENT>>): void;
setBackgroundColor(color: React.CSSProperties["color"]): void;
setIndicatorPixels(indicatorPixels: Array<PixelModifyItem>): void;
setIsGridFixed(isGridFixed: boolean): void;
setGridStrokeColor(color: string): void;
setGridStrokeWidth(width: number): void;
setDefaultPixelColor(color: string): void;
setGridSquareLength(length: number): void;
setMinScale(minScale: number): void;
setMaxScale(maxScale: number): void;
setIsGridVisible(isGridVisible: boolean): void;
setIsPanZoomable(isPanZoomable: boolean): void;
setIsDrawingEnabled(isDrawingEnabled: boolean): void;
setIsInteractionApplicable(isInteractionApplicable: boolean): void;
setBrushTool(tool: BrushTool): void;
setIsAltPressed(isAltPressed: boolean): void;
setResizeUnit(resizeUnit: number): void;
setZoomSensitivity(zoomSensitivity: number): void;
setMaxColumnCount(maxColumnCount: number): void;
setMaxRowCount(maxRowCount: number): void;
setMinColumnCount(minColumnCount: number): void;
setMinRowCount(minRowCount: number): void;
changeBrushColor(color: string): void;
setBrushColor(color: string): void;
getBrushColor(): string;
getBrushPattern(): BRUSH_PATTERN_ELEMENT[][];
getColumnCount(): number;
getRowCount(): number;
getGridIndices(): GridIndices;
getGridSquareLength(): number;
getMinScale(): number;
getMaxScale(): number;
styleMouseCursor: (mouseCoord: Coord) => void;
detectButtonClicked(coord: Coord): ButtonDirection | null;
scale(x: number, y: number): void;
setWidth(width: number, devicePixelRatio?: number): void;
setHeight(height: number, devicePixelRatio?: number): void;
getWidth(): number;
getHeight(): number;
getCanvasElement(): HTMLCanvasElement;
getLayers(): {
id: string;
data: import("./types").DottingData;
}[];
getLayersAsArray(): {
id: string;
data: PixelModifyItem[][];
}[];
getPanZoom(): PanZoom;
setSize(width: number, height: number, devicePixelRatio?: number): void;
setDpr(dpr: number): void;
setTopLeftIndices(topRowIndex: number, leftColumnIndex: number): void;
setCurrentLayer(layerId: string): void;
addLayer(layerId: string, insertPosition: number, data?: Array<Array<PixelModifyItem>>, shouldRecordAction?: boolean): void;
removeLayer(layerId: string, shouldRecordAction?: boolean): void;
showLayer(layerId: string): void;
hideLayer(layerId: string): void;
/**
* @description Isolates the layer, i.e. hides all other layers
* @param layerId Layer Id to be isolated
*/
isolateLayer(layerId: string): void;
/**
* @description Shows all layers
*/
showAllLayers(): void;
/**
* @description This moves the layer to the specified index,
* However, the moved information will not be saved in to history
* This is because moving a layer from one index to another can happen frequently
* If a user wants to record this action, use reorderlayerByIds instead
* @param layerId layer id to be moved
* @param toIndex index to be moved to
*/
changeLayerPosition(layerId: string, toIndex: number): void;
reorderLayersByIds(layerIds: Array<string>): void;
/**
* @summary Sets the data of the pixel array (use with caution, since data will be overwritten!)
* This function will reset the undo and redo history since it is unnecessary to keep them when data is set externally
* @param data Array of PixelModifyItem (It must be a rectangular array, i.e. all rows must have the same length)
*/
setData(data: Array<Array<PixelModifyItem>>, layerId?: string, isLocalChange?: boolean): void;
setLayers(layers: Array<LayerProps>): void;
convertWorldPosToCanvasOffset(worldPos: Coord): Coord;
setPanZoom({ offset, scale, baseColumnCount, baseRowCount, }: Partial<PanZoom> & {
baseColumnCount?: number;
baseRowCount?: number;
}): void;
relayPanZoomToOtherLayers(): void;
handleExtension: (evt: TouchyEvent) => void;
addGridIndices({ rowIndices, columnIndices, data, layerId, isLocalChange, }: AddGridIndicesParams): void;
deleteGridIndices({ rowIndices, columnIndices, layerId, isLocalChange, }: DeleteGridIndicesParams): void;
private extendInteractionGridBy;
private shortenInteractionGridBy;
handlePinchZoom: (evt: TouchyEvent) => void;
handleKeyDown: (e: KeyboardEvent) => void;
handleWheel: (e: WheelEvent) => void;
handlePanning: (evt: TouchyEvent) => void;
private drawPixelInInteractionLayer;
private relayDataDimensionsToLayers;
private relayInteractionDataToDataLayer;
/**
* @description records the size change action of the user interaction
*/
recordSizeChangeAction(rowIndicesToAdd: Array<number>, columnIndicesToAdd: Array<number>, rowIndicesToDelete: Array<number>, columnIndicesToDelete: Array<number>, deletedPixels: Array<PixelModifyItem>): void;
recordColorChangeAction(pixelModifyItems: Array<ColorChangeItem>): void;
commitAction(action: Action): void;
recordAction(action: Action): void;
undo(): void;
redo(): void;
erasePixels(data: Array<{
rowIndex: number;
columnIndex: number;
}>, layerId?: string, isLocalChange?: boolean): void;
colorPixels(data: Array<PixelModifyItem>, layerId?: string, isLocalChange?: boolean): void;
private colorPixelsArea;
onMouseDown(evt: TouchyEvent): void;
private getColoredPixelsInSelectedArea;
onMouseMove(evt: TouchyEvent): void;
getSelectedArea(): SelectAreaRange;
onKeyDown(e: KeyboardEvent): void;
onKeyUp(e: KeyboardEvent<HTMLDivElement>): void;
relaySelectingAreaToSelectedArea(): void;
relayExtendingSelectedAreaToSelectedArea(): void;
relayMovingSelectedAreaToSelectedArea(): void;
onInteractionEnded(evt: TouchyEvent, shouldUpdateCapturedImage: boolean): void;
onMouseUp(evt: TouchyEvent): void;
onMouseOut(evt: TouchyEvent): void;
renderGridLayer(): void;
clear(): void;
downloadImage(options: ImageDownloadOptions): void;
renderAll(): void;
renderErasedPixelsFromInteractionLayerInDataLayer(): void;
renderDataLayer(): void;
renderInteractionLayer(): void;
destroy(): void;
}