mirror of
https://github.com/excalidraw/excalidraw.git
synced 2024-11-10 11:35:52 +01:00
fix: set height correctly when text properties updated while editing in container until first submit (#4469)
* fix: set height correctly when text properties updated while editing in container * rename PADDING to BOUND_TEXT_PADDING
This commit is contained in:
parent
bf2bca221e
commit
ef62390841
@ -61,6 +61,7 @@ import {
|
||||
isSomeElementSelected,
|
||||
} from "../scene";
|
||||
import { hasStrokeColor } from "../scene/comparisons";
|
||||
import Scene from "../scene/Scene";
|
||||
import { register } from "./register";
|
||||
|
||||
const changeProperty = (
|
||||
@ -431,7 +432,11 @@ export const actionChangeFontSize = register({
|
||||
const element: ExcalidrawTextElement = newElementWith(el, {
|
||||
fontSize: value,
|
||||
});
|
||||
redrawTextBoundingBox(element);
|
||||
let container = null;
|
||||
if (el.containerId) {
|
||||
container = Scene.getScene(el)!.getElement(el.containerId);
|
||||
}
|
||||
redrawTextBoundingBox(element, container);
|
||||
return element;
|
||||
}
|
||||
|
||||
@ -492,7 +497,11 @@ export const actionChangeFontFamily = register({
|
||||
const element: ExcalidrawTextElement = newElementWith(el, {
|
||||
fontFamily: value,
|
||||
});
|
||||
redrawTextBoundingBox(element);
|
||||
let container = null;
|
||||
if (el.containerId) {
|
||||
container = Scene.getScene(el)!.getElement(el.containerId);
|
||||
}
|
||||
redrawTextBoundingBox(element, container);
|
||||
return element;
|
||||
}
|
||||
|
||||
@ -556,7 +565,11 @@ export const actionChangeTextAlign = register({
|
||||
const element: ExcalidrawTextElement = newElementWith(el, {
|
||||
textAlign: value,
|
||||
});
|
||||
redrawTextBoundingBox(element);
|
||||
let container = null;
|
||||
if (el.containerId) {
|
||||
container = Scene.getScene(el)!.getElement(el.containerId);
|
||||
}
|
||||
redrawTextBoundingBox(element, container);
|
||||
return element;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,9 @@ import {
|
||||
DEFAULT_FONT_FAMILY,
|
||||
DEFAULT_TEXT_ALIGN,
|
||||
} from "../constants";
|
||||
import Scene from "../scene/Scene";
|
||||
import { isBoundToContainer } from "../element/typeChecks";
|
||||
import { ExcalidrawTextElement } from "../element/types";
|
||||
|
||||
// `copiedStyles` is exported only for tests.
|
||||
export let copiedStyles: string = "{}";
|
||||
@ -61,7 +64,14 @@ export const actionPasteStyles = register({
|
||||
fontFamily: pastedElement?.fontFamily || DEFAULT_FONT_FAMILY,
|
||||
textAlign: pastedElement?.textAlign || DEFAULT_TEXT_ALIGN,
|
||||
});
|
||||
redrawTextBoundingBox(newElement);
|
||||
let container = null;
|
||||
|
||||
if (isBoundToContainer(element)) {
|
||||
container = Scene.getScene(element)!.getElement(
|
||||
element.containerId,
|
||||
);
|
||||
}
|
||||
redrawTextBoundingBox(element as ExcalidrawTextElement, container);
|
||||
}
|
||||
return newElement;
|
||||
}
|
||||
|
@ -182,4 +182,4 @@ export const VERSIONS = {
|
||||
excalidrawLibrary: 2,
|
||||
} as const;
|
||||
|
||||
export const PADDING = 30;
|
||||
export const BOUND_TEXT_PADDING = 30;
|
||||
|
@ -24,7 +24,7 @@ import { getResizedElementAbsoluteCoords } from "./bounds";
|
||||
import { measureText } from "./textElement";
|
||||
import { isBoundToContainer } from "./typeChecks";
|
||||
import Scene from "../scene/Scene";
|
||||
import { PADDING } from "../constants";
|
||||
import { BOUND_TEXT_PADDING } from "../constants";
|
||||
|
||||
type ElementConstructorOpts = MarkOptional<
|
||||
Omit<ExcalidrawGenericElement, "id" | "type" | "isDeleted" | "updated">,
|
||||
@ -219,11 +219,11 @@ const getAdjustedDimensions = (
|
||||
const container = Scene.getScene(element)!.getElement(element.containerId)!;
|
||||
let height = container.height;
|
||||
let width = container.width;
|
||||
if (nextHeight > height - PADDING * 2) {
|
||||
height = nextHeight + PADDING * 2;
|
||||
if (nextHeight > height - BOUND_TEXT_PADDING * 2) {
|
||||
height = nextHeight + BOUND_TEXT_PADDING * 2;
|
||||
}
|
||||
if (nextWidth > width - PADDING * 2) {
|
||||
width = nextWidth + PADDING * 2;
|
||||
if (nextWidth > width - BOUND_TEXT_PADDING * 2) {
|
||||
width = nextWidth + BOUND_TEXT_PADDING * 2;
|
||||
}
|
||||
if (height !== container.height || width !== container.width) {
|
||||
mutateElement(container, { height, width });
|
||||
|
@ -7,15 +7,17 @@ import {
|
||||
NonDeletedExcalidrawElement,
|
||||
} from "./types";
|
||||
import { mutateElement } from "./mutateElement";
|
||||
import { PADDING } from "../constants";
|
||||
import { BOUND_TEXT_PADDING } from "../constants";
|
||||
import { MaybeTransformHandleType } from "./transformHandles";
|
||||
import Scene from "../scene/Scene";
|
||||
|
||||
export const redrawTextBoundingBox = (element: ExcalidrawTextElement) => {
|
||||
let maxWidth;
|
||||
if (element.containerId) {
|
||||
maxWidth = element.width;
|
||||
}
|
||||
export const redrawTextBoundingBox = (
|
||||
element: ExcalidrawTextElement,
|
||||
container: ExcalidrawElement | null,
|
||||
) => {
|
||||
const maxWidth = container
|
||||
? container.width - BOUND_TEXT_PADDING * 2
|
||||
: undefined;
|
||||
const metrics = measureText(
|
||||
element.originalText,
|
||||
getFontString(element),
|
||||
@ -87,7 +89,7 @@ export const handleBindTextResize = (
|
||||
minCharWidthTillNow = getMinCharWidth(getFontString(textElement));
|
||||
// check if the diff has exceeded min char width needed
|
||||
const diff = Math.abs(
|
||||
element.width - textElement.width + PADDING * 2,
|
||||
element.width - textElement.width + BOUND_TEXT_PADDING * 2,
|
||||
);
|
||||
if (diff >= minCharWidthTillNow) {
|
||||
text = wrapText(
|
||||
@ -107,8 +109,8 @@ export const handleBindTextResize = (
|
||||
nextBaseLine = dimensions.baseline;
|
||||
}
|
||||
// increase height in case text element height exceeds
|
||||
if (nextHeight > element.height - PADDING * 2) {
|
||||
containerHeight = nextHeight + PADDING * 2;
|
||||
if (nextHeight > element.height - BOUND_TEXT_PADDING * 2) {
|
||||
containerHeight = nextHeight + BOUND_TEXT_PADDING * 2;
|
||||
const diff = containerHeight - element.height;
|
||||
// fix the y coord when resizing from ne/nw/n
|
||||
const updatedY =
|
||||
@ -127,9 +129,9 @@ export const handleBindTextResize = (
|
||||
mutateElement(textElement, {
|
||||
text,
|
||||
// preserve padding and set width correctly
|
||||
width: element.width - PADDING * 2,
|
||||
width: element.width - BOUND_TEXT_PADDING * 2,
|
||||
height: nextHeight,
|
||||
x: element.x + PADDING,
|
||||
x: element.x + BOUND_TEXT_PADDING,
|
||||
y: updatedY,
|
||||
baseline: nextBaseLine,
|
||||
});
|
||||
@ -207,7 +209,7 @@ export const wrapText = (
|
||||
font: FontString,
|
||||
containerWidth: number,
|
||||
) => {
|
||||
const maxWidth = containerWidth - PADDING * 2;
|
||||
const maxWidth = containerWidth - BOUND_TEXT_PADDING * 2;
|
||||
|
||||
const lines: Array<string> = [];
|
||||
const originalLines = text.split("\n");
|
||||
@ -343,11 +345,14 @@ export const charWidth = (() => {
|
||||
};
|
||||
})();
|
||||
export const getApproxMinLineWidth = (font: FontString) => {
|
||||
return measureText(DUMMY_TEXT.split("").join("\n"), font).width + PADDING * 2;
|
||||
return (
|
||||
measureText(DUMMY_TEXT.split("").join("\n"), font).width +
|
||||
BOUND_TEXT_PADDING * 2
|
||||
);
|
||||
};
|
||||
|
||||
export const getApproxMinLineHeight = (font: FontString) => {
|
||||
return getApproxLineHeight(font) + PADDING * 2;
|
||||
return getApproxLineHeight(font) + BOUND_TEXT_PADDING * 2;
|
||||
};
|
||||
|
||||
export const getMinCharWidth = (font: FontString) => {
|
||||
|
@ -6,7 +6,7 @@ import {
|
||||
} from "../utils";
|
||||
import Scene from "../scene/Scene";
|
||||
import { isBoundToContainer, isTextElement } from "./typeChecks";
|
||||
import { CLASSES, PADDING } from "../constants";
|
||||
import { CLASSES, BOUND_TEXT_PADDING } from "../constants";
|
||||
import {
|
||||
ExcalidrawBindableElement,
|
||||
ExcalidrawElement,
|
||||
@ -129,8 +129,11 @@ export const textWysiwyg = ({
|
||||
approxLineHeight = isTextElement(updatedElement)
|
||||
? getApproxLineHeight(getFontString(updatedElement))
|
||||
: 0;
|
||||
if (updatedElement.height > currentContainer.height - PADDING * 2) {
|
||||
const nextHeight = updatedElement.height + PADDING * 2;
|
||||
if (
|
||||
updatedElement.height >
|
||||
currentContainer.height - BOUND_TEXT_PADDING * 2
|
||||
) {
|
||||
const nextHeight = updatedElement.height + BOUND_TEXT_PADDING * 2;
|
||||
originalContainerHeight = nextHeight;
|
||||
mutateElement(container, { height: nextHeight });
|
||||
container = { ...container, height: nextHeight };
|
||||
@ -141,12 +144,12 @@ export const textWysiwyg = ({
|
||||
if (!originalContainerHeight) {
|
||||
originalContainerHeight = container.height;
|
||||
}
|
||||
maxWidth = container.width - PADDING * 2;
|
||||
maxHeight = container.height - PADDING * 2;
|
||||
maxWidth = container.width - BOUND_TEXT_PADDING * 2;
|
||||
maxHeight = container.height - BOUND_TEXT_PADDING * 2;
|
||||
width = maxWidth;
|
||||
// The coordinates of text box set a distance of
|
||||
// 30px to preserve padding
|
||||
coordX = container.x + PADDING;
|
||||
coordX = container.x + BOUND_TEXT_PADDING;
|
||||
// autogrow container height if text exceeds
|
||||
if (height > maxHeight) {
|
||||
const diff = Math.min(height - maxHeight, approxLineHeight);
|
||||
@ -465,7 +468,7 @@ export const textWysiwyg = ({
|
||||
height: editorHeight,
|
||||
width: Number(editable.style.width.slice(0, -2)),
|
||||
// preserve padding
|
||||
x: container.x + PADDING,
|
||||
x: container.x + BOUND_TEXT_PADDING,
|
||||
});
|
||||
const boundTextElementId = getBoundTextElementId(container);
|
||||
if (!boundTextElementId || boundTextElementId !== element.id) {
|
||||
|
Loading…
Reference in New Issue
Block a user