mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: create new text with width (#8038)
Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
parent
4eb9463f26
commit
860308eb27
13 changed files with 178 additions and 33 deletions
|
@ -4,11 +4,17 @@ import { getCommonBounds } from "./bounds";
|
|||
import { mutateElement } from "./mutateElement";
|
||||
import { getPerfectElementSize } from "./sizeHelpers";
|
||||
import type { NonDeletedExcalidrawElement } from "./types";
|
||||
import type { AppState, PointerDownState } from "../types";
|
||||
import { getBoundTextElement } from "./textElement";
|
||||
import type { AppState, NormalizedZoomValue, PointerDownState } from "../types";
|
||||
import { getBoundTextElement, getMinTextElementWidth } from "./textElement";
|
||||
import { getGridPoint } from "../math";
|
||||
import type Scene from "../scene/Scene";
|
||||
import { isArrowElement, isFrameLikeElement } from "./typeChecks";
|
||||
import {
|
||||
isArrowElement,
|
||||
isFrameLikeElement,
|
||||
isTextElement,
|
||||
} from "./typeChecks";
|
||||
import { getFontString } from "../utils";
|
||||
import { TEXT_AUTOWRAP_THRESHOLD } from "../constants";
|
||||
|
||||
export const dragSelectedElements = (
|
||||
pointerDownState: PointerDownState,
|
||||
|
@ -140,6 +146,7 @@ export const dragNewElement = (
|
|||
height: number,
|
||||
shouldMaintainAspectRatio: boolean,
|
||||
shouldResizeFromCenter: boolean,
|
||||
zoom: NormalizedZoomValue,
|
||||
/** whether to keep given aspect ratio when `isResizeWithSidesSameLength` is
|
||||
true */
|
||||
widthAspectRatio?: number | null,
|
||||
|
@ -185,12 +192,41 @@ export const dragNewElement = (
|
|||
newY = originY - height / 2;
|
||||
}
|
||||
|
||||
let textAutoResize = null;
|
||||
|
||||
// NOTE this should apply only to creating text elements, not existing
|
||||
// (once we rewrite appState.draggingElement to actually mean dragging
|
||||
// elements)
|
||||
if (isTextElement(draggingElement)) {
|
||||
height = draggingElement.height;
|
||||
const minWidth = getMinTextElementWidth(
|
||||
getFontString({
|
||||
fontSize: draggingElement.fontSize,
|
||||
fontFamily: draggingElement.fontFamily,
|
||||
}),
|
||||
draggingElement.lineHeight,
|
||||
);
|
||||
width = Math.max(width, minWidth);
|
||||
|
||||
if (Math.abs(x - originX) > TEXT_AUTOWRAP_THRESHOLD / zoom) {
|
||||
textAutoResize = {
|
||||
autoResize: false,
|
||||
};
|
||||
}
|
||||
|
||||
newY = originY;
|
||||
if (shouldResizeFromCenter) {
|
||||
newX = originX - width / 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (width !== 0 && height !== 0) {
|
||||
mutateElement(draggingElement, {
|
||||
x: newX + (originOffset?.x ?? 0),
|
||||
y: newY + (originOffset?.y ?? 0),
|
||||
width,
|
||||
height,
|
||||
...textAutoResize,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
import {
|
||||
BOUND_TEXT_PADDING,
|
||||
MIN_FONT_SIZE,
|
||||
SHIFT_LOCKING_ANGLE,
|
||||
} from "../constants";
|
||||
import { MIN_FONT_SIZE, SHIFT_LOCKING_ANGLE } from "../constants";
|
||||
import { rescalePoints } from "../points";
|
||||
|
||||
import { rotate, centerPoint, rotatePoint } from "../math";
|
||||
|
@ -51,7 +47,7 @@ import {
|
|||
getApproxMinLineHeight,
|
||||
wrapText,
|
||||
measureText,
|
||||
getMinCharWidth,
|
||||
getMinTextElementWidth,
|
||||
} from "./textElement";
|
||||
import { LinearElementEditor } from "./linearElementEditor";
|
||||
import { isInGroup } from "../groups";
|
||||
|
@ -352,8 +348,13 @@ const resizeSingleTextElement = (
|
|||
const boundsCurrentWidth = esx2 - esx1;
|
||||
|
||||
const atStartBoundsWidth = startBottomRight[0] - startTopLeft[0];
|
||||
const minWidth =
|
||||
getMinCharWidth(getFontString(element)) + BOUND_TEXT_PADDING * 2;
|
||||
const minWidth = getMinTextElementWidth(
|
||||
getFontString({
|
||||
fontSize: element.fontSize,
|
||||
fontFamily: element.fontFamily,
|
||||
}),
|
||||
element.lineHeight,
|
||||
);
|
||||
|
||||
let scaleX = atStartBoundsWidth / boundsCurrentWidth;
|
||||
|
||||
|
|
|
@ -938,3 +938,10 @@ export const getDefaultLineHeight = (fontFamily: FontFamilyValues) => {
|
|||
}
|
||||
return DEFAULT_LINE_HEIGHT[DEFAULT_FONT_FAMILY];
|
||||
};
|
||||
|
||||
export const getMinTextElementWidth = (
|
||||
font: FontString,
|
||||
lineHeight: ExcalidrawTextElement["lineHeight"],
|
||||
) => {
|
||||
return measureText("", font, lineHeight).width + BOUND_TEXT_PADDING * 2;
|
||||
};
|
||||
|
|
|
@ -576,7 +576,7 @@ describe("textWysiwyg", () => {
|
|||
|
||||
it("text should never go beyond max width", async () => {
|
||||
UI.clickTool("text");
|
||||
mouse.clickAt(750, 300);
|
||||
mouse.click(0, 0);
|
||||
|
||||
textarea = await getTextEditor(textEditorSelector, true);
|
||||
updateTextEditor(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue