|
@@ -1,4 +1,4 @@
|
|
|
-import { SHIFT_LOCKING_ANGLE } from "../constants";
|
|
|
+import { MIN_FONT_SIZE, SHIFT_LOCKING_ANGLE } from "../constants";
|
|
|
import { rescalePoints } from "../points";
|
|
|
|
|
|
import {
|
|
@@ -204,8 +204,6 @@ const rescalePointsInElement = (
|
|
|
}
|
|
|
: {};
|
|
|
|
|
|
-const MIN_FONT_SIZE = 1;
|
|
|
-
|
|
|
const measureFontSizeFromWidth = (
|
|
|
element: NonDeleted<ExcalidrawTextElement>,
|
|
|
nextWidth: number,
|
|
@@ -589,24 +587,42 @@ export const resizeSingleElement = (
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ if (
|
|
|
+ isArrowElement(element) &&
|
|
|
+ boundTextElement &&
|
|
|
+ shouldMaintainAspectRatio
|
|
|
+ ) {
|
|
|
+ const fontSize =
|
|
|
+ (resizedElement.width / element.width) * boundTextElement.fontSize;
|
|
|
+ if (fontSize < MIN_FONT_SIZE) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ boundTextFont.fontSize = fontSize;
|
|
|
+ }
|
|
|
+
|
|
|
if (
|
|
|
resizedElement.width !== 0 &&
|
|
|
resizedElement.height !== 0 &&
|
|
|
Number.isFinite(resizedElement.x) &&
|
|
|
Number.isFinite(resizedElement.y)
|
|
|
) {
|
|
|
+ mutateElement(element, resizedElement);
|
|
|
+
|
|
|
updateBoundElements(element, {
|
|
|
newSize: { width: resizedElement.width, height: resizedElement.height },
|
|
|
});
|
|
|
|
|
|
- mutateElement(element, resizedElement);
|
|
|
if (boundTextElement && boundTextFont != null) {
|
|
|
mutateElement(boundTextElement, {
|
|
|
fontSize: boundTextFont.fontSize,
|
|
|
baseline: boundTextFont.baseline,
|
|
|
});
|
|
|
}
|
|
|
- handleBindTextResize(element, transformHandleDirection);
|
|
|
+ handleBindTextResize(
|
|
|
+ element,
|
|
|
+ transformHandleDirection,
|
|
|
+ shouldMaintainAspectRatio,
|
|
|
+ );
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -722,12 +738,8 @@ export const resizeMultipleElements = (
|
|
|
fontSize?: ExcalidrawTextElement["fontSize"];
|
|
|
baseline?: ExcalidrawTextElement["baseline"];
|
|
|
scale?: ExcalidrawImageElement["scale"];
|
|
|
+ boundTextFontSize?: ExcalidrawTextElement["fontSize"];
|
|
|
};
|
|
|
- boundText: {
|
|
|
- element: ExcalidrawTextElementWithContainer;
|
|
|
- fontSize: ExcalidrawTextElement["fontSize"];
|
|
|
- baseline: ExcalidrawTextElement["baseline"];
|
|
|
- } | null;
|
|
|
}[] = [];
|
|
|
|
|
|
for (const { orig, latest } of targetElements) {
|
|
@@ -798,50 +810,39 @@ export const resizeMultipleElements = (
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- let boundText: typeof elementsAndUpdates[0]["boundText"] = null;
|
|
|
-
|
|
|
- const boundTextElement = getBoundTextElement(latest);
|
|
|
-
|
|
|
- if (boundTextElement || isTextElement(orig)) {
|
|
|
- const updatedElement = {
|
|
|
- ...latest,
|
|
|
- width,
|
|
|
- height,
|
|
|
- };
|
|
|
- const metrics = measureFontSizeFromWidth(
|
|
|
- boundTextElement ?? (orig as ExcalidrawTextElement),
|
|
|
- boundTextElement
|
|
|
- ? getBoundTextMaxWidth(updatedElement)
|
|
|
- : updatedElement.width,
|
|
|
- boundTextElement
|
|
|
- ? getBoundTextMaxHeight(updatedElement, boundTextElement)
|
|
|
- : updatedElement.height,
|
|
|
- );
|
|
|
-
|
|
|
+ if (isTextElement(orig)) {
|
|
|
+ const metrics = measureFontSizeFromWidth(orig, width, height);
|
|
|
if (!metrics) {
|
|
|
return;
|
|
|
}
|
|
|
+ update.fontSize = metrics.size;
|
|
|
+ update.baseline = metrics.baseline;
|
|
|
+ }
|
|
|
|
|
|
- if (isTextElement(orig)) {
|
|
|
- update.fontSize = metrics.size;
|
|
|
- update.baseline = metrics.baseline;
|
|
|
- }
|
|
|
+ const boundTextElement = pointerDownState.originalElements.get(
|
|
|
+ getBoundTextElementId(orig) ?? "",
|
|
|
+ ) as ExcalidrawTextElementWithContainer | undefined;
|
|
|
|
|
|
- if (boundTextElement) {
|
|
|
- boundText = {
|
|
|
- element: boundTextElement,
|
|
|
- fontSize: metrics.size,
|
|
|
- baseline: metrics.baseline,
|
|
|
- };
|
|
|
+ if (boundTextElement) {
|
|
|
+ const newFontSize = boundTextElement.fontSize * scale;
|
|
|
+ if (newFontSize < MIN_FONT_SIZE) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ update.boundTextFontSize = newFontSize;
|
|
|
}
|
|
|
|
|
|
- elementsAndUpdates.push({ element: latest, update, boundText });
|
|
|
+ elementsAndUpdates.push({
|
|
|
+ element: latest,
|
|
|
+ update,
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
const elementsToUpdate = elementsAndUpdates.map(({ element }) => element);
|
|
|
|
|
|
- for (const { element, update, boundText } of elementsAndUpdates) {
|
|
|
+ for (const {
|
|
|
+ element,
|
|
|
+ update: { boundTextFontSize, ...update },
|
|
|
+ } of elementsAndUpdates) {
|
|
|
const { width, height, angle } = update;
|
|
|
|
|
|
mutateElement(element, update, false);
|
|
@@ -851,17 +852,17 @@ export const resizeMultipleElements = (
|
|
|
newSize: { width, height },
|
|
|
});
|
|
|
|
|
|
- if (boundText) {
|
|
|
- const { element: boundTextElement, ...boundTextUpdates } = boundText;
|
|
|
+ const boundTextElement = getBoundTextElement(element);
|
|
|
+ if (boundTextElement && boundTextFontSize) {
|
|
|
mutateElement(
|
|
|
boundTextElement,
|
|
|
{
|
|
|
- ...boundTextUpdates,
|
|
|
+ fontSize: boundTextFontSize,
|
|
|
angle: isLinearElement(element) ? undefined : angle,
|
|
|
},
|
|
|
false,
|
|
|
);
|
|
|
- handleBindTextResize(element, transformHandleType);
|
|
|
+ handleBindTextResize(element, transformHandleType, true);
|
|
|
}
|
|
|
}
|
|
|
|