UNPKG

dotting

Version:

Dotting is a pixel art editor component library for react

219 lines (218 loc) 10 kB
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; }