Compare commits

...

2 Commits

Author SHA1 Message Date
Aakansha Doshi
16a396a188 Merge remote-tracking branch 'origin/master' into aakansha-improve-text-wrap-ellipse 2022-09-16 13:12:31 +05:30
Aakansha Doshi
873bab69e0 fix: improve text weappin inside ellipse 2022-09-08 18:19:12 +05:30
4 changed files with 86 additions and 29 deletions

View File

@ -2399,7 +2399,6 @@ class App extends React.Component<AppProps, AppState> {
); );
} }
} }
const element = existingTextElement const element = existingTextElement
? existingTextElement ? existingTextElement
: newTextElement({ : newTextElement({

View File

@ -21,7 +21,12 @@ import { AppState } from "../types";
import { getElementAbsoluteCoords } from "."; import { getElementAbsoluteCoords } from ".";
import { adjustXYWithRotation } from "../math"; import { adjustXYWithRotation } from "../math";
import { getResizedElementAbsoluteCoords } from "./bounds"; import { getResizedElementAbsoluteCoords } from "./bounds";
import { getContainerElement, measureText, wrapText } from "./textElement"; import {
getContainerElement,
getContainerDims,
measureText,
wrapText,
} from "./textElement";
import { BOUND_TEXT_PADDING, VERTICAL_ALIGN } from "../constants"; import { BOUND_TEXT_PADDING, VERTICAL_ALIGN } from "../constants";
type ElementConstructorOpts = MarkOptional< type ElementConstructorOpts = MarkOptional<
@ -164,7 +169,9 @@ const getAdjustedDimensions = (
let maxWidth = null; let maxWidth = null;
const container = getContainerElement(element); const container = getContainerElement(element);
if (container) { if (container) {
maxWidth = container.width - BOUND_TEXT_PADDING * 2; const containerDims = getContainerDims(container);
maxWidth = containerDims.width - BOUND_TEXT_PADDING * 2;
} }
const { const {
width: nextWidth, width: nextWidth,
@ -224,16 +231,21 @@ const getAdjustedDimensions = (
// make sure container dimensions are set properly when // make sure container dimensions are set properly when
// text editor overflows beyond viewport dimensions // text editor overflows beyond viewport dimensions
if (container) { if (container) {
let height = container.height; const containerDims = getContainerDims(container);
let width = container.width; let { width, height } = containerDims;
if (nextHeight > height - BOUND_TEXT_PADDING * 2) { if (nextHeight > height - BOUND_TEXT_PADDING * 2) {
height = nextHeight + BOUND_TEXT_PADDING * 2; height = nextHeight + BOUND_TEXT_PADDING * 2;
} }
if (nextWidth > width - BOUND_TEXT_PADDING * 2) { if (nextWidth > width - BOUND_TEXT_PADDING * 2) {
width = nextWidth + BOUND_TEXT_PADDING * 2; width = nextWidth + BOUND_TEXT_PADDING * 2;
} }
if (height !== container.height || width !== container.width) { if (height !== containerDims.height || width !== containerDims.height) {
mutateElement(container, { height, width }); const diffHeight = height - containerDims.height;
const diffWidth = width - containerDims.width;
mutateElement(container, {
height: container.height + diffHeight,
width: container.width + diffWidth,
});
} }
} }
return { return {
@ -259,7 +271,11 @@ export const updateTextElement = (
): ExcalidrawTextElement => { ): ExcalidrawTextElement => {
const container = getContainerElement(element); const container = getContainerElement(element);
if (container) { if (container) {
text = wrapText(text, getFontString(element), container.width); text = wrapText(
text,
getFontString(element),
getContainerDims(container).width,
);
} }
const dimensions = getAdjustedDimensions(element, text); const dimensions = getAdjustedDimensions(element, text);
return newElementWith(element, { return newElementWith(element, {

View File

@ -16,16 +16,20 @@ export const redrawTextBoundingBox = (
element: ExcalidrawTextElement, element: ExcalidrawTextElement,
container: ExcalidrawElement | null, container: ExcalidrawElement | null,
) => { ) => {
const maxWidth = container let containerDims;
? container.width - BOUND_TEXT_PADDING * 2 if (container) {
containerDims = getContainerDims(container);
}
const maxWidth = containerDims
? containerDims.width - BOUND_TEXT_PADDING * 2
: undefined; : undefined;
let text = element.text; let text = element.text;
if (container) { if (containerDims) {
text = wrapText( text = wrapText(
element.originalText, element.originalText,
getFontString(element), getFontString(element),
container.width, containerDims.width,
); );
} }
const metrics = measureText( const metrics = measureText(
@ -37,18 +41,24 @@ export const redrawTextBoundingBox = (
let coordX = element.x; let coordX = element.x;
// Resize container and vertically center align the text // Resize container and vertically center align the text
if (container) { if (container) {
let nextHeight = container.height; const containerDims = getContainerDims(container);
coordX = container.x + BOUND_TEXT_PADDING; const containerCoords = getBoundTextContainerCoords(container);
let nextHeight = containerDims.height;
coordX = containerCoords.x + BOUND_TEXT_PADDING;
if (element.verticalAlign === VERTICAL_ALIGN.TOP) { if (element.verticalAlign === VERTICAL_ALIGN.TOP) {
coordY = container.y + BOUND_TEXT_PADDING; coordY = containerCoords.y + BOUND_TEXT_PADDING;
} else if (element.verticalAlign === VERTICAL_ALIGN.BOTTOM) { } else if (element.verticalAlign === VERTICAL_ALIGN.BOTTOM) {
coordY = coordY =
container.y + container.height - metrics.height - BOUND_TEXT_PADDING; containerCoords.y +
containerDims.height -
metrics.height -
BOUND_TEXT_PADDING;
} else { } else {
coordY = container.y + container.height / 2 - metrics.height / 2; coordY =
if (metrics.height > container.height - BOUND_TEXT_PADDING * 2) { containerCoords.y + containerDims.height / 2 - metrics.height / 2;
if (metrics.height > containerDims.height - BOUND_TEXT_PADDING * 2) {
nextHeight = metrics.height + BOUND_TEXT_PADDING * 2; nextHeight = metrics.height + BOUND_TEXT_PADDING * 2;
coordY = container.y + nextHeight / 2 - metrics.height / 2; coordY = containerCoords.y + nextHeight / 2 - metrics.height / 2;
} }
} }
mutateElement(container, { height: nextHeight }); mutateElement(container, { height: nextHeight });
@ -121,7 +131,7 @@ export const handleBindTextResize = (
text = wrapText( text = wrapText(
textElement.originalText, textElement.originalText,
getFontString(textElement), getFontString(textElement),
element.width, getContainerDims(element).width,
); );
} }
@ -474,3 +484,28 @@ export const getContainerElement = (
} }
return null; return null;
}; };
export const getContainerDims = (element: ExcalidrawElement) => {
if (element.type === "ellipse") {
return {
width: Math.round((element.width / 2) * Math.sqrt(2)),
height: Math.round((element.height / 2) * Math.sqrt(2)),
};
}
return { width: element.width, height: element.height };
};
export const getBoundTextContainerCoords = (container: ExcalidrawElement) => {
if (container.type === "ellipse") {
const offsetX = (container.width / 2) * (1 - Math.sqrt(2) / 2);
const offsetY = (container.height / 2) * (1 - Math.sqrt(2) / 2);
return {
x: container.x + offsetX,
y: container.y + offsetY,
};
}
return {
x: container.x,
y: container.y,
};
};

View File

@ -19,7 +19,9 @@ import {
getApproxLineHeight, getApproxLineHeight,
getBoundTextElementId, getBoundTextElementId,
getContainerElement, getContainerElement,
getContainerDims,
wrapText, wrapText,
getBoundTextContainerCoords,
} from "./textElement"; } from "./textElement";
import { import {
actionDecreaseFontSize, actionDecreaseFontSize,
@ -126,26 +128,28 @@ export const textWysiwyg = ({
updatedElement, updatedElement,
editable, editable,
); );
const containerDims = getContainerDims(container);
// using editor.style.height to get the accurate height of text editor // using editor.style.height to get the accurate height of text editor
const editorHeight = Number(editable.style.height.slice(0, -2)); const editorHeight = Number(editable.style.height.slice(0, -2));
if (editorHeight > 0) { if (editorHeight > 0) {
height = editorHeight; height = editorHeight;
} }
if (propertiesUpdated) { if (propertiesUpdated) {
originalContainerHeight = container.height; originalContainerHeight = containerDims.height;
// update height of the editor after properties updated // update height of the editor after properties updated
height = updatedElement.height; height = updatedElement.height;
} }
if (!originalContainerHeight) { if (!originalContainerHeight) {
originalContainerHeight = container.height; originalContainerHeight = containerDims.height;
} }
maxWidth = container.width - BOUND_TEXT_PADDING * 2; maxWidth = containerDims.width - BOUND_TEXT_PADDING * 2;
maxHeight = container.height - BOUND_TEXT_PADDING * 2; maxHeight = containerDims.height - BOUND_TEXT_PADDING * 2;
width = maxWidth; width = maxWidth;
const boundTextCoords = getBoundTextContainerCoords(container);
// The coordinates of text box set a distance of // The coordinates of text box set a distance of
// 5px to preserve padding // 5px to preserve padding
coordX = container.x + BOUND_TEXT_PADDING; coordX = boundTextCoords.x + BOUND_TEXT_PADDING;
// autogrow container height if text exceeds // autogrow container height if text exceeds
if (height > maxHeight) { if (height > maxHeight) {
const diff = Math.min(height - maxHeight, approxLineHeight); const diff = Math.min(height - maxHeight, approxLineHeight);
@ -154,7 +158,7 @@ export const textWysiwyg = ({
} else if ( } else if (
// autoshrink container height until original container height // autoshrink container height until original container height
// is reached when text is removed // is reached when text is removed
container.height > originalContainerHeight && containerDims.height > originalContainerHeight &&
height < maxHeight height < maxHeight
) { ) {
const diff = Math.min(maxHeight - height, approxLineHeight); const diff = Math.min(maxHeight - height, approxLineHeight);
@ -165,11 +169,14 @@ export const textWysiwyg = ({
else { else {
// vertically center align the text // vertically center align the text
if (verticalAlign === VERTICAL_ALIGN.MIDDLE) { if (verticalAlign === VERTICAL_ALIGN.MIDDLE) {
coordY = container.y + container.height / 2 - height / 2; coordY = boundTextCoords.y + containerDims.height / 2 - height / 2;
} }
if (verticalAlign === VERTICAL_ALIGN.BOTTOM) { if (verticalAlign === VERTICAL_ALIGN.BOTTOM) {
coordY = coordY =
container.y + container.height - height - BOUND_TEXT_PADDING; boundTextCoords.y +
containerDims.height -
height -
BOUND_TEXT_PADDING;
} }
} }
} }
@ -303,7 +310,7 @@ export const textWysiwyg = ({
const actualLineCount = wrapText( const actualLineCount = wrapText(
editable.value, editable.value,
font, font,
container!.width, getContainerDims(container!).width,
).split("\n").length; ).split("\n").length;
// This is browser behaviour when setting height to "auto" // This is browser behaviour when setting height to "auto"
// It sets the height needed for 2 lines even if actual // It sets the height needed for 2 lines even if actual