diff --git a/packages/excalidraw/actions/actionFontSize.ts b/packages/excalidraw/actions/actionFontSize.ts new file mode 100644 index 000000000..b0ee3fbff --- /dev/null +++ b/packages/excalidraw/actions/actionFontSize.ts @@ -0,0 +1,94 @@ +import { ExcalidrawElement, ExcalidrawTextElement } from "../element/types"; +import { KEYS } from "../keys"; +import { AppClassProperties, AppState } from "../types"; +import { register } from "./register"; + +const FONT_SIZE_RELATIVE_INCREASE_STEP = 0.1; + +const changeFontSize = ( + elements: readonly ExcalidrawElement[], + appState: AppState, + app: AppClassProperties, + getNewFontSize: (element: ExcalidrawTextElement) => number, + fallbackValue?: ExcalidrawTextElement["fontSize"], +) => { + const newFontSizes = new Set(); + + return { + elements: changeProperty( + elements, + appState, + (oldElement) => { + if (isTextElement(oldElement)) { + const newFontSize = getNewFontSize(oldElement); + newFontSizes.add(newFontSize); + + let newElement: ExcalidrawTextElement = newElementWith(oldElement, { + fontSize: newFontSize, + }); + redrawTextBoundingBox( + newElement, + app.scene.getContainerElement(oldElement), + ); + + newElement = offsetElementAfterFontResize(oldElement, newElement); + + return newElement; + } + + return oldElement; + }, + true, + ), + appState: { + ...appState, + // update state only if we've set all select text elements to + // the same font size + currentItemFontSize: + newFontSizes.size === 1 + ? [...newFontSizes][0] + : fallbackValue ?? appState.currentItemFontSize, + }, + commitToHistory: true, + }; +}; + +export const actionDecreaseFontSize = register({ + name: "decreaseFontSize", + trackEvent: false, + perform: (elements, appState, value, app) => { + return changeFontSize(elements, appState, app, (element) => + Math.round( + // get previous value before relative increase (doesn't work fully + // due to rounding and float precision issues) + (1 / (1 + FONT_SIZE_RELATIVE_INCREASE_STEP)) * element.fontSize, + ), + ); + }, + keyTest: (event) => { + return ( + event[KEYS.CTRL_OR_CMD] && + event.shiftKey && + // KEYS.COMMA needed for MacOS + (event.key === KEYS.CHEVRON_LEFT || event.key === KEYS.COMMA) + ); + }, +}); + +export const actionIncreaseFontSize = register({ + name: "increaseFontSize", + trackEvent: false, + perform: (elements, appState, value, app) => { + return changeFontSize(elements, appState, app, (element) => + Math.round(element.fontSize * (1 + FONT_SIZE_RELATIVE_INCREASE_STEP)), + ); + }, + keyTest: (event) => { + return ( + event[KEYS.CTRL_OR_CMD] && + event.shiftKey && + // KEYS.PERIOD needed for MacOS + (event.key === KEYS.CHEVRON_RIGHT || event.key === KEYS.PERIOD) + ); + }, +}); diff --git a/packages/excalidraw/actions/actionProperties.tsx b/packages/excalidraw/actions/actionProperties.tsx index 79e50aa68..9fee07e17 100644 --- a/packages/excalidraw/actions/actionProperties.tsx +++ b/packages/excalidraw/actions/actionProperties.tsx @@ -96,8 +96,6 @@ import { hasStrokeColor } from "../scene/comparisons"; import { arrayToMap, getShortcutKey } from "../utils"; import { register } from "./register"; -const FONT_SIZE_RELATIVE_INCREASE_STEP = 0.1; - export const changeProperty = ( elements: readonly ExcalidrawElement[], appState: AppState, @@ -185,54 +183,6 @@ const offsetElementAfterFontResize = ( ); }; -const changeFontSize = ( - elements: readonly ExcalidrawElement[], - appState: AppState, - app: AppClassProperties, - getNewFontSize: (element: ExcalidrawTextElement) => number, - fallbackValue?: ExcalidrawTextElement["fontSize"], -) => { - const newFontSizes = new Set(); - - return { - elements: changeProperty( - elements, - appState, - (oldElement) => { - if (isTextElement(oldElement)) { - const newFontSize = getNewFontSize(oldElement); - newFontSizes.add(newFontSize); - - let newElement: ExcalidrawTextElement = newElementWith(oldElement, { - fontSize: newFontSize, - }); - redrawTextBoundingBox( - newElement, - app.scene.getContainerElement(oldElement), - ); - - newElement = offsetElementAfterFontResize(oldElement, newElement); - - return newElement; - } - - return oldElement; - }, - true, - ), - appState: { - ...appState, - // update state only if we've set all select text elements to - // the same font size - currentItemFontSize: - newFontSizes.size === 1 - ? [...newFontSizes][0] - : fallbackValue ?? appState.currentItemFontSize, - }, - commitToHistory: true, - }; -}; - // ----------------------------------------------------------------------------- export const actionChangeStrokeColor = register({ @@ -670,46 +620,6 @@ export const actionChangeFontSize = register({ ), }); -export const actionDecreaseFontSize = register({ - name: "decreaseFontSize", - trackEvent: false, - perform: (elements, appState, value, app) => { - return changeFontSize(elements, appState, app, (element) => - Math.round( - // get previous value before relative increase (doesn't work fully - // due to rounding and float precision issues) - (1 / (1 + FONT_SIZE_RELATIVE_INCREASE_STEP)) * element.fontSize, - ), - ); - }, - keyTest: (event) => { - return ( - event[KEYS.CTRL_OR_CMD] && - event.shiftKey && - // KEYS.COMMA needed for MacOS - (event.key === KEYS.CHEVRON_LEFT || event.key === KEYS.COMMA) - ); - }, -}); - -export const actionIncreaseFontSize = register({ - name: "increaseFontSize", - trackEvent: false, - perform: (elements, appState, value, app) => { - return changeFontSize(elements, appState, app, (element) => - Math.round(element.fontSize * (1 + FONT_SIZE_RELATIVE_INCREASE_STEP)), - ); - }, - keyTest: (event) => { - return ( - event[KEYS.CTRL_OR_CMD] && - event.shiftKey && - // KEYS.PERIOD needed for MacOS - (event.key === KEYS.CHEVRON_RIGHT || event.key === KEYS.PERIOD) - ); - }, -}); - export const actionChangeFontFamily = register({ name: "changeFontFamily", trackEvent: false, diff --git a/packages/excalidraw/actions/index.ts b/packages/excalidraw/actions/index.ts index b4551acf5..1b047af97 100644 --- a/packages/excalidraw/actions/index.ts +++ b/packages/excalidraw/actions/index.ts @@ -20,6 +20,11 @@ export { actionChangeVerticalAlign, } from "./actionProperties"; +export { + actionDecreaseFontSize, + actionIncreaseFontSize, +} from "./actionFontSize"; + export { actionChangeViewBackgroundColor, actionClearCanvas,