mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: text wrapping (#7999)
* resize single elements from the side * fix lint * do not resize texts from the sides (for we want to wrap/unwrap) * omit side handles for frames too * upgrade types * enable resizing from the sides for multiple elements as well * fix lint * maintain aspect ratio when elements are not of the same angle * lint * always resize proportionally for multiple elements * increase side resizing padding * code cleanup * adaptive handles * do not resize for linear elements with only two points * prioritize point dragging over edge resizing * lint * allow free resizing for multiple elements at degree 0 * always resize from the sides * reduce hit threshold * make small multiple elements movable * lint * show side handles on touch screen and mobile devices * differentiate touchscreens * keep proportional with text in multi-element resizing * update snapshot * update multi elements resizing logic * lint * reduce side resizing padding * bound texts do not scale in normal cases * lint * test sides for texts * wrap text * do not update text size when changing its alignment * keep text wrapped/unwrapped when editing * change wrapped size to auto size from context menu * fix test * lint * increase min width for wrapped texts * wrap wrapped text in container * unwrap when binding text to container * rename `wrapped` to `autoResize` * fix lint * revert: use `center` align when wrapping text in container * update snaps * fix lint * simplify logic on autoResize * lint and test * snapshots * remove unnecessary code * snapshots * fix: defaults not set correctly * tests for wrapping texts when resized * tests for text wrapping when edited * fix autoResize refactor * include autoResize flag check * refactor * feat: rename action label & change contextmenu position * fix: update version on `autoResize` action * fix infinite loop when editing text in a container * simplify * always maintain `width` if `!autoResize` * maintain `x` if `!autoResize` * maintain `y` pos after fontSize change if `!autoResize` * refactor * when editing, do not wrap text in textWysiwyg * simplify text editor * make test more readable * comment * rename action to match file name * revert function signature change * only update in app --------- Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
parent
cc4c51996c
commit
971b4d4ae6
22 changed files with 596 additions and 143 deletions
|
@ -240,24 +240,28 @@ export const newTextElement = (
|
|||
metrics,
|
||||
);
|
||||
|
||||
const textElement = newElementWith(
|
||||
{
|
||||
..._newElementBase<ExcalidrawTextElement>("text", opts),
|
||||
text,
|
||||
fontSize,
|
||||
fontFamily,
|
||||
textAlign,
|
||||
verticalAlign,
|
||||
x: opts.x - offsets.x,
|
||||
y: opts.y - offsets.y,
|
||||
width: metrics.width,
|
||||
height: metrics.height,
|
||||
containerId: opts.containerId || null,
|
||||
originalText: text,
|
||||
lineHeight,
|
||||
},
|
||||
const textElementProps: ExcalidrawTextElement = {
|
||||
..._newElementBase<ExcalidrawTextElement>("text", opts),
|
||||
text,
|
||||
fontSize,
|
||||
fontFamily,
|
||||
textAlign,
|
||||
verticalAlign,
|
||||
x: opts.x - offsets.x,
|
||||
y: opts.y - offsets.y,
|
||||
width: metrics.width,
|
||||
height: metrics.height,
|
||||
containerId: opts.containerId || null,
|
||||
originalText: text,
|
||||
autoResize: true,
|
||||
lineHeight,
|
||||
};
|
||||
|
||||
const textElement: ExcalidrawTextElement = newElementWith(
|
||||
textElementProps,
|
||||
{},
|
||||
);
|
||||
|
||||
return textElement;
|
||||
};
|
||||
|
||||
|
@ -271,18 +275,25 @@ const getAdjustedDimensions = (
|
|||
width: number;
|
||||
height: number;
|
||||
} => {
|
||||
const { width: nextWidth, height: nextHeight } = measureText(
|
||||
let { width: nextWidth, height: nextHeight } = measureText(
|
||||
nextText,
|
||||
getFontString(element),
|
||||
element.lineHeight,
|
||||
);
|
||||
|
||||
// wrapped text
|
||||
if (!element.autoResize) {
|
||||
nextWidth = element.width;
|
||||
}
|
||||
|
||||
const { textAlign, verticalAlign } = element;
|
||||
let x: number;
|
||||
let y: number;
|
||||
if (
|
||||
textAlign === "center" &&
|
||||
verticalAlign === VERTICAL_ALIGN.MIDDLE &&
|
||||
!element.containerId
|
||||
!element.containerId &&
|
||||
element.autoResize
|
||||
) {
|
||||
const prevMetrics = measureText(
|
||||
element.text,
|
||||
|
@ -343,38 +354,19 @@ export const refreshTextDimensions = (
|
|||
if (textElement.isDeleted) {
|
||||
return;
|
||||
}
|
||||
if (container) {
|
||||
if (container || !textElement.autoResize) {
|
||||
text = wrapText(
|
||||
text,
|
||||
getFontString(textElement),
|
||||
getBoundTextMaxWidth(container, textElement),
|
||||
container
|
||||
? getBoundTextMaxWidth(container, textElement)
|
||||
: textElement.width,
|
||||
);
|
||||
}
|
||||
const dimensions = getAdjustedDimensions(textElement, elementsMap, text);
|
||||
return { text, ...dimensions };
|
||||
};
|
||||
|
||||
export const updateTextElement = (
|
||||
textElement: ExcalidrawTextElement,
|
||||
container: ExcalidrawTextContainer | null,
|
||||
elementsMap: ElementsMap,
|
||||
{
|
||||
text,
|
||||
isDeleted,
|
||||
originalText,
|
||||
}: {
|
||||
text: string;
|
||||
isDeleted?: boolean;
|
||||
originalText: string;
|
||||
},
|
||||
): ExcalidrawTextElement => {
|
||||
return newElementWith(textElement, {
|
||||
originalText,
|
||||
isDeleted: isDeleted ?? textElement.isDeleted,
|
||||
...refreshTextDimensions(textElement, container, elementsMap, originalText),
|
||||
});
|
||||
};
|
||||
|
||||
export const newFreeDrawElement = (
|
||||
opts: {
|
||||
type: "freedraw";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue