Add type to controls and change colour types

This commit is contained in:
Mitchell McCaffrey 2021-07-09 22:06:32 +10:00
parent 72b6994a2e
commit 49b8caa2d7
21 changed files with 238 additions and 148 deletions

View File

@ -1,10 +1,17 @@
import React from "react";
import { IconButton } from "theme-ui"; import { IconButton } from "theme-ui";
import BlendOnIcon from "../../../icons/BlendOnIcon"; import BlendOnIcon from "../../../icons/BlendOnIcon";
import BlendOffIcon from "../../../icons/BlendOffIcon"; import BlendOffIcon from "../../../icons/BlendOffIcon";
function AlphaBlendToggle({ useBlending, onBlendingChange }) { type AlphaBlendToggleProps = {
useBlending: boolean;
onBlendingChange: (useBlending: boolean) => void;
};
function AlphaBlendToggle({
useBlending,
onBlendingChange,
}: AlphaBlendToggleProps) {
return ( return (
<IconButton <IconButton
aria-label={useBlending ? "Disable Blending (O)" : "Enable Blending (O)"} aria-label={useBlending ? "Disable Blending (O)" : "Enable Blending (O)"}

View File

@ -1,10 +1,16 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { Box } from "theme-ui"; import { Box, SxProp } from "theme-ui";
import colors, { colorOptions } from "../../../helpers/colors"; import colors, { colorOptions, Color } from "../../../helpers/colors";
import MapMenu from "../MapMenu"; import MapMenu from "../MapMenu";
function ColorCircle({ color, selected, onClick, sx }) { type ColorCircleProps = {
color: Color;
selected: boolean;
onClick?: React.MouseEventHandler<HTMLDivElement>;
} & SxProp;
function ColorCircle({ color, selected, onClick, sx }: ColorCircleProps) {
return ( return (
<Box <Box
key={color} key={color}
@ -34,24 +40,30 @@ function ColorCircle({ color, selected, onClick, sx }) {
); );
} }
function ColorControl({ color, onColorChange, exclude }) { type ColorControlProps = {
color: Color;
onColorChange: (newColor: Color) => void;
exclude: Color[];
};
function ColorControl({ color, onColorChange, exclude }: ColorControlProps) {
const [showColorMenu, setShowColorMenu] = useState(false); const [showColorMenu, setShowColorMenu] = useState(false);
const [colorMenuOptions, setColorMenuOptions] = useState({}); const [colorMenuOptions, setColorMenuOptions] = useState({});
function handleControlClick(event) { function handleControlClick(event: React.MouseEvent<HTMLDivElement>) {
if (showColorMenu) { if (showColorMenu) {
setShowColorMenu(false); setShowColorMenu(false);
setColorMenuOptions({}); setColorMenuOptions({});
} else { } else {
setShowColorMenu(true); setShowColorMenu(true);
const rect = event.target.getBoundingClientRect(); const rect = event.currentTarget.getBoundingClientRect();
setColorMenuOptions({ setColorMenuOptions({
// Align the right of the submenu to the left of the tool and center vertically // Align the right of the submenu to the left of the tool and center vertically
left: `${rect.left + rect.width / 2}px`, left: `${rect.left + rect.width / 2}px`,
top: `${rect.bottom + 16}px`, top: `${rect.bottom + 16}px`,
style: { transform: "translateX(-50%)" }, style: { transform: "translateX(-50%)" },
// Exclude this node from the sub menus auto close // Exclude this node from the sub menus auto close
excludeNode: event.target, excludeNode: event.currentTarget,
}); });
} }
} }

View File

@ -1,4 +1,4 @@
import React, { useEffect } from "react"; import { useEffect } from "react";
import { Flex, IconButton } from "theme-ui"; import { Flex, IconButton } from "theme-ui";
import { useMedia } from "react-media"; import { useMedia } from "react-media";
@ -26,14 +26,23 @@ import { useKeyboard } from "../../../contexts/KeyboardContext";
import shortcuts from "../../../shortcuts"; import shortcuts from "../../../shortcuts";
import { DrawingToolSettings, DrawingToolType } from "../../../types/Drawing";
type DrawingToolSettingsProps = {
settings: DrawingToolSettings;
onSettingChange: (change: Partial<DrawingToolSettings>) => void;
onToolAction: (action: string) => void;
disabledActions: string[];
};
function DrawingToolSettings({ function DrawingToolSettings({
settings, settings,
onSettingChange, onSettingChange,
onToolAction, onToolAction,
disabledActions, disabledActions,
}) { }: DrawingToolSettingsProps) {
// Keyboard shotcuts // Keyboard shotcuts
function handleKeyDown(event) { function handleKeyDown(event: KeyboardEvent) {
if (shortcuts.drawBrush(event)) { if (shortcuts.drawBrush(event)) {
onSettingChange({ type: "brush" }); onSettingChange({ type: "brush" });
} else if (shortcuts.drawPaint(event)) { } else if (shortcuts.drawPaint(event)) {
@ -115,7 +124,9 @@ function DrawingToolSettings({
<Divider vertical /> <Divider vertical />
<ToolSection <ToolSection
tools={tools} tools={tools}
onToolClick={(tool) => onSettingChange({ type: tool.id })} onToolClick={(tool) =>
onSettingChange({ type: tool.id as DrawingToolType })
}
collapse={isSmallScreen} collapse={isSmallScreen}
/> />
<Divider vertical /> <Divider vertical />

View File

@ -1,10 +1,19 @@
import React from "react";
import { IconButton } from "theme-ui"; import { IconButton } from "theme-ui";
import CutOnIcon from "../../../icons/FogCutOnIcon"; import CutOnIcon from "../../../icons/FogCutOnIcon";
import CutOffIcon from "../../../icons/FogCutOffIcon"; import CutOffIcon from "../../../icons/FogCutOffIcon";
function FogCutToggle({ useFogCut, onFogCutChange, disabled }) { type FogCutToggleProps = {
useFogCut: boolean;
onFogCutChange: (useFogCut: boolean) => void;
disabled?: boolean;
};
function FogCutToggle({
useFogCut,
onFogCutChange,
disabled,
}: FogCutToggleProps) {
return ( return (
<IconButton <IconButton
aria-label={ aria-label={

View File

@ -1,10 +1,17 @@
import React from "react";
import { IconButton } from "theme-ui"; import { IconButton } from "theme-ui";
import PreviewOnIcon from "../../../icons/FogPreviewOnIcon"; import PreviewOnIcon from "../../../icons/FogPreviewOnIcon";
import PreviewOffIcon from "../../../icons/FogPreviewOffIcon"; import PreviewOffIcon from "../../../icons/FogPreviewOffIcon";
function FogPreviewToggle({ useFogPreview, onFogPreviewChange }) { type FogPreviewToggleProps = {
useFogPreview: boolean;
onFogPreviewChange: (useFogCut: boolean) => void;
};
function FogPreviewToggle({
useFogPreview,
onFogPreviewChange,
}: FogPreviewToggleProps) {
return ( return (
<IconButton <IconButton
aria-label={ aria-label={

View File

@ -1,4 +1,3 @@
import React from "react";
import { Flex } from "theme-ui"; import { Flex } from "theme-ui";
import { useMedia } from "react-media"; import { useMedia } from "react-media";
@ -24,14 +23,23 @@ import { useKeyboard } from "../../../contexts/KeyboardContext";
import shortcuts from "../../../shortcuts"; import shortcuts from "../../../shortcuts";
function BrushToolSettings({ import { FogToolSettings, FogToolType } from "../../../types/Fog";
type FogToolSettingsProps = {
settings: FogToolSettings;
onSettingChange: (change: Partial<FogToolSettings>) => void;
onToolAction: (action: string) => void;
disabledActions: string[];
};
function FogToolSettings({
settings, settings,
onSettingChange, onSettingChange,
onToolAction, onToolAction,
disabledActions, disabledActions,
}) { }: FogToolSettingsProps) {
// Keyboard shortcuts // Keyboard shortcuts
function handleKeyDown(event) { function handleKeyDown(event: KeyboardEvent) {
if (shortcuts.fogPolygon(event)) { if (shortcuts.fogPolygon(event)) {
onSettingChange({ type: "polygon" }); onSettingChange({ type: "polygon" });
} else if (shortcuts.fogBrush(event)) { } else if (shortcuts.fogBrush(event)) {
@ -86,7 +94,9 @@ function BrushToolSettings({
<Flex sx={{ alignItems: "center" }}> <Flex sx={{ alignItems: "center" }}>
<ToolSection <ToolSection
tools={drawTools} tools={drawTools}
onToolClick={(tool) => onSettingChange({ type: tool.id })} onToolClick={(tool) =>
onSettingChange({ type: tool.id as FogToolType })
}
collapse={isSmallScreen} collapse={isSmallScreen}
/> />
<Divider vertical /> <Divider vertical />
@ -134,4 +144,4 @@ function BrushToolSettings({
); );
} }
export default BrushToolSettings; export default FogToolSettings;

View File

@ -1,10 +1,19 @@
import React from "react";
import { IconButton } from "theme-ui"; import { IconButton } from "theme-ui";
import MultilayerOnIcon from "../../../icons/FogMultilayerOnIcon"; import MultilayerOnIcon from "../../../icons/FogMultilayerOnIcon";
import MultilayerOffIcon from "../../../icons/FogMultilayerOffIcon"; import MultilayerOffIcon from "../../../icons/FogMultilayerOffIcon";
function MultilayerToggle({ multilayer, onMultilayerChange, disabled }) { type MultilayerToggleProps = {
multilayer: boolean;
onMultilayerChange: (multilayer: boolean) => void;
disabled?: boolean;
};
function MultilayerToggle({
multilayer,
onMultilayerChange,
disabled,
}: MultilayerToggleProps) {
return ( return (
<IconButton <IconButton
aria-label={ aria-label={

View File

@ -1,9 +1,18 @@
import React from "react";
import { Flex } from "theme-ui"; import { Flex } from "theme-ui";
import ColorControl from "./ColorControl"; import ColorControl from "./ColorControl";
function PointerToolSettings({ settings, onSettingChange }) { import { PointerToolSettings } from "../../../types/Pointer";
type PointerToolSettingsProps = {
settings: PointerToolSettings;
onSettingChange: (change: Partial<PointerToolSettings>) => void;
};
function PointerToolSettings({
settings,
onSettingChange,
}: PointerToolSettingsProps) {
return ( return (
<Flex sx={{ alignItems: "center" }}> <Flex sx={{ alignItems: "center" }}>
<ColorControl <ColorControl

View File

@ -5,7 +5,12 @@ import RedoIcon from "../../../icons/RedoIcon";
import { isMacLike } from "../../../helpers/shared"; import { isMacLike } from "../../../helpers/shared";
function RedoButton({ onClick, disabled }) { type RedoButtonProps = {
onClick?: React.MouseEventHandler<HTMLButtonElement>;
disabled?: boolean;
};
function RedoButton({ onClick, disabled }: RedoButtonProps) {
return ( return (
<IconButton <IconButton
title={`Redo (${isMacLike ? "Cmd" : "Ctrl"} + Shift + Z)`} title={`Redo (${isMacLike ? "Cmd" : "Ctrl"} + Shift + Z)`}

View File

@ -3,10 +3,24 @@ import { Box, Flex } from "theme-ui";
import RadioIconButton from "../../RadioIconButton"; import RadioIconButton from "../../RadioIconButton";
export type Tool = {
id: string;
title: string;
isSelected: boolean;
icon: React.ReactNode;
disabled?: boolean;
};
type ToolSectionProps = {
collapse: boolean;
tools: Tool[];
onToolClick: (tool: Tool) => void;
};
// Section of map tools with the option to collapse into a vertical list // Section of map tools with the option to collapse into a vertical list
function ToolSection({ collapse, tools, onToolClick }) { function ToolSection({ collapse, tools, onToolClick }: ToolSectionProps) {
const [showMore, setShowMore] = useState(false); const [showMore, setShowMore] = useState(false);
const [collapsedTool, setCollapsedTool] = useState(); const [collapsedTool, setCollapsedTool] = useState<Tool>();
useEffect(() => { useEffect(() => {
const selectedTool = tools.find((tool) => tool.isSelected); const selectedTool = tools.find((tool) => tool.isSelected);
@ -20,7 +34,7 @@ function ToolSection({ collapse, tools, onToolClick }) {
} }
}, [tools]); }, [tools]);
function handleToolClick(tool) { function handleToolClick(tool: Tool) {
if (collapse && tool.isSelected) { if (collapse && tool.isSelected) {
setShowMore(!showMore); setShowMore(!showMore);
} else if (collapse && !tool.isSelected) { } else if (collapse && !tool.isSelected) {
@ -29,7 +43,7 @@ function ToolSection({ collapse, tools, onToolClick }) {
onToolClick(tool); onToolClick(tool);
} }
function renderTool(tool) { function renderTool(tool: Tool) {
return ( return (
<RadioIconButton <RadioIconButton
title={tool.title} title={tool.title}
@ -85,7 +99,9 @@ function ToolSection({ collapse, tools, onToolClick }) {
</Box> </Box>
); );
} else { } else {
return tools.map((tool) => ( return (
<>
{tools.map((tool) => (
<RadioIconButton <RadioIconButton
title={tool.title} title={tool.title}
onClick={() => handleToolClick(tool)} onClick={() => handleToolClick(tool)}
@ -95,7 +111,9 @@ function ToolSection({ collapse, tools, onToolClick }) {
> >
{tool.icon} {tool.icon}
</RadioIconButton> </RadioIconButton>
)); ))}
</>
);
} }
} }

View File

@ -5,7 +5,12 @@ import UndoIcon from "../../../icons/UndoIcon";
import { isMacLike } from "../../../helpers/shared"; import { isMacLike } from "../../../helpers/shared";
function UndoButton({ onClick, disabled }) { type UndoButtonProps = {
onClick?: React.MouseEventHandler<HTMLButtonElement>;
disabled?: boolean;
};
function UndoButton({ onClick, disabled }: UndoButtonProps) {
return ( return (
<IconButton <IconButton
title={`Undo (${isMacLike ? "Cmd" : "Ctrl"} + Z)`} title={`Undo (${isMacLike ? "Cmd" : "Ctrl"} + Z)`}

View File

@ -206,7 +206,7 @@ export function GroupProvider({
/** /**
* Shortcuts * Shortcuts
*/ */
function handleKeyDown(event: React.KeyboardEvent) { function handleKeyDown(event: KeyboardEvent) {
if (disabled) { if (disabled) {
return; return;
} }
@ -218,7 +218,7 @@ export function GroupProvider({
} }
} }
function handleKeyUp(event: React.KeyboardEvent) { function handleKeyUp(event: KeyboardEvent) {
if (disabled) { if (disabled) {
return; return;
} }

View File

@ -3,7 +3,7 @@ import { EventEmitter } from "events";
const KeyboardContext = React.createContext({ keyEmitter: new EventEmitter() }); const KeyboardContext = React.createContext({ keyEmitter: new EventEmitter() });
export function KeyboardProvider({ children }: { children: any}) { export function KeyboardProvider({ children }: { children: React.ReactNode }) {
const [keyEmitter] = useState(new EventEmitter()); const [keyEmitter] = useState(new EventEmitter());
useEffect(() => { useEffect(() => {
function handleKeyDown(event: Event) { function handleKeyDown(event: Event) {
@ -45,11 +45,10 @@ export function KeyboardProvider({ children }: { children: any}) {
); );
} }
/** export function useKeyboard(
* @param {KeyboardEvent} onKeyDown onKeyDown?: (event: KeyboardEvent) => void,
* @param {KeyboardEvent} onKeyUp onKeyUp?: (event: KeyboardEvent) => void
*/ ) {
export function useKeyboard(onKeyDown: (...args: any[]) => void, onKeyUp: (...args: any[]) => void) {
const context = useContext(KeyboardContext); const context = useContext(KeyboardContext);
if (context === undefined) { if (context === undefined) {
throw new Error("useKeyboard must be used within a KeyboardProvider"); throw new Error("useKeyboard must be used within a KeyboardProvider");

View File

@ -1,20 +1,5 @@
export type Colors = {
blue: string;
orange: string;
red: string;
yellow: string;
purple: string;
green: string;
pink: string;
teal: string;
black: string;
darkGray: string;
lightGray: string;
white: string;
}
// Colors used for the game for theme general UI colors look at theme.js // Colors used for the game for theme general UI colors look at theme.js
const colors: Colors = { const colors = {
blue: "rgb(26, 106, 255)", blue: "rgb(26, 106, 255)",
orange: "rgb(255, 116, 51)", orange: "rgb(255, 116, 51)",
red: "rgb(255, 77, 77)", red: "rgb(255, 77, 77)",
@ -29,6 +14,10 @@ const colors: Colors = {
white: "rgb(255, 255, 255)", white: "rgb(255, 255, 255)",
}; };
export const colorOptions = Object.keys(colors); export type Colors = typeof colors;
export type Color = keyof Colors;
export const colorOptions = Object.keys(colors) as Color[];
export default colors; export default colors;

View File

@ -30,12 +30,15 @@ import { useAssets } from "../contexts/AssetsContext";
import { GroupProvider } from "../contexts/GroupContext"; import { GroupProvider } from "../contexts/GroupContext";
import { TileDragProvider } from "../contexts/TileDragContext"; import { TileDragProvider } from "../contexts/TileDragContext";
import { Map } from "../types/Map";
import { MapState } from "../types/MapState";
type SelectMapProps = { type SelectMapProps = {
isOpen: boolean; isOpen: boolean;
onDone: any; onDone: () => void;
onMapChange: any; onMapChange: (map?: Map, mapState?: MapState) => void;
onMapReset: any; onMapReset: (newState: MapState) => void;
currentMap: any; currentMap?: Map;
}; };
function SelectMapModal({ function SelectMapModal({
@ -79,9 +82,9 @@ function SelectMapModal({
const [isLargeImageWarningModalOpen, setShowLargeImageWarning] = const [isLargeImageWarningModalOpen, setShowLargeImageWarning] =
useState(false); useState(false);
const largeImageWarningFiles = useRef<any>(); const largeImageWarningFiles = useRef<File[]>();
async function handleImagesUpload(files: any) { async function handleImagesUpload(files: File[]) {
if (navigator.storage) { if (navigator.storage) {
// Attempt to enable persistant storage // Attempt to enable persistant storage
await navigator.storage.persist(); await navigator.storage.persist();
@ -132,9 +135,11 @@ function SelectMapModal({
async function handleLargeImageWarningConfirm() { async function handleLargeImageWarningConfirm() {
setShowLargeImageWarning(false); setShowLargeImageWarning(false);
const files = largeImageWarningFiles.current; const files = largeImageWarningFiles.current;
if (files) {
for (let file of files) { for (let file of files) {
await handleImageUpload(file); await handleImageUpload(file);
} }
}
largeImageWarningFiles.current = undefined; largeImageWarningFiles.current = undefined;
clearFileInput(); clearFileInput();
} }
@ -171,7 +176,7 @@ function SelectMapModal({
onMapChange(map, mapState); onMapChange(map, mapState);
setIsLoading(false); setIsLoading(false);
} else { } else {
onMapChange(null, null); onMapChange(undefined, undefined);
} }
onDone(); onDone();
} }
@ -220,9 +225,15 @@ function SelectMapModal({
}} }}
shouldCloseOnEsc={!isDraggingMap} shouldCloseOnEsc={!isDraggingMap}
> >
<ImageDrop onDrop={handleImagesUpload} dropText="Drop map to import"> <ImageDrop
onDrop={({ files }) => handleImagesUpload(files)}
dropText="Drop map to import"
>
<input <input
onChange={(event) => handleImagesUpload(event.target.files)} onChange={(event) =>
event.target.files &&
handleImagesUpload(Array.from(event.target.files))
}
type="file" type="file"
accept="image/jpeg, image/gif, image/png, image/webp" accept="image/jpeg, image/gif, image/png, image/webp"
style={{ display: "none" }} style={{ display: "none" }}

View File

@ -79,7 +79,7 @@ function SelectTokensModal({
useState(false); useState(false);
const largeImageWarningFiles = useRef<File[]>(); const largeImageWarningFiles = useRef<File[]>();
async function handleImagesUpload(files: FileList) { async function handleImagesUpload(files: File[]) {
if (navigator.storage) { if (navigator.storage) {
// Attempt to enable persistant storage // Attempt to enable persistant storage
await navigator.storage.persist(); await navigator.storage.persist();
@ -231,10 +231,14 @@ function SelectTokensModal({
}} }}
shouldCloseOnEsc={!isDraggingToken} shouldCloseOnEsc={!isDraggingToken}
> >
<ImageDrop onDrop={handleImagesUpload} dropText="Drop token to import"> <ImageDrop
onDrop={({ files }) => handleImagesUpload(files)}
dropText="Drop token to import"
>
<input <input
onChange={(event: React.ChangeEvent<HTMLInputElement>) => onChange={(event) =>
event.target.files && handleImagesUpload(event.target.files) event.target.files &&
handleImagesUpload(Array.from(event.target.files))
} }
type="file" type="file"
accept="image/jpeg, image/gif, image/png, image/webp" accept="image/jpeg, image/gif, image/png, image/webp"

View File

@ -19,96 +19,76 @@ function singleKey(event: KeyboardEvent, key: string): boolean {
); );
} }
/** function undo(event: KeyboardEvent): boolean {
* @param {Keyboard} event
* @returns {string | boolean}
*/
function undo(event: KeyboardEvent): string | boolean {
const { key, ctrlKey, metaKey, shiftKey } = event; const { key, ctrlKey, metaKey, shiftKey } = event;
return (key === "z" || key === "Z") && (ctrlKey || metaKey) && !shiftKey; return (key === "z" || key === "Z") && (ctrlKey || metaKey) && !shiftKey;
} }
/** function redo(event: KeyboardEvent): boolean {
* @param {Keyboard} event
* @returns {string | boolean}
*/
function redo(event: KeyboardEvent): string | boolean {
const { key, ctrlKey, metaKey, shiftKey } = event; const { key, ctrlKey, metaKey, shiftKey } = event;
return (key === "z" || key === "Z") && (ctrlKey || metaKey) && shiftKey; return (key === "z" || key === "Z") && (ctrlKey || metaKey) && shiftKey;
} }
/** function zoomIn(event: KeyboardEvent): boolean {
* @param {Keyboard} event
* @returns {string | boolean}
*/
function zoomIn(event: KeyboardEvent): string | boolean {
const { key, ctrlKey, metaKey } = event; const { key, ctrlKey, metaKey } = event;
return (key === "=" || key === "+") && !ctrlKey && !metaKey; return (key === "=" || key === "+") && !ctrlKey && !metaKey;
} }
/** function zoomOut(event: KeyboardEvent): boolean {
* @param {Keyboard} event
* @returns {string | boolean}
*/
function zoomOut(event: KeyboardEvent): string | boolean {
const { key, ctrlKey, metaKey } = event; const { key, ctrlKey, metaKey } = event;
return (key === "-" || key === "_") && !ctrlKey && !metaKey; return (key === "-" || key === "_") && !ctrlKey && !metaKey;
} }
/** type Shortcut = (event: KeyboardEvent) => boolean;
* @callback shortcut
* @param {KeyboardEvent} event
* @returns {boolean}
*/
/** /**
* @type {Object.<string, shortcut>} * @type {Object.<string, shortcut>}
*/ */
const shortcuts = { const shortcuts: Record<string, Shortcut> = {
// Tools // Tools
move: (event: KeyboardEvent) => singleKey(event, " "), move: (event) => singleKey(event, " "),
moveTool: (event: KeyboardEvent) => singleKey(event, "w"), moveTool: (event) => singleKey(event, "w"),
drawingTool: (event: KeyboardEvent) => singleKey(event, "d"), drawingTool: (event) => singleKey(event, "d"),
fogTool: (event: KeyboardEvent) => singleKey(event, "f"), fogTool: (event) => singleKey(event, "f"),
measureTool: (event: KeyboardEvent) => singleKey(event, "m"), measureTool: (event) => singleKey(event, "m"),
pointerTool: (event: KeyboardEvent) => singleKey(event, "q"), pointerTool: (event) => singleKey(event, "q"),
noteTool: (event: KeyboardEvent) => singleKey(event, "n"), noteTool: (event) => singleKey(event, "n"),
// Map editor // Map editor
gridNudgeUp: ({ key }: { key: string}) => key === "ArrowUp", gridNudgeUp: ({ key }) => key === "ArrowUp",
gridNudgeLeft: ({ key }: { key: string }) => key === "ArrowLeft", gridNudgeLeft: ({ key }) => key === "ArrowLeft",
gridNudgeRight: ({ key }: { key: string }) => key === "ArrowRight", gridNudgeRight: ({ key }) => key === "ArrowRight",
gridNudgeDown: ({ key }: { key: string }) => key === "ArrowDown", gridNudgeDown: ({ key }) => key === "ArrowDown",
// Drawing tool // Drawing tool
drawBrush: (event: KeyboardEvent) => singleKey(event, "b"), drawBrush: (event) => singleKey(event, "b"),
drawPaint: (event: KeyboardEvent) => singleKey(event, "p"), drawPaint: (event) => singleKey(event, "p"),
drawLine: (event: KeyboardEvent) => singleKey(event, "l"), drawLine: (event) => singleKey(event, "l"),
drawRect: (event: KeyboardEvent) => singleKey(event, "r"), drawRect: (event) => singleKey(event, "r"),
drawCircle: (event: KeyboardEvent) => singleKey(event, "c"), drawCircle: (event) => singleKey(event, "c"),
drawTriangle: (event: KeyboardEvent) => singleKey(event, "t"), drawTriangle: (event) => singleKey(event, "t"),
drawErase: (event: KeyboardEvent) => singleKey(event, "e"), drawErase: (event) => singleKey(event, "e"),
drawBlend: (event: KeyboardEvent) => singleKey(event, "o"), drawBlend: (event) => singleKey(event, "o"),
// Fog tool // Fog tool
fogPolygon: (event: KeyboardEvent) => singleKey(event, "p"), fogPolygon: (event) => singleKey(event, "p"),
fogRectangle: (event: KeyboardEvent) => singleKey(event, "r"), fogRectangle: (event) => singleKey(event, "r"),
fogBrush: (event: KeyboardEvent) => singleKey(event, "b"), fogBrush: (event) => singleKey(event, "b"),
fogToggle: (event: KeyboardEvent) => singleKey(event, "t"), fogToggle: (event) => singleKey(event, "t"),
fogErase: (event: KeyboardEvent) => singleKey(event, "e"), fogErase: (event) => singleKey(event, "e"),
fogLayer: (event: KeyboardEvent) => singleKey(event, "l"), fogLayer: (event) => singleKey(event, "l"),
fogPreview: (event: KeyboardEvent) => singleKey(event, "f"), fogPreview: (event) => singleKey(event, "f"),
fogCut: (event: KeyboardEvent) => singleKey(event, "c"), fogCut: (event) => singleKey(event, "c"),
fogFinishPolygon: ({ key }: { key: string }) => key === "Enter", fogFinishPolygon: ({ key }) => key === "Enter",
fogCancelPolygon: ({ key }: { key: string }) => key === "Escape", fogCancelPolygon: ({ key }) => key === "Escape",
// Stage interaction // Stage interaction
stageZoomIn: zoomIn, stageZoomIn: zoomIn,
stageZoomOut: zoomOut, stageZoomOut: zoomOut,
stagePrecisionZoom: ({ key }: { key: string }) => key === "Shift", stagePrecisionZoom: ({ key }) => key === "Shift",
// Select // Select
selectRange: ({ key }: { key: string }) => key === "Shift", selectRange: ({ key }) => key === "Shift",
selectMultiple: ({ key }: { key: string }) => key === "Control" || key === "Meta", selectMultiple: ({ key }) => key === "Control" || key === "Meta",
// Common // Common
undo, undo,
redo, redo,
delete: ({ key }: { key: string }) => key === "Backspace" || key === "Delete", delete: ({ key }) => key === "Backspace" || key === "Delete",
}; };
export default shortcuts; export default shortcuts;

View File

@ -1,4 +1,5 @@
import Vector2 from "../helpers/Vector2"; import Vector2 from "../helpers/Vector2";
import { Color } from "../helpers/colors";
export type DrawingToolType = export type DrawingToolType =
| "brush" | "brush"
@ -11,7 +12,7 @@ export type DrawingToolType =
export type DrawingToolSettings = { export type DrawingToolSettings = {
type: DrawingToolType; type: DrawingToolType;
color: string; color: Color;
useBlending: boolean; useBlending: boolean;
}; };

View File

@ -1,4 +1,5 @@
import Vector2 from "../helpers/Vector2"; import Vector2 from "../helpers/Vector2";
import { Color } from "../helpers/colors";
export type FogToolType = export type FogToolType =
| "polygon" | "polygon"
@ -20,7 +21,7 @@ export type FogData = {
}; };
export type Fog = { export type Fog = {
color: string; color: Color;
data: FogData; data: FogData;
id: string; id: string;
strokeWidth: number; strokeWidth: number;

View File

@ -1,6 +1,8 @@
import { Color } from "../helpers/colors";
export type Note = { export type Note = {
id: string; id: string;
color: string; color: Color;
lastModified: number; lastModified: number;
lastModifiedBy: string; lastModifiedBy: string;
locked: boolean; locked: boolean;

View File

@ -1,12 +1,13 @@
import Vector2 from "../helpers/Vector2"; import Vector2 from "../helpers/Vector2";
import { Color } from "../helpers/colors";
export type PointerToolSettings = { export type PointerToolSettings = {
color: string; color: Color;
}; };
export type PointerState = { export type PointerState = {
position: Vector2; position: Vector2;
visible: boolean; visible: boolean;
id: string; id: string;
color: string; color: Color;
}; };